-
Notifications
You must be signed in to change notification settings - Fork 212
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: revamp multipoolAutoswap: liquidity bug, in vs. out prices
distinguish prices for stated input from prices for stated output. provide swapIn/swapOut to distinguish stated In/Out prices ensure proportionality is enforced when adding liquidity re-use the test jig match the autoswap API Tests for all combinations of swapIn/Out to/from central pool and trading secondary currencies Update documentation
- Loading branch information
1 parent
73f373b
commit 92bfdd5
Showing
10 changed files
with
1,189 additions
and
401 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 53 additions & 18 deletions
71
packages/zoe/src/contracts/multipoolAutoswap/getCurrentPrice.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,82 @@ | ||
import '../../../exported'; | ||
|
||
/** | ||
* Build functions to calculate prices for multipoolAutoswap. Two methods are | ||
* returned. In one the caller specifies the amount they will pay, and in the | ||
* other they specify the amount they wish to receive. | ||
* | ||
* @param {(brand: Brand) => boolean} isSecondary | ||
* @param {(brand: Brand) => boolean} isCentral | ||
* @param {(brand: Brand) => Pool} getPool | ||
*/ | ||
|
||
import '../../../exported'; | ||
|
||
export const makeGetCurrentPrice = (isSecondary, isCentral, getPool) => { | ||
/** | ||
* `getCurrentPrice` calculates the result of a trade, given a certain | ||
* `getOutputForGivenInput` calculates the result of a trade, given a certain | ||
* amount of digital assets in. | ||
* @param {Amount} amountIn - the amount of digital assets to be | ||
* sent in | ||
* @param {Brand} brandOut - the brand of the requested payment. | ||
* @param {Amount} amountIn - the amount of digital | ||
* assets to be sent in | ||
* @param {Brand} brandOut - The brand of asset desired | ||
* @return {Amount} the amount that would be paid out at the current price. | ||
*/ | ||
// eslint-disable-next-line consistent-return | ||
const getCurrentPrice = (amountIn, brandOut) => { | ||
// BrandIn could either be the central token brand, or one of | ||
// the secondary token brands. | ||
const getOutputForGivenInput = (amountIn, brandOut) => { | ||
const { brand: brandIn, value: inputValue } = amountIn; | ||
|
||
if (isCentral(brandIn) && isSecondary(brandOut)) { | ||
return getPool(brandOut).getCurrentPrice(true, inputValue); | ||
return getPool(brandOut).getCentralToSecondaryInputPrice(inputValue); | ||
} | ||
|
||
if (isSecondary(brandIn) && isCentral(brandOut)) { | ||
return getPool(brandIn).getSecondaryToCentralInputPrice(inputValue); | ||
} | ||
|
||
if (isSecondary(brandIn) && isSecondary(brandOut)) { | ||
// We must do two consecutive calls to get the price: from | ||
// the brandIn to the central token, then from the central | ||
// token to the brandOut. | ||
const centralTokenAmount = getPool( | ||
brandIn, | ||
).getSecondaryToCentralInputPrice(inputValue); | ||
return getPool(brandOut).getCentralToSecondaryInputPrice( | ||
centralTokenAmount.value, | ||
); | ||
} | ||
|
||
throw new Error(`brands were not recognized`); | ||
}; | ||
|
||
/** | ||
* `getInputForGivenOutput` calculates the amount of assets required to be | ||
* provided in order to obtain a specified gain. | ||
* @param {Amount} amountOut - the amount of digital assets desired | ||
* @param {Brand} brandIn - The brand of asset desired | ||
* @return {Amount} The amount required to be paid in order to gain amountOut | ||
*/ | ||
const getInputForGivenOutput = (amountOut, brandIn) => { | ||
const { brand: brandOut, value: outputValue } = amountOut; | ||
|
||
if (isCentral(brandIn) && isSecondary(brandOut)) { | ||
return getPool(brandOut).getCentralToSecondaryOutputPrice(outputValue); | ||
} | ||
|
||
if (isSecondary(brandIn) && isCentral(brandOut)) { | ||
return getPool(brandIn).getCurrentPrice(false, inputValue); | ||
return getPool(brandIn).getSecondaryToCentralOutputPrice(outputValue); | ||
} | ||
|
||
if (isSecondary(brandIn) && isSecondary(brandOut)) { | ||
// We must do two consecutive `getCurrentPrice` calls: from | ||
// We must do two consecutive calls to get the price: from | ||
// the brandIn to the central token, then from the central | ||
// token to the brandOut. | ||
const centralTokenAmount = getPool(brandIn).getCurrentPrice( | ||
false, | ||
inputValue, | ||
const centralTokenAmount = getPool( | ||
brandIn, | ||
).getSecondaryToCentralOutputPrice(outputValue); | ||
return getPool(brandOut).getCentralToSecondaryOutputPrice( | ||
centralTokenAmount.value, | ||
); | ||
return getPool(brandOut).getCurrentPrice(true, centralTokenAmount.value); | ||
} | ||
|
||
throw new Error(`brands were not recognized`); | ||
}; | ||
|
||
return getCurrentPrice; | ||
return { getOutputForGivenInput, getInputForGivenOutput }; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.