Skip to main content

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)