IBalancerVault
IBalancerVault
WeightedPoolJoinKind
enum WeightedPoolJoinKind {
INIT,
EXACT_TOKENS_IN_FOR_BPT_OUT,
TOKEN_IN_FOR_EXACT_BPT_OUT,
ALL_TOKENS_IN_FOR_EXACT_BPT_OUT,
ADD_TOKEN
}
WeightedPoolExitKind
enum WeightedPoolExitKind {
EXACT_BPT_IN_FOR_ONE_TOKEN_OUT,
EXACT_BPT_IN_FOR_TOKENS_OUT,
BPT_IN_FOR_EXACT_TOKENS_OUT,
REMOVE_TOKEN
}
joinPool
function joinPool(bytes32 poolId, address sender, address recipient, struct IBalancerVault.JoinPoolRequest request) external payable
Called by users to join a Pool, which transfers tokens from sender
into the Pool's balance. This will
trigger custom Pool behavior, which will typically grant something in return to recipient
- often tokenized
Pool shares.
If the caller is not sender
, it must be an authorized relayer for them.
The assets
and maxAmountsIn
arrays must have the same length, and each entry indicates the maximum amount
to send for each asset. The amounts to send are decided by the Pool and not the Vault: it just enforces
these maximums.
If joining a Pool that holds WETH, it is possible to send ETH directly: the Vault will do the wrapping. To enable
this mechanism, the IAsset sentinel value (the zero address) must be passed in the assets
array instead of the
WETH address. Note that it is not possible to combine ETH and WETH in the same join. Any excess ETH will be sent
back to the caller (not the sender, which is important for relayers).
assets
must have the same length and order as the array returned by getPoolTokens
. This prevents issues when
interacting with Pools that register and deregister tokens frequently. If sending ETH however, the array must be
sorted before replacing the WETH address with the ETH sentinel value (the zero address), which means the final
assets
array might not be sorted. Pools with no registered tokens cannot be joined.
If fromInternalBalance
is true, the caller's Internal Balance will be preferred: ERC20 transfers will only
be made for the difference between the requested amount and Internal Balance (if any). Note that ETH cannot be
withdrawn from Internal Balance: attempting to do so will trigger a revert.
This causes the Vault to call the IBasePool.onJoinPool
hook on the Pool's contract, where Pools implement
their own custom logic. This typically requires additional information from the user (such as the expected number
of Pool shares). This can be encoded in the userData
argument, which is ignored by the Vault and passed
directly to the Pool's contract, as is recipient
.
Emits a PoolBalanceChanged
event.
JoinPoolRequest
struct JoinPoolRequest {
address[] assets;
uint256[] maxAmountsIn;
bytes userData;
bool fromInternalBalance;
}
exitPool
function exitPool(bytes32 poolId, address sender, address payable recipient, struct IBalancerVault.ExitPoolRequest request) external
Called by users to exit a Pool, which transfers tokens from the Pool's balance to recipient
. This will
trigger custom Pool behavior, which will typically ask for something in return from sender
- often tokenized
Pool shares. The amount of tokens that can be withdrawn is limited by the Pool's cash
balance (see
getPoolTokenInfo
).
If the caller is not sender
, it must be an authorized relayer for them.
The tokens
and minAmountsOut
arrays must have the same length, and each entry in these indicates the minimum
token amount to receive for each token contract. The amounts to send are decided by the Pool and not the Vault:
it just enforces these minimums.
If exiting a Pool that holds WETH, it is possible to receive ETH directly: the Vault will do the unwrapping. To
enable this mechanism, the IAsset sentinel value (the zero address) must be passed in the assets
array instead
of the WETH address. Note that it is not possible to combine ETH and WETH in the same exit.
assets
must have the same length and order as the array returned by getPoolTokens
. This prevents issues when
interacting with Pools that register and deregister tokens frequently. If receiving ETH however, the array must
be sorted before replacing the WETH address with the ETH sentinel value (the zero address), which means the
final assets
array might not be sorted. Pools with no registered tokens cannot be exited.
If toInternalBalance
is true, the tokens will be deposited to recipient
's Internal Balance. Otherwise,
an ERC20 transfer will be performed. Note that ETH cannot be deposited to Internal Balance: attempting to
do so will trigger a revert.
minAmountsOut
is the minimum amount of tokens the user expects to get out of the Pool, for each token in the
tokens
array. This array must match the Pool's registered tokens.
This causes the Vault to call the IBasePool.onExitPool
hook on the Pool's contract, where Pools implement
their own custom logic. This typically requires additional information from the user (such as the expected number
of Pool shares to return). This can be encoded in the userData
argument, which is ignored by the Vault and
passed directly to the Pool's contract.
Emits a PoolBalanceChanged
event.
ExitPoolRequest
struct ExitPoolRequest {
address[] assets;
uint256[] minAmountsOut;
bytes userData;
bool toInternalBalance;
}
getPoolTokens
function getPoolTokens(bytes32 poolId) external view returns (contract IERC20[] tokens, uint256[] balances, uint256 lastChangeBlock)
Returns a Pool's registered tokens, the total balance for each, and the latest block when any of
the tokens' balances
changed.
The order of the tokens
array is the same order that will be used in joinPool
, exitPool
, as well as in all
Pool hooks (where applicable). Calls to registerTokens
and deregisterTokens
may change this order.
If a Pool only registers tokens once, and these are sorted in ascending order, they will be stored in the same
order as passed to registerTokens
.
Total balances include both tokens held by the Vault and those withdrawn by the Pool's Asset Managers. These are
the amounts used by joins, exits and swaps. For a detailed breakdown of token balances, use getPoolTokenInfo
instead.
manageUserBalance
function manageUserBalance(struct IBalancerVault.UserBalanceOp[] ops) external payable
Performs a set of user balance operations, which involve Internal Balance (deposit, withdraw or transfer) and plain ERC20 transfers using the Vault's allowance. This last feature is particularly useful for relayers, as it lets integrators reuse a user's Vault allowance.
For each operation, if the caller is not sender
, it must be an authorized relayer for them.
UserBalanceOp
struct UserBalanceOp {
enum IBalancerVault.UserBalanceOpKind kind;
address asset;
uint256 amount;
address sender;
address payable recipient;
}
UserBalanceOpKind
enum UserBalanceOpKind {
DEPOSIT_INTERNAL,
WITHDRAW_INTERNAL,
TRANSFER_INTERNAL,
TRANSFER_EXTERNAL
}
SwapKind
enum SwapKind {
GIVEN_IN,
GIVEN_OUT
}
SingleSwap
struct SingleSwap {
bytes32 poolId;
enum IBalancerVault.SwapKind kind;
address assetIn;
address assetOut;
uint256 amount;
bytes userData;
}
FundManagement
struct FundManagement {
address sender;
bool fromInternalBalance;
address payable recipient;
bool toInternalBalance;
}
swap
function swap(struct IBalancerVault.SingleSwap singleSwap, struct IBalancerVault.FundManagement funds, uint256 limit, uint256 deadline) external returns (uint256 amountCalculated)
getPoolTokenInfo
function getPoolTokenInfo(bytes32 poolId, address token) external view returns (uint256 cash, uint256 managed, uint256 lastChangeBlock, address assetManager)