Pool

Git Source

Inherits: Ownable, ReentrancyGuard

State Variables

PRECISION

uint256 constant PRECISION = 1_000_000_000_000_000_000;

MAX_NUM_TOKENS

uint256 constant MAX_NUM_TOKENS = 32;

ALL_TOKENS_FLAG

uint256 constant ALL_TOKENS_FLAG =
    14_528_991_250_861_404_666_834_535_435_384_615_765_856_667_510_756_806_797_353_855_100_662_256_435_713;

POOL_VB_MASK

uint256 constant POOL_VB_MASK = 2 ** 128 - 1;

POOL_VB_SHIFT

uint128 constant POOL_VB_SHIFT = 128;

VB_MASK

uint256 constant VB_MASK = 2 ** 96 - 1;

RATE_MASK

uint256 constant RATE_MASK = 2 ** 80 - 1;

RATE_SHIFT

uint128 constant RATE_SHIFT = 96;

PACKED_WEIGHT_SHIFT

uint128 constant PACKED_WEIGHT_SHIFT = 176;

WEIGHT_SCALE

uint256 constant WEIGHT_SCALE = 1_000_000_000_000;

WEIGHT_MASK

uint256 constant WEIGHT_MASK = 2 ** 20 - 1;

TARGET_WEIGHT_SHIFT

uint128 constant TARGET_WEIGHT_SHIFT = 20;

LOWER_BAND_SHIFT

uint128 constant LOWER_BAND_SHIFT = 40;

UPPER_BAND_SHIFT

uint128 constant UPPER_BAND_SHIFT = 60;

MAX_POW_REL_ERR

uint256 constant MAX_POW_REL_ERR = 100;

amplification

uint256 public amplification;

numTokens

uint256 public numTokens;

supply

uint256 public supply;

tokenAddress

address public tokenAddress;

stakingAddress

address public stakingAddress;

tokens

address[MAX_NUM_TOKENS] public tokens;

rateProviders

address[MAX_NUM_TOKENS] public rateProviders;

packedVirtualBalances

uint256[MAX_NUM_TOKENS] public packedVirtualBalances;

paused

bool public paused;

killed

bool public killed;

swapFeeRate

uint256 public swapFeeRate;

rampStep

uint256 public rampStep;

rampLastTime

uint256 public rampLastTime;

rampStopTime

uint256 public rampStopTime;

targetAmplification

uint256 public targetAmplification;

packedPoolVirtualBalance

uint256 packedPoolVirtualBalance;

Functions

constructor

constructor

sum of all weights

rebasing tokens not supported

constructor(
    address tokenAddress_,
    uint256 amplification_,
    address[] memory tokens_,
    address[] memory rateProviders_,
    uint256[] memory weights_,
    address owner_
);

Parameters

NameTypeDescription
tokenAddress_addressaddress of the poolToken
amplification_uint256the pool amplification factor (in 18 decimals)
tokens_address[]array of addresses of tokens in the pool
rateProviders_address[]array of addresses of rate providers for the tokens in the pool
weights_uint256[]weight of each token (in 18 decimals)
owner_address

swap

swap one pool token for another

function swap(
    uint256 tokenIn_,
    uint256 tokenOut_,
    uint256 tokenInAmount_,
    uint256 minTokenOutAmount_,
    address receiver_
) external nonReentrant returns (uint256);

Parameters

NameTypeDescription
tokenIn_uint256index of the input token
tokenOut_uint256index of the output token
tokenInAmount_uint256amount of input token to take from the caller
minTokenOutAmount_uint256minimum amount of output token to send
receiver_addressaccount to receive the output token

Returns

NameTypeDescription
<none>uint256the amount of output token

addLiquidity

deposit tokens into the pool

function addLiquidity(uint256[] calldata amounts_, uint256 minLpAmount_, address receiver_)
    external
    nonReentrant
    returns (uint256);

Parameters

NameTypeDescription
amounts_uint256[]array of the amount for each token to take from caller
minLpAmount_uint256minimum amount of lp tokens to mint
receiver_addressaccount to receive the lp tokens

Returns

NameTypeDescription
<none>uint256amount of LP tokens minted

removeLiquidity

withdraw tokens from the pool in a balanced manner

function removeLiquidity(uint256 lpAmount_, uint256[] calldata minAmounts_, address receiver_) external nonReentrant;

Parameters

NameTypeDescription
lpAmount_uint256amount of lp tokens to burn
minAmounts_uint256[]array of minimum amount of each token to send
receiver_addressaccount to receive the tokens

removeLiquiditySingle

withdraw a single token from the pool

function removeLiquiditySingle(uint256 token_, uint256 lpAmount_, uint256 minTokenOutAmount_, address receiver_)
    external
    nonReentrant
    returns (uint256);

Parameters

NameTypeDescription
token_uint256index of the token to withdraw
lpAmount_uint256amount of lp tokens to burn
minTokenOutAmount_uint256minimum amount of tokens to send
receiver_addressaccount to receive the token

Returns

NameTypeDescription
<none>uint256the amount of the token sent

updateRates

update the stored rate of any of the pool's tokens

if no assets are passed in, every asset will be updated

function updateRates(uint256[] calldata tokens_) external;

Parameters

NameTypeDescription
tokens_uint256[]array of indices of tokens to update

updateWeights

update weights and amplification factor, if possible

will only update the weights if a ramp is active and at least the minimum time step has been reached

function updateWeights() external returns (bool);

Returns

NameTypeDescription
<none>boolboolean to indicate whether the weights and amplification factor have been updated

virtualBalanceProdSum

get the pool's virtual balance product (pi) and sum (sigma)

function virtualBalanceProdSum() external view returns (uint256, uint256);

Returns

NameTypeDescription
<none>uint256tuple with product and sum
<none>uint256

virtualBalance

get the virtual balance of a token

function virtualBalance(uint256 token_) external view returns (uint256);

Parameters

NameTypeDescription
token_uint256index of the token in the pool

Returns

NameTypeDescription
<none>uint256virtual balance of the token

rate

get the rate of an token

function rate(uint256 token_) external view returns (uint256);

Parameters

NameTypeDescription
token_uint256index of the token

Returns

NameTypeDescription
<none>uint256rate of the token

weight

get the weight of a token

does not take into account any active ramp

function weight(uint256 token_) external view returns (uint256, uint256, uint256, uint256);

Parameters

NameTypeDescription
token_uint256index of the token

Returns

NameTypeDescription
<none>uint256tuple with weight, target weight, lower band width, upper weight band width
<none>uint256
<none>uint256
<none>uint256

packedWeight

get the packed weight of a token in a packed format

does not take into account any active ramp

function packedWeight(uint256 token_) external view returns (uint256);

Parameters

NameTypeDescription
token_uint256index of the token

Returns

NameTypeDescription
<none>uint256weight in packed format

pause

pause the pool

function pause() external onlyOwner;

unpause

unpause the pool

function unpause() external onlyOwner;

kill

kill the pool

function kill() external onlyOwner;

addToken

add a new token to the pool

can only be called if no ramp is currently active

every other token will their weight reduced pro rata

caller should assure that amplification before and after the call are the same

function addToken(
    address token_,
    address rateProvider_,
    uint256 weight_,
    uint256 lower_,
    uint256 upper_,
    uint256 amount_,
    uint256 amplification_,
    uint256 minLpAmount_,
    address receiver_
) external onlyOwner;

Parameters

NameTypeDescription
token_addressaddress of the token to add
rateProvider_addressrate provider for the token
weight_uint256weight of the new token
lower_uint256lower band width
upper_uint256upper band width
amount_uint256amount of tokens
amplification_uint256new pool amplification factor
minLpAmount_uint256
receiver_addressaccount to receive the lp tokens minted

rescue

rescue tokens from this contract

cannot be used to rescue pool tokens

function rescue(address token_, address receiver_) external onlyOwner;

Parameters

NameTypeDescription
token_addressthe token to be rescued
receiver_addressreceiver of the rescued tokens

skim

skim surplus of a pool token

function skim(uint256 token_, address receiver_) external onlyOwner;

Parameters

NameTypeDescription
token_uint256index of the token
receiver_addressreceiver of the skimmed tokens

setSwapFeeRate

set new swap fee rate

function setSwapFeeRate(uint256 feeRate_) external onlyOwner;

Parameters

NameTypeDescription
feeRate_uint256new swap fee rate (in 18 decimals)

setWeightBands

set safeft weight bands, if any user operation puts the weight outside of the bands, the transaction will revert

function setWeightBands(uint256[] calldata tokens_, uint256[] calldata lower_, uint256[] calldata upper_)
    external
    onlyOwner;

Parameters

NameTypeDescription
tokens_uint256[]array of indices of the tokens to set the bands for
lower_uint256[]array of widths of the lower band
upper_uint256[]array of widths of the upper band

setRateProvider

set a rate provider for a token

function setRateProvider(uint256 token_, address rateProvider_) external onlyOwner;

Parameters

NameTypeDescription
token_uint256index of the token
rateProvider_addressnew rate provider for the token

setRamp

schedule an amplification and/or weight change

effective amplification at any time is amplification/f^n

function setRamp(uint256 amplification_, uint256[] calldata weights_, uint256 duration_, uint256 start_)
    external
    onlyOwner;

Parameters

NameTypeDescription
amplification_uint256new amplification factor (in 18 decimals)
weights_uint256[]array of the new weight for each token (in 18 decimals)
duration_uint256duration of the ramp (in seconds)
start_uint256ramp start time

setRampStep

set the minimum time b/w ramp step

function setRampStep(uint256 rampStep_) external onlyOwner;

Parameters

NameTypeDescription
rampStep_uint256minimum step time (in seconds)

stopRamp

stop an active ramp

function stopRamp() external onlyOwner;

setStaking

set the address that receives yield, slashings and swap fees

function setStaking(address stakingAddress_) external onlyOwner;

Parameters

NameTypeDescription
stakingAddress_addressnew staking address

_updateRates

update rates of specific tokens

loops through the bytes in token_ until a zero or a number larger than the number of assets is encountered

update weights (if needed) prior to checking any rates

will recalculate supply and mint/burn to staking contract if any weight or rate has updated

will revert if any rate increases by more than 10%, unless called by management

function _updateRates(uint256 tokens_, uint256 virtualBalanceProd_, uint256 virtualBalanceSum_)
    internal
    returns (uint256, uint256);

Parameters

NameTypeDescription
tokens_uint256integer where each byte represents a token index offset by one
virtualBalanceProd_uint256product term (pi) before update
virtualBalanceSum_uint256sum term (sigma) before update

Returns

NameTypeDescription
<none>uint256tuple with new product and sum term
<none>uint256

_updateWeights

apply a step in amplitude and weight ramp, if applicable

caller is reponsible for updating supply if a step has been taken

function _updateWeights(uint256 vbProd_) internal returns (uint256, bool);

Parameters

NameTypeDescription
vbProd_uint256product term(pi) before update

Returns

NameTypeDescription
<none>uint256tuple with new product term and flag indicating if a step has been taken
<none>bool

_updateSupply

calculate supply and burn or mint difference from the staking contract

function _updateSupply(uint256 supply_, uint256 vbProd_, uint256 vbSum_) internal returns (uint256, uint256);

Parameters

NameTypeDescription
supply_uint256previous supply
vbProd_uint256product term (pi)
vbSum_uint256sum term (sigma)

Returns

NameTypeDescription
<none>uint256tuple with new supply and product term
<none>uint256

_checkBands

check whether asset is within safety band, or if previously outside, moves closer to it

reverts if conditions are not met

function _checkBands(uint256 prevRatio_, uint256 ratio_, uint256 packedWeight_) internal pure;

Parameters

NameTypeDescription
prevRatio_uint256token ratio before user action
ratio_uint256token ratio after user action
packedWeight_uint256packed weight

_calculateVirtualBalanceProdSum

calculate product term (pi) and sum term (sigma)

function _calculateVirtualBalanceProdSum() internal view returns (uint256, uint256);

Returns

NameTypeDescription
<none>uint256tuple with product and sum term
<none>uint256

_calculateVirtualBalanceProd

calculate product term (pi)

function _calculateVirtualBalanceProd(uint256 supply_) internal view returns (uint256);

Parameters

NameTypeDescription
supply_uint256supply to use in product term

Returns

NameTypeDescription
<none>uint256product term

_calculateSupply

calculate supply iteratively

function _calculateSupply(
    uint256 numTokens_,
    uint256 supply_,
    uint256 amplification_,
    uint256 virtualBalanceProd_,
    uint256 virtualBalanceSum_,
    bool up_
) internal pure returns (uint256, uint256);

Parameters

NameTypeDescription
numTokens_uint256number of tokens in the pool
supply_uint256supply as used in product term
amplification_uint256amplification factor (A f^n)
virtualBalanceProd_uint256product term (pi)
virtualBalanceSum_uint256sum term (sigma)
up_boolwhether to round up

Returns

NameTypeDescription
<none>uint256tuple with new supply and product term
<none>uint256

_calculateVirtualBalance

calculate a single token's virtual balance iteratively using newton's method

function _calculateVirtualBalance(
    uint256 wn_,
    uint256 y_,
    uint256 supply_,
    uint256 amplification_,
    uint256 vbProd_,
    uint256 vbSum_
) internal pure returns (uint256);

Parameters

NameTypeDescription
wn_uint256token weight times number of tokens
y_uint256starting value
supply_uint256supply
amplification_uint256amplification factor A f^n
vbProd_uint256intermediary product term (pi~), pi with previous balances factored out and new balance factored in
vbSum_uint256intermediary sum term (sigma~), sigma with previous balances subtracted and new balance added

Returns

NameTypeDescription
<none>uint256new token virtual balance

_packVirtualBalance

pack virtual balance of a token along with other related variables

function _packVirtualBalance(uint256 virtualBalance_, uint256 rate_, uint256 packedWeight_)
    internal
    pure
    returns (uint256);

Parameters

NameTypeDescription
virtualBalance_uint256virtual balance of a token
rate_uint256token rate
packedWeight_uint256packed weight of a token

Returns

NameTypeDescription
<none>uint256packed variable

_unpackVirtualBalance

unpack variable to it's components

function _unpackVirtualBalance(uint256 packed_) internal pure returns (uint256, uint256, uint256);

Parameters

NameTypeDescription
packed_uint256packed variable

Returns

NameTypeDescription
<none>uint256tuple with virtual balance, rate and packed weight
<none>uint256
<none>uint256

_packWeight

pack weight with target and bands

function _packWeight(uint256 weight_, uint256 target_, uint256 lower_, uint256 upper_)
    internal
    pure
    returns (uint256);

Parameters

NameTypeDescription
weight_uint256weight with 18 decimals
target_uint256target weight with 18 decimals
lower_uint256lower band with 18 decimals, allowed distance from weight in negative direction
upper_uint256upper band with 18 decimal, allowed distance from weight in positive direction

_unpackWeight

unpack weight to its components

function _unpackWeight(uint256 packed_) internal pure returns (uint256, uint256, uint256, uint256);

Parameters

NameTypeDescription
packed_uint256packed weight

Returns

NameTypeDescription
<none>uint256tuple with weight, target weight, lower band and upper band (all in 18 decimals)
<none>uint256
<none>uint256
<none>uint256

_unpackWeightTimesN

unpack weight and multiply by number of tokens

function _unpackWeightTimesN(uint256 packed_, uint256 numTokens_) internal pure returns (uint256);

Parameters

NameTypeDescription
packed_uint256packed weight
numTokens_uint256number of tokens

Returns

NameTypeDescription
<none>uint256weight multiplied by number of tokens (18 decimals)

_packPoolVirtualBalance

pack pool product and sum term

function _packPoolVirtualBalance(uint256 prod_, uint256 sum_) internal pure returns (uint256);

Parameters

NameTypeDescription
prod_uint256Product term (pi)
sum_uint256Sum term (sigma)

Returns

NameTypeDescription
<none>uint256packed term

_unpackPoolVirtualBalance

unpack pool product and sum term

function _unpackPoolVirtualBalance(uint256 packed_) internal pure returns (uint256, uint256);

Parameters

NameTypeDescription
packed_uint256packed terms

Returns

NameTypeDescription
<none>uint256tuple with pool product term (pi) and pool sum term (sigma)
<none>uint256

_checkIfPaused

function _checkIfPaused() internal view;

_powUp

function _powUp(uint256 x, uint256 y) internal pure returns (uint256);

_powDown

function _powDown(uint256 x, uint256 y) internal pure returns (uint256);

Events

Swap

event Swap(
    address indexed caller, address receiver, uint256 tokenIn, uint256 tokenOut, uint256 amountIn, uint256 amountOut
);

AddLiquidity

event AddLiquidity(address indexed caller, address receiver, uint256[] amountsIn, uint256 lpAmount);

RemoveLiquidity

event RemoveLiquidity(address indexed caller, address receiver, uint256 lpAmount);

RemoveLiquiditySingle

event RemoveLiquiditySingle(
    address indexed caller, address receiver, uint256 token, uint256 amountOut, uint256 lpAmount
);

RateUpdate

event RateUpdate(uint256 indexed token, uint256 rate);

Pause

event Pause(address indexed caller);

Unpause

event Unpause(address indexed caller);

Kill

event Kill();

AddToken

event AddToken(uint256 index, address token, address rateProvider, uint256 rate, uint256 weight, uint256 amount);

SetSwapFeeRate

event SetSwapFeeRate(uint256 rate);

SetWeightBand

event SetWeightBand(uint256 indexed token, uint256 lower, uint256 upper);

SetRateProvider

event SetRateProvider(uint256 token, address rateProvider);

SetRamp

event SetRamp(uint256 amplification, uint256[] weights, uint256 duration, uint256 start);

SetRampStep

event SetRampStep(uint256 rampStep);

StopRamp

event StopRamp();

SetStaking

event SetStaking(address stakingAddress);

SetGuardian

event SetGuardian(address indexed caller, address guardian);

Errors

Pool__InputOutputTokensSame

error Pool__InputOutputTokensSame();

Pool__IndexOutOfBounds

error Pool__IndexOutOfBounds();

Pool__MaxLimitExceeded

error Pool__MaxLimitExceeded();

Pool__ZeroAmount

error Pool__ZeroAmount();

Pool__MustBeInitiatedWithMoreThanOneToken

error Pool__MustBeInitiatedWithMoreThanOneToken();

Pool__MustBeInitiatedWithAGreaterThanZero

error Pool__MustBeInitiatedWithAGreaterThanZero();

Pool__InvalidParams

error Pool__InvalidParams();

Pool__CannotBeZeroAddress

error Pool__CannotBeZeroAddress();

Pool__InvalidDecimals

error Pool__InvalidDecimals();

Pool__SumOfWeightsMustBeOne

error Pool__SumOfWeightsMustBeOne();

Pool__InvalidRateProvided

error Pool__InvalidRateProvided();

Pool__NoConvergence

error Pool__NoConvergence();

Pool__RatioBelowLowerBound

error Pool__RatioBelowLowerBound();

Pool__RatioAboveUpperBound

error Pool__RatioAboveUpperBound();

Pool__SlippageLimitExceeded

error Pool__SlippageLimitExceeded();

Pool__NeedToDepositAtleastOneToken

error Pool__NeedToDepositAtleastOneToken();

Pool__InitialDepositAmountMustBeNonZero

error Pool__InitialDepositAmountMustBeNonZero();

Pool__AmountsMustBeNonZero

error Pool__AmountsMustBeNonZero();

Pool__WeightOutOfBounds

error Pool__WeightOutOfBounds();

Pool__PoolIsFull

error Pool__PoolIsFull();

Pool__RampActive

error Pool__RampActive();

Pool__PoolIsEmpty

error Pool__PoolIsEmpty();

Pool__TokenAlreadyPartOfPool

error Pool__TokenAlreadyPartOfPool();

Pool__CannotRescuePoolToken

error Pool__CannotRescuePoolToken();

Pool__BandsOutOfBounds

error Pool__BandsOutOfBounds();

Pool__WeightsDoNotAddUp

error Pool__WeightsDoNotAddUp();

Pool__AlreadyPaused

error Pool__AlreadyPaused();

Pool__NotPaused

error Pool__NotPaused();

Pool__Killed

error Pool__Killed();

Pool__NoSurplus

error Pool__NoSurplus();

Pool__NoRate

error Pool__NoRate();

Pool__Paused

error Pool__Paused();