Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: simplify autoswap helper APIs #1732

Merged
merged 1 commit into from
Sep 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
dtribble marked this conversation as resolved.
Show resolved Hide resolved
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