Swap
This contract is responsible for custody of closely pegged assets (eg. group of stablecoins) and automatic market making system. Users become an LP (Liquidity Provider) by depositing their tokens in desired ratios for an exchange of the pool token that represents their share of the pool. Users can burn pool tokens and withdraw their share of token(s).
Each time a swap between the pooled tokens happens, a set fee incurs which effectively gets distributed to the LPs.
In case of emergencies, admin can pause additional deposits, swaps, or single-asset withdraws - which stops the ratio of the tokens in the pool from changing. Users can always withdraw their tokens via multi-asset withdraws.
Most of the logic is stored as a library SwapUtils
for the sake of reducing contract's deployment size.
Functions:
getA()
getAPrecise()
getToken(uint8 index)
getTokenIndex(address tokenAddress)
getAllowlist()
getDepositTimestamp(address user)
getTokenBalance(uint8 index)
getVirtualPrice()
calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)
calculateTokenAmount(address account, uint256[] amounts, bool deposit)
calculateRemoveLiquidity(address account, uint256 amount)
calculateRemoveLiquidityOneToken(address account, uint256 tokenAmount, uint8 tokenIndex)
getAdminBalance(uint256 index)
swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)
addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline, bytes32[] merkleProof)
removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline)
removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline)
removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline)
updateUserWithdrawFee(address recipient, uint256 transferAmount)
withdrawAdminFees()
setAdminFee(uint256 newAdminFee)
setSwapFee(uint256 newSwapFee)
rampA(uint256 futureA, uint256 futureTime)
stopRampA()
disableGuard()
isGuarded()
Events:
TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)
AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)
RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)
RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)
RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)
NewAdminFee(uint256 newAdminFee)
NewSwapFee(uint256 newSwapFee)
RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime)
StopRampA(uint256 currentA, uint256 time)
Function constructor(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, contract IAllowlist _allowlist)
constructor(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, contract IAllowlist _allowlist)
Deploys this Swap contract with given parameters as default values. This will also deploy a LPToken that represents users LP position. The owner of LPToken will be this contract - which means only this contract is allowed to mint new tokens.
Parameters:
_pooledTokens
: an array of ERC20s this pool will acceptdecimals
: the decimals to use for each pooled token, eg 8 for WBTC. Cannot be larger than POOL_PRECISION_DECIMALSlpTokenName
: the long-form name of the token to be deployedlpTokenSymbol
: the short symbol for the token to be deployed_a
: the amplification coefficient n (n - 1). See the StableSwap paper for details_fee
: default swap fee to be initialized with_adminFee
: default adminFee to be initialized with_allowlist
: address of allowlist contract for guarded launch
Function getA() → uint256
getA() → uint256
Return A, the amplification coefficient n (n - 1)
See the StableSwap paper for details
Return Values:
A parameter
Function getAPrecise() → uint256
getAPrecise() → uint256
Return A in its raw precision form
See the StableSwap paper for details
Return Values:
A parameter in its raw precision form
Function getToken(uint8 index) → contract IERC20
getToken(uint8 index) → contract IERC20
Return address of the pooled token at given index. Reverts if tokenIndex is out of range.
Parameters:
index
: the index of the token
Return Values:
address of the token at given index
Function getTokenIndex(address tokenAddress) → uint8
getTokenIndex(address tokenAddress) → uint8
Return the index of the given token address. Reverts if no matching token is found.
Parameters:
tokenAddress
: address of the token
Return Values:
the index of the given token address
Function getAllowlist() → contract IAllowlist
getAllowlist() → contract IAllowlist
Reads and returns the address of the allowlist that is set during deployment of this contract
Return Values:
the address of the allowlist contract casted to the IAllowlist interface
Function getDepositTimestamp(address user) → uint256
getDepositTimestamp(address user) → uint256
Return timestamp of last deposit of given address
Return Values:
timestamp of the last deposit made by the given address
Function getTokenBalance(uint8 index) → uint256
getTokenBalance(uint8 index) → uint256
Return current balance of the pooled token at given index
Parameters:
index
: the index of the token
Return Values:
current balance of the pooled token at given index with token's native precision
Function getVirtualPrice() → uint256
getVirtualPrice() → uint256
Get the virtual price, to help calculate profit
Return Values:
the virtual price, scaled to the POOL_PRECISION_DECIMALS
Function calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256
calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256
Calculate amount of tokens you receive on swap
Parameters:
tokenIndexFrom
: the token the user wants to selltokenIndexTo
: the token the user wants to buydx
: the amount of tokens the user wants to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.
Return Values:
amount of tokens the user will receive
Function calculateTokenAmount(address account, uint256[] amounts, bool deposit) → uint256
calculateTokenAmount(address account, uint256[] amounts, bool deposit) → uint256
A simple method to calculate prices from deposits or withdrawals, excluding fees but including slippage. This is helpful as an input into the various "min" parameters on calls to fight front-running
This shouldn't be used outside frontends for user estimates.
Parameters:
account
: address that is depositing or withdrawing tokensamounts
: an array of token amounts to deposit or withdrawal, corresponding to pooledTokens. The amount should be in each pooled token's native precision. If a token charges a fee on transfers, use the amount that gets transferred after the fee.deposit
: whether this is a deposit or a withdrawal
Return Values:
token amount the user will receive
Function calculateRemoveLiquidity(address account, uint256 amount) → uint256[]
calculateRemoveLiquidity(address account, uint256 amount) → uint256[]
A simple method to calculate amount of each underlying tokens that is returned upon burning given amount of LP tokens
Parameters:
account
: the address that is withdrawing tokensamount
: the amount of LP tokens that would be burned on withdrawal
Return Values:
array of token balances that the user will receive
Function calculateRemoveLiquidityOneToken(address account, uint256 tokenAmount, uint8 tokenIndex) → uint256 availableTokenAmount
calculateRemoveLiquidityOneToken(address account, uint256 tokenAmount, uint8 tokenIndex) → uint256 availableTokenAmount
Calculate the amount of underlying token available to withdraw when withdrawing via only single token
Parameters:
account
: the address that is withdrawing tokenstokenAmount
: the amount of LP token to burntokenIndex
: index of which token will be withdrawn
Return Values:
availableTokenAmount calculated amount of underlying token
available to withdraw
Function getAdminBalance(uint256 index) → uint256
getAdminBalance(uint256 index) → uint256
This function reads the accumulated amount of admin fees of the token with given index
Parameters:
index
: Index of the pooled token
Return Values:
s token balance in the token's precision
Function swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256
swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256
Swap two tokens using this pool
Parameters:
tokenIndexFrom
: the token the user wants to swap fromtokenIndexTo
: the token the user wants to swap todx
: the amount of tokens the user wants to swap fromminDy
: the min amount the user would like to receive, or revert.deadline
: latest timestamp to accept this transaction
Function addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline, bytes32[] merkleProof) → uint256
addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline, bytes32[] merkleProof) → uint256
Add liquidity to the pool with given amounts during guarded launch phase. Only users with valid address and proof can successfully call this function. When this function is called after the guarded release phase is over, the merkleProof is ignored.
Parameters:
amounts
: the amounts of each token to add, in their native precisionminToMint
: the minimum LP tokens adding this amount of liquidity should mint, otherwise revert. Handy for front-running mitigationdeadline
: latest timestamp to accept this transactionmerkleProof
: data generated when constructing the allowlist merkle tree. Users can get this data off chain. Even if the address is in the allowlist, users must include a valid proof for this call to succeed. If the pool is no longer in the guarded release phase, this parameter is ignored.
Return Values:
amount of LP token user minted and received
Function removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline) → uint256[]
removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline) → uint256[]
Burn LP tokens to remove liquidity from the pool.
Liquidity can always be removed, even when the pool is paused.
Parameters:
amount
: the amount of LP tokens to burnminAmounts
: the minimum amounts of each token in the pool acceptable for this burn. Useful as a front-running mitigationdeadline
: latest timestamp to accept this transaction
Return Values:
amounts of tokens user received
Function removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256
removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256
Remove liquidity from the pool all in one token.
Parameters:
tokenAmount
: the amount of the token you want to receivetokenIndex
: the index of the token you want to receiveminAmount
: the minimum amount to withdraw, otherwise revertdeadline
: latest timestamp to accept this transaction
Return Values:
amount of chosen token user received
Function removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256
removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256
Remove liquidity from the pool, weighted differently than the pool's current balances.
Parameters:
amounts
: how much of each token to withdrawmaxBurnAmount
: the max LP token provider is willing to pay to remove liquidity. Useful as a front-running mitigation.deadline
: latest timestamp to accept this transaction
Return Values:
amount of LP tokens burned
Function withdrawAdminFees()
withdrawAdminFees()
Withdraw all admin fees to the contract owner
Function setAdminFee(uint256 newAdminFee)
setAdminFee(uint256 newAdminFee)
Update the admin fee. Admin fee takes portion of the swap fee.
Parameters:
newAdminFee
: new admin fee to be applied on future transactions
Function setSwapFee(uint256 newSwapFee)
setSwapFee(uint256 newSwapFee)
Update the swap fee to be applied on swaps
Parameters:
newSwapFee
: new swap fee to be applied on future transactions
Function rampA(uint256 futureA, uint256 futureTime)
rampA(uint256 futureA, uint256 futureTime)
Start ramping up or down A parameter towards given futureA and futureTime Checks if the change is too rapid, and commits the new A value only when it falls under the limit range.
Parameters:
futureA
: the new A to ramp towardsfutureTime
: timestamp when the new A should be reached
Function stopRampA()
stopRampA()
Stop ramping A immediately. Reverts if ramp A is already stopped.
Function disableGuard()
disableGuard()
Disables the guarded launch phase, removing any limits on deposit amounts and addresses
Function isGuarded() → bool
isGuarded() → bool
Reads and returns current guarded status of the pool
Return Values:
guarded_ boolean value indicating whether the deposits should be guarded
Event TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)
TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)
No description
Event AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)
AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)
No description
Event RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)
RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)
No description
Event RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)
RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)
No description
Event RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)
RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)
No description
Event NewAdminFee(uint256 newAdminFee)
NewAdminFee(uint256 newAdminFee)
No description
Event NewSwapFee(uint256 newSwapFee)
NewSwapFee(uint256 newSwapFee)
No description
Event NewWithdrawFee(uint256 newWithdrawFee)
NewWithdrawFee(uint256 newWithdrawFee)
No description
Event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime)
RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime)
No description
Event StopRampA(uint256 currentA, uint256 time)
StopRampA(uint256 currentA, uint256 time)
No description
Last updated