Skip to content

Commit

Permalink
fix: simplify helper APIs (#1732)
Browse files Browse the repository at this point in the history
Switch the calling convention for autoswap helpers to
passing positional arguments. The use of a params object
doesn't work very well in JS. It's exacerbated if we
need to use `harden`, and the value is reduced now that
we have pervasive types on helpers.

Co-authored-by: Dean Tribble <[email protected]>
  • Loading branch information
dtribble and dtribble authored Sep 14, 2020
1 parent 2a8b0fc commit 068f4b1
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 144 deletions.
52 changes: 24 additions & 28 deletions packages/zoe/src/contractSupport/bondingCurves.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,23 @@ const { add, subtract, multiply, floorDivide } = natSafeMath;
* request, and to do the actual reallocation after an offer has
* been made.
*
* @param {Object} params
* @param {number} params.inputValue - the value of the asset sent
* @param {number} inputValue - the value of the asset sent
* in to be swapped
* @param {number} params.inputReserve - the value in the liquidity
* @param {number} inputReserve - the value in the liquidity
* pool of the kind of asset sent in
* @param {number} params.outputReserve - the value in the liquidity
* @param {number} outputReserve - the value in the liquidity
* pool of the kind of asset to be sent out
* @param {number} [params.feeBasisPoints=30] - the fee taken in
* basis points. The default is 0.3% or 30 basis points. The fee is taken from
* inputValue
* @param {number} [feeBasisPoints=30] - the fee taken in
* basis points. The default is 0.3% or 30 basis points. The fee
* is taken from inputValue
* @returns {number} outputValue - the current price, in value form
*/
export const getInputPrice = ({
export const getInputPrice = (
inputValue,
inputReserve,
outputReserve,
feeBasisPoints = 30,
}) => {
) => {
const oneMinusFeeInTenThousandths = subtract(10000, feeBasisPoints);
const inputWithFee = multiply(inputValue, oneMinusFeeInTenThousandths);
const numerator = multiply(inputWithFee, outputReserve);
Expand All @@ -49,24 +48,23 @@ export const getInputPrice = ({
* request, and to do the actual reallocation after an offer has
* been made.
*
* @param {Object} params
* @param {number} params.outputValue - the value of the asset the user wants
* @param {number} outputValue - the value of the asset the user wants
* to get
* @param {number} params.inputReserve - the value in the liquidity
* @param {number} inputReserve - the value in the liquidity
* pool of the asset being spent
* @param {number} params.outputReserve - the value in the liquidity
* @param {number} outputReserve - the value in the liquidity
* pool of the kind of asset to be sent out
* @param {number} [params.feeBasisPoints=30] - the fee taken in
* @param {number} [feeBasisPoints=30] - the fee taken in
* basis points. The default is 0.3% or 30 basis points. The fee is taken from
* outputValue
* @returns {number} inputValue - the value of input required to purchase output
*/
export const getOutputPrice = ({
export const getOutputPrice = (
outputValue,
inputReserve,
outputReserve,
feeBasisPoints = 30,
}) => {
) => {
const oneMinusFeeInTenThousandths = subtract(10000, feeBasisPoints);
const numerator = multiply(multiply(outputValue, inputReserve), 10000);
const denominator = multiply(
Expand All @@ -86,19 +84,18 @@ function assertDefined(label, value) {
// liquidity multiplied by the ratio of new central tokens to central tokens
// already held. If the current supply is zero, return the inputValue as the
// initial liquidity to mint is arbitrary.
export const calcLiqValueToMint = ({
export const calcLiqValueToMint = (
liqTokenSupply,
inputValue,
inputReserve,
}) => {
) => {
assertDefined('liqTokenSupply', liqTokenSupply);
assertDefined('inputValue', inputValue);
assertDefined('inputReserve', inputReserve);

if (liqTokenSupply === 0) {
return inputValue;
}

return floorDivide(multiply(inputValue, liqTokenSupply), inputReserve);
};

Expand All @@ -107,20 +104,19 @@ export const calcLiqValueToMint = ({
* adding liquidity. We require that the deposited ratio of central to secondary
* match the current ratio of holdings in the pool.
*
* @param {Object} params
* @param {number} params.centralIn - The value of central assets being deposited
* @param {number} params.centralPool - The value of central assets in the pool
* @param {number} params.secondaryPool - The value of secondary assets in the pool
* @param {number} params.secondaryIn - The value of secondary assets provided. If
* @param {number} centralIn - The value of central assets being deposited
* @param {number} centralPool - The value of central assets in the pool
* @param {number} secondaryPool - The value of secondary assets in the pool
* @param {number} secondaryIn - The value of secondary assets provided. If
* the pool is empty, the entire amount will be accepted
* @returns {number} - the amount of secondary required
*/
export const calcSecondaryRequired = ({
export const calcSecondaryRequired = (
centralIn,
centralPool,
secondaryPool,
secondaryIn,
}) => {
) => {
assertDefined('centralIn', centralIn);
assertDefined('centralPool', centralPool);
assertDefined('secondaryReserve', secondaryPool);
Expand All @@ -143,11 +139,11 @@ export const calcSecondaryRequired = ({

// Calculate how many underlying tokens (in the form of a value) should be
// returned when removing liquidity.
export const calcValueToRemove = ({
export const calcValueToRemove = (
liqTokenSupply,
poolValue,
liquidityValueIn,
}) => {
) => {
assertDefined('liqTokenSupply', liqTokenSupply);
assertDefined('liquidityValueIn', liquidityValueIn);
assertDefined('poolValue', poolValue);
Expand Down
70 changes: 29 additions & 41 deletions packages/zoe/src/contracts/autoswap.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,9 @@ const start = async zcf => {
} = swapSeat.getProposal();

const outputValue = getInputPrice(
harden({
inputValue: amountIn.value,
inputReserve: getPoolAmount(amountIn.brand).value,
outputReserve: getPoolAmount(wantedAmountOut.brand).value,
}),
amountIn.value,
getPoolAmount(amountIn.brand).value,
getPoolAmount(wantedAmountOut.brand).value,
);
const outAmountMath = zcf.getAmountMath(wantedAmountOut.brand);
const tradeAmountOut = outAmountMath.make(outputValue);
Expand All @@ -173,11 +171,11 @@ const start = async zcf => {
want: { Out: wantedAmountOut },
} = swapSeat.getProposal();

const tradePrice = getOutputPrice({
outputValue: wantedAmountOut.value,
inputReserve: getPoolAmount(amountIn.brand).value,
outputReserve: getPoolAmount(wantedAmountOut.brand).value,
});
const tradePrice = getOutputPrice(
wantedAmountOut.value,
getPoolAmount(amountIn.brand).value,
getPoolAmount(wantedAmountOut.brand).value,
);
assert(tradePrice <= amountIn.value, 'amountIn insufficient');
const inAmountMath = zcf.getAmountMath(amountIn.brand);
const tradeAmountIn = inAmountMath.make(tradePrice);
Expand All @@ -190,11 +188,9 @@ const start = async zcf => {
const centralPool = getPoolAmount(brands.Central).value;
const centralIn = userAllocation.Central.value;
const liquidityValueOut = calcLiqValueToMint(
harden({
liqTokenSupply,
inputValue: centralIn,
inputReserve: centralPool,
}),
liqTokenSupply,
centralIn,
centralPool,
);
const liquidityAmountOut = liquidityMath.make(liquidityValueOut);
liquidityMint.mintGains({ Liquidity: liquidityAmountOut }, poolSeat);
Expand Down Expand Up @@ -248,12 +244,12 @@ const start = async zcf => {
// To calculate liquidity, we'll need to calculate alpha from the primary
// token's value before, and the value that will be added to the pool
const secondaryOut = secondaryMath.make(
calcSecondaryRequired({
centralIn: userAllocation.Central.value,
centralPool: getPoolAmount(brands.Central).value,
secondaryPool: getPoolAmount(brands.Secondary).value,
secondaryIn: secondaryIn.value,
}),
calcSecondaryRequired(
userAllocation.Central.value,
getPoolAmount(brands.Central).value,
getPoolAmount(brands.Secondary).value,
secondaryIn.value,
),
);

// Central was specified precisely so offer must provide enough secondary.
Expand All @@ -277,20 +273,16 @@ const start = async zcf => {

const newUserCentralAmount = centralMath.make(
calcValueToRemove(
harden({
liqTokenSupply,
poolValue: getPoolAmount(brands.Central).value,
liquidityValueIn,
}),
liqTokenSupply,
getPoolAmount(brands.Central).value,
liquidityValueIn,
),
);
const newUserSecondaryAmount = secondaryMath.make(
calcValueToRemove(
harden({
liqTokenSupply,
poolValue: getPoolAmount(brands.Secondary).value,
liquidityValueIn,
}),
liqTokenSupply,
getPoolAmount(brands.Secondary).value,
liquidityValueIn,
),
);

Expand Down Expand Up @@ -339,11 +331,9 @@ const start = async zcf => {
const inputReserve = getPoolAmount(amountIn.brand).value;
const outputReserve = getPoolAmount(brandOut).value;
const outputValue = getInputPrice(
harden({
inputValue: amountIn.value,
inputReserve,
outputReserve,
}),
amountIn.value,
inputReserve,
outputReserve,
);
return zcf.getAmountMath(brandOut).make(outputValue);
};
Expand All @@ -359,11 +349,9 @@ const start = async zcf => {
const inputReserve = getPoolAmount(brandIn).value;
const outputReserve = getPoolAmount(amountOut.brand).value;
const outputValue = getOutputPrice(
harden({
outputValue: amountOut.value,
inputReserve,
outputReserve,
}),
amountOut.value,
inputReserve,
outputReserve,
);
return zcf.getAmountMath(brandIn).make(outputValue);
};
Expand Down
86 changes: 43 additions & 43 deletions packages/zoe/src/contracts/multipoolAutoswap/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,9 @@ export const makeAddPool = (zcf, isSecondary, initPool, centralBrand) => {

const addLiquidityActual = (pool, userSeat, secondaryAmount) => {
const liquidityValueOut = calcLiqValueToMint(
harden({
liqTokenSupply,
inputValue: userSeat.getAmountAllocated('Central').value,
inputReserve: pool.getCentralAmount().value,
}),
liqTokenSupply,
userSeat.getAmountAllocated('Central').value,
pool.getCentralAmount().value,
);

const liquidityAmountOut = liquidityAmountMath.make(liquidityValueOut);
Expand Down Expand Up @@ -78,38 +76,38 @@ export const makeAddPool = (zcf, isSecondary, initPool, centralBrand) => {
poolSeat.getAmountAllocated('Secondary', secondaryBrand),
getCentralToSecondaryInputPrice: inputValue => {
assertPoolInitialized(pool);
const result = getInputPrice({
const result = getInputPrice(
inputValue,
inputReserve: pool.getCentralAmount().value,
outputReserve: pool.getSecondaryAmount().value,
});
pool.getCentralAmount().value,
pool.getSecondaryAmount().value,
);
return pool.getAmountMath().make(result);
},
getSecondaryToCentralInputPrice: inputValue => {
assertPoolInitialized(pool);
const result = getInputPrice({
const result = getInputPrice(
inputValue,
inputReserve: pool.getSecondaryAmount().value,
outputReserve: pool.getCentralAmount().value,
});
pool.getSecondaryAmount().value,
pool.getCentralAmount().value,
);
return pool.getCentralAmountMath().make(result);
},
getCentralToSecondaryOutputPrice: outputValue => {
assertPoolInitialized(pool);
const result = getOutputPrice({
const result = getOutputPrice(
outputValue,
inputReserve: pool.getCentralAmount().value,
outputReserve: pool.getSecondaryAmount().value,
});
pool.getCentralAmount().value,
pool.getSecondaryAmount().value,
);
return pool.getAmountMath().make(result);
},
getSecondaryToCentralOutputPrice: outputValue => {
assertPoolInitialized(pool);
const result = getOutputPrice({
const result = getOutputPrice(
outputValue,
inputReserve: pool.getSecondaryAmount().value,
outputReserve: pool.getCentralAmount().value,
});
pool.getSecondaryAmount().value,
pool.getCentralAmount().value,
);
return pool.getCentralAmountMath().make(result);
},
addLiquidity: userSeat => {
Expand All @@ -123,14 +121,16 @@ export const makeAddPool = (zcf, isSecondary, initPool, centralBrand) => {

// To calculate liquidity, we'll need to calculate alpha from the primary
// token's value before, and the value that will be added to the pool
const secondaryOut = pool.getAmountMath().make(
calcSecondaryRequired({
centralIn: userAllocation.Central.value,
centralPool: pool.getCentralAmount().value,
secondaryPool: pool.getSecondaryAmount().value,
secondaryIn: secondaryIn.value,
}),
);
const secondaryOut = pool
.getAmountMath()
.make(
calcSecondaryRequired(
userAllocation.Central.value,
pool.getCentralAmount().value,
pool.getSecondaryAmount().value,
secondaryIn.value,
),
);

// Central was specified precisely so offer must provide enough secondary.
assert(
Expand All @@ -146,25 +146,25 @@ export const makeAddPool = (zcf, isSecondary, initPool, centralBrand) => {
liquidityBrand,
);
const liquidityValueIn = liquidityIn.value;
const centralTokenAmountOut = pool.getCentralAmountMath().make(
calcValueToRemove(
harden({
const centralTokenAmountOut = pool
.getCentralAmountMath()
.make(
calcValueToRemove(
liqTokenSupply,
poolValue: pool.getCentralAmount().value,
pool.getCentralAmount().value,
liquidityValueIn,
}),
),
);
),
);

const tokenKeywordAmountOut = pool.getAmountMath().make(
calcValueToRemove(
harden({
const tokenKeywordAmountOut = pool
.getAmountMath()
.make(
calcValueToRemove(
liqTokenSupply,
poolValue: pool.getSecondaryAmount().value,
pool.getSecondaryAmount().value,
liquidityValueIn,
}),
),
);
),
);

liqTokenSupply -= liquidityValueIn;

Expand Down
Loading

0 comments on commit 068f4b1

Please sign in to comment.