Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"src/BalancerV3MultiActionQueries.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IVaultMain} from "@balancer-labs/v3-interfaces/contracts/vault/IVaultMain.sol";
import {IVaultExtension} from "@balancer-labs/v3-interfaces/contracts/vault/IVaultExtension.sol";
import {RevertCodec} from "@balancer-labs/v3-solidity-utils/contracts/helpers/RevertCodec.sol";
import "@balancer-labs/v3-interfaces/contracts/vault/VaultTypes.sol";
import "./interfaces/IBalancerV3MultiActionQueries.sol";
/**
* @title BalancerV3MultiActionQueries
* @notice Contract for querying sequences of actions in Balancer V3 pools
*/
contract BalancerV3MultiActionQueries is IBalancerV3MultiActionQueries {
address public immutable vault;
constructor(address _vault) {
vault = _vault;
}
/**
* @notice Query a sequence of actions on a Balancer V3 pool
* @param pool The pool address to query
* @param actions Array of actions to simulate
* @return amountsOut Array of output amounts for each action
*/
function queryActions(address pool, PoolAction[] calldata actions) external returns (uint256[] memory amountsOut) {
bytes memory data = abi.encodeCall(this.executeActions, (pool, actions));
try IVaultExtension(vault).quoteAndRevert(data) {
revert("Query did not revert");
} catch (bytes memory revertData) {
bytes memory decodedData = RevertCodec.catchEncodedResult(revertData);
return abi.decode(decodedData, (uint256[]));
}
}
/**
* @notice Find the index of a token in the pool's token array
* @param tokens Array of pool tokens
* @param token Token to find
* @return Index of the token in the array
*/
function _findTokenIndex(IERC20[] memory tokens, IERC20 token) internal pure returns (uint256) {
for (uint256 i = 0; i < tokens.length; i++) {
if (tokens[i] == token) {
return i;
}
}
revert("Token not found in pool");
}
/**
* @notice Callback function executed by the vault during query
* @param pool The pool to execute actions on
* @param actions Array of actions to execute
* @return amountsOut Array of output amounts for each action
*/
function executeActions(address pool, PoolAction[] calldata actions)
external
returns (uint256[] memory amountsOut)
{
require(msg.sender == vault, "Unauthorized");
amountsOut = new uint256[](actions.length);
for (uint256 i = 0; i < actions.length; i++) {
PoolAction calldata action = actions[i];
if (action.actionType == ActionType.SWAP) {
(,, uint256 amountOut) = IVaultMain(vault).swap(
VaultSwapParams({
kind: SwapKind.EXACT_IN,
pool: pool,
tokenIn: action.tokenIn,
tokenOut: action.tokenOut,
amountGivenRaw: action.amountIn,
limitRaw: 0,
userData: ""
})
);
amountsOut[i] = amountOut;
} else if (action.actionType == ActionType.DEPOSIT_SINGLE_TOKEN) {
IERC20[] memory tokens = IVaultExtension(vault).getPoolTokens(pool);
uint256 tokenIndex = _findTokenIndex(tokens, action.tokenIn);
uint256[] memory maxAmountsIn = new uint256[](tokens.length);
maxAmountsIn[tokenIndex] = action.amountIn;
(, uint256 bptAmountOut,) = IVaultMain(vault).addLiquidity(
AddLiquidityParams({
pool: pool,
to: address(this),
maxAmountsIn: maxAmountsIn,
minBptAmountOut: 0,
kind: AddLiquidityKind.UNBALANCED,
userData: ""
})
);
amountsOut[i] = bptAmountOut;
} else if (action.actionType == ActionType.WITHDRAW_SINGLE_TOKEN) {
IERC20[] memory tokens = IVaultExtension(vault).getPoolTokens(pool);
uint256 tokenIndex = _findTokenIndex(tokens, action.tokenOut);
uint256[] memory minAmountsOut = new uint256[](tokens.length);
minAmountsOut[tokenIndex] = 1;
(, uint256[] memory tokensOut,) = IVaultMain(vault).removeLiquidity(
RemoveLiquidityParams({
pool: pool,
from: address(this),
maxBptAmountIn: action.amountIn,
minAmountsOut: minAmountsOut,
kind: RemoveLiquidityKind.SINGLE_TOKEN_EXACT_IN,
userData: ""
})
);
amountsOut[i] = tokensOut[tokenIndex];
}
}
return amountsOut;
}
}
"
},
"lib/@openzeppelin/contracts/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
"
},
"lib/@balancer-labs/balancer-v3/pkg/interfaces/contracts/vault/IVaultMain.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./VaultTypes.sol";
/**
* @notice Interface for functions defined on the main Vault contract.
* @dev These are generally "critical path" functions (swap, add/remove liquidity) that are in the main contract
* for technical or performance reasons.
*/
interface IVaultMain {
/*******************************************************************************
Transient Accounting
*******************************************************************************/
/**
* @notice Creates a context for a sequence of operations (i.e., "unlocks" the Vault).
* @dev Performs a callback on msg.sender with arguments provided in `data`. The Callback is `transient`,
* meaning all balances for the caller have to be settled at the end.
*
* @param data Contains function signature and args to be passed to the msg.sender
* @return result Resulting data from the call
*/
function unlock(bytes calldata data) external returns (bytes memory result);
/**
* @notice Settles deltas for a token; must be successful for the current lock to be released.
* @dev Protects the caller against leftover dust in the Vault for the token being settled. The caller
* should know in advance how many tokens were paid to the Vault, so it can provide it as a hint to discard any
* excess in the Vault balance.
*
* If the given hint is equal to or higher than the difference in reserves, the difference in reserves is given as
* credit to the caller. If it's higher, the caller sent fewer tokens than expected, so settlement would fail.
*
* If the given hint is lower than the difference in reserves, the hint is given as credit to the caller.
* In this case, the excess would be absorbed by the Vault (and reflected correctly in the reserves), but would
* not affect settlement.
*
* The credit supplied by the Vault can be calculated as `min(reserveDifference, amountHint)`, where the reserve
* difference equals current balance of the token minus existing reserves of the token when the function is called.
*
* @param token Address of the token
* @param amountHint Amount paid as reported by the caller
* @return credit Credit received in return of the payment
*/
function settle(IERC20 token, uint256 amountHint) external returns (uint256 credit);
/**
* @notice Sends tokens to a recipient.
* @dev There is no inverse operation for this function. Transfer funds to the Vault and call `settle` to cancel
* debts.
*
* @param token Address of the token
* @param to Recipient address
* @param amount Amount of tokens to send
*/
function sendTo(IERC20 token, address to, uint256 amount) external;
/***************************************************************************
Swaps
***************************************************************************/
/**
* @notice Swaps tokens based on provided parameters.
* @dev All parameters are given in raw token decimal encoding.
* @param vaultSwapParams Parameters for the swap (see above for struct definition)
* @return amountCalculatedRaw Calculated swap amount
* @return amountInRaw Amount of input tokens for the swap
* @return amountOutRaw Amount of output tokens from the swap
*/
function swap(
VaultSwapParams memory vaultSwapParams
) external returns (uint256 amountCalculatedRaw, uint256 amountInRaw, uint256 amountOutRaw);
/***************************************************************************
Add Liquidity
***************************************************************************/
/**
* @notice Adds liquidity to a pool.
* @dev Caution should be exercised when adding liquidity because the Vault has the capability
* to transfer tokens from any user, given that it holds all allowances.
*
* @param params Parameters for the add liquidity (see above for struct definition)
* @return amountsIn Actual amounts of input tokens
* @return bptAmountOut Output pool token amount
* @return returnData Arbitrary (optional) data with an encoded response from the pool
*/
function addLiquidity(
AddLiquidityParams memory params
) external returns (uint256[] memory amountsIn, uint256 bptAmountOut, bytes memory returnData);
/***************************************************************************
Remove Liquidity
***************************************************************************/
/**
* @notice Removes liquidity from a pool.
* @dev Trusted routers can burn pool tokens belonging to any user and require no prior approval from the user.
* Untrusted routers require prior approval from the user. This is the only function allowed to call
* _queryModeBalanceIncrease (and only in a query context).
*
* @param params Parameters for the remove liquidity (see above for struct definition)
* @return bptAmountIn Actual amount of BPT burned
* @return amountsOut Actual amounts of output tokens
* @return returnData Arbitrary (optional) data with an encoded response from the pool
*/
function removeLiquidity(
RemoveLiquidityParams memory params
) external returns (uint256 bptAmountIn, uint256[] memory amountsOut, bytes memory returnData);
/*******************************************************************************
Pool Information
*******************************************************************************/
/**
* @notice Gets the index of a token in a given pool.
* @dev Reverts if the pool is not registered, or if the token does not belong to the pool.
* @param pool Address of the pool
* @param token Address of the token
* @return tokenCount Number of tokens in the pool
* @return index Index corresponding to the given token in the pool's token list
*/
function getPoolTokenCountAndIndexOfToken(
address pool,
IERC20 token
) external view returns (uint256 tokenCount, uint256 index);
/*******************************************************************************
Balancer Pool Tokens
*******************************************************************************/
/**
* @notice Transfers pool token from owner to a recipient.
* @dev Notice that the pool token address is not included in the params. This function is exclusively called by
* the pool contract, so msg.sender is used as the token address.
*
* @param owner Address of the owner
* @param to Address of the recipient
* @param amount Amount of tokens to transfer
* @return success True if successful, false otherwise
*/
function transfer(address owner, address to, uint256 amount) external returns (bool);
/**
* @notice Transfers pool token from a sender to a recipient using an allowance.
* @dev Notice that the pool token address is not included in the params. This function is exclusively called by
* the pool contract, so msg.sender is used as the token address.
*
* @param spender Address allowed to perform the transfer
* @param from Address of the sender
* @param to Address of the recipient
* @param amount Amount of tokens to transfer
* @return success True if successful, false otherwise
*/
function transferFrom(address spender, address from, address to, uint256 amount) external returns (bool success);
/*******************************************************************************
ERC4626 Buffers
*******************************************************************************/
/**
* @notice Wraps/unwraps tokens based on the parameters provided.
* @dev All parameters are given in raw token decimal encoding. It requires the buffer to be initialized,
* and uses the internal wrapped token buffer when it has enough liquidity to avoid external calls.
*
* @param params Parameters for the wrap/unwrap operation (see struct definition)
* @return amountCalculatedRaw Calculated swap amount
* @return amountInRaw Amount of input tokens for the swap
* @return amountOutRaw Amount of output tokens from the swap
*/
function erc4626BufferWrapOrUnwrap(
BufferWrapOrUnwrapParams memory params
) external returns (uint256 amountCalculatedRaw, uint256 amountInRaw, uint256 amountOutRaw);
/*******************************************************************************
Miscellaneous
*******************************************************************************/
/**
* @notice Returns the VaultExtension contract address.
* @dev Function is in the main Vault contract. The VaultExtension handles less critical or frequently used
* functions, since delegate calls through the Vault are more expensive than direct calls.
*
* @return vaultExtension Address of the VaultExtension
*/
function getVaultExtension() external view returns (address vaultExtension);
}
"
},
"lib/@balancer-labs/balancer-v3/pkg/interfaces/contracts/vault/IVaultExtension.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
import { IERC4626 } from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IAuthorizer } from "./IAuthorizer.sol";
import { IProtocolFeeController } from "./IProtocolFeeController.sol";
import { IVault } from "./IVault.sol";
import { IHooks } from "./IHooks.sol";
import "./VaultTypes.sol";
/**
* @notice Interface for functions defined on the `VaultExtension` contract.
* @dev `VaultExtension` handles less critical or frequently used functions, since delegate calls through
* the Vault are more expensive than direct calls. The main Vault contains the core code for swaps and
* liquidity operations.
*/
interface IVaultExtension {
/*******************************************************************************
Constants and immutables
*******************************************************************************/
/**
* @notice Returns the main Vault address.
* @dev The main Vault contains the entrypoint and main liquidity operation implementations.
* @return vault The address of the main Vault
*/
function vault() external view returns (IVault);
/**
* @notice Returns the VaultAdmin contract address.
* @dev The VaultAdmin contract mostly implements permissioned functions.
* @return vaultAdmin The address of the Vault admin
*/
function getVaultAdmin() external view returns (address vaultAdmin);
/*******************************************************************************
Transient Accounting
*******************************************************************************/
/**
* @notice Returns whether the Vault is unlocked (i.e., executing an operation).
* @dev The Vault must be unlocked to perform state-changing liquidity operations.
* @return unlocked True if the Vault is unlocked, false otherwise
*/
function isUnlocked() external view returns (bool unlocked);
/**
* @notice Returns the count of non-zero deltas.
* @return nonzeroDeltaCount The current value of `_nonzeroDeltaCount`
*/
function getNonzeroDeltaCount() external view returns (uint256 nonzeroDeltaCount);
/**
* @notice Retrieves the token delta for a specific token.
* @dev This function allows reading the value from the `_tokenDeltas` mapping.
* @param token The token for which the delta is being fetched
* @return tokenDelta The delta of the specified token
*/
function getTokenDelta(IERC20 token) external view returns (int256 tokenDelta);
/**
* @notice Retrieves the reserve (i.e., total Vault balance) of a given token.
* @param token The token for which to retrieve the reserve
* @return reserveAmount The amount of reserves for the given token
*/
function getReservesOf(IERC20 token) external view returns (uint256 reserveAmount);
/**
* @notice This flag is used to detect and tax "round-trip" interactions (adding and removing liquidity in the
* same pool).
* @dev Taxing remove liquidity proportional whenever liquidity was added in the same `unlock` call adds an extra
* layer of security, discouraging operations that try to undo others for profit. Remove liquidity proportional
* is the only standard way to exit a position without fees, and this flag is used to enable fees in that case.
* It also discourages indirect swaps via unbalanced add and remove proportional, as they are expected to be worse
* than a simple swap for every pool type.
*
* @param pool Address of the pool to check
* @return liquidityAdded True if liquidity has been added to this pool in the current transaction
* Note that there is no `sessionId` argument; it always returns the value for the current (i.e., latest) session.
*/
function getAddLiquidityCalledFlag(address pool) external view returns (bool liquidityAdded);
/*******************************************************************************
Pool Registration
*******************************************************************************/
/**
* @notice Registers a pool, associating it with its factory and the tokens it manages.
* @dev A pool can opt-out of pausing by providing a zero value for the pause window, or allow pausing indefinitely
* by providing a large value. (Pool pause windows are not limited by the Vault maximums.) The vault defines an
* additional buffer period during which a paused pool will stay paused. After the buffer period passes, a paused
* pool will automatically unpause. Balancer timestamps are 32 bits.
*
* A pool can opt out of Balancer governance pausing by providing a custom `pauseManager`. This might be a
* multi-sig contract or an arbitrary smart contract with its own access controls, that forwards calls to
* the Vault.
*
* If the zero address is provided for the `pauseManager`, permissions for pausing the pool will default to the
* authorizer.
*
* @param pool The address of the pool being registered
* @param tokenConfig An array of descriptors for the tokens the pool will manage
* @param swapFeePercentage The initial static swap fee percentage of the pool
* @param pauseWindowEndTime The timestamp after which it is no longer possible to pause the pool
* @param protocolFeeExempt If true, the pool's initial aggregate fees will be set to 0
* @param roleAccounts Addresses the Vault will allow to change certain pool settings
* @param poolHooksContract Contract that implements the hooks for the pool
* @param liquidityManagement Liquidity management flags with implemented methods
*/
function registerPool(
address pool,
TokenConfig[] memory tokenConfig,
uint256 swapFeePercentage,
uint32 pauseWindowEndTime,
bool protocolFeeExempt,
PoolRoleAccounts calldata roleAccounts,
address poolHooksContract,
LiquidityManagement calldata liquidityManagement
) external;
/**
* @notice Checks whether a pool is registered.
* @param pool Address of the pool to check
* @return registered True if the pool is registered, false otherwise
*/
function isPoolRegistered(address pool) external view returns (bool registered);
/**
* @notice Initializes a registered pool by adding liquidity; mints BPT tokens for the first time in exchange.
* @param pool Address of the pool to initialize
* @param to Address that will receive the output BPT
* @param tokens Tokens used to seed the pool (must match the registered tokens)
* @param exactAmountsIn Exact amounts of input tokens
* @param minBptAmountOut Minimum amount of output pool tokens
* @param userData Additional (optional) data required for adding initial liquidity
* @return bptAmountOut Output pool token amount
*/
function initialize(
address pool,
address to,
IERC20[] memory tokens,
uint256[] memory exactAmountsIn,
uint256 minBptAmountOut,
bytes memory userData
) external returns (uint256 bptAmountOut);
/*******************************************************************************
Pool Information
*******************************************************************************/
/**
* @notice Checks whether a pool is initialized.
* @dev An initialized pool can be considered registered as well.
* @param pool Address of the pool to check
* @return initialized True if the pool is initialized, false otherwise
*/
function isPoolInitialized(address pool) external view returns (bool initialized);
/**
* @notice Gets the tokens registered to a pool.
* @param pool Address of the pool
* @return tokens List of tokens in the pool
*/
function getPoolTokens(address pool) external view returns (IERC20[] memory tokens);
/**
* @notice Gets pool token rates.
* @dev This function performs external calls if tokens are yield-bearing. All returned arrays are in token
* registration order.
*
* @param pool Address of the pool
* @return decimalScalingFactors Conversion factor used to adjust for token decimals for uniform precision in
* calculations. FP(1) for 18-decimal tokens
* @return tokenRates 18-decimal FP values for rate tokens (e.g., yield-bearing), or FP(1) for standard tokens
*/
function getPoolTokenRates(
address pool
) external view returns (uint256[] memory decimalScalingFactors, uint256[] memory tokenRates);
/**
* @notice Returns comprehensive pool data for the given pool.
* @dev This contains the pool configuration (flags), tokens and token types, rates, scaling factors, and balances.
* @param pool The address of the pool
* @return poolData The `PoolData` result
*/
function getPoolData(address pool) external view returns (PoolData memory poolData);
/**
* @notice Gets the raw data for a pool: tokens, raw balances, scaling factors.
* @param pool Address of the pool
* @return tokens The pool tokens, sorted in registration order
* @return tokenInfo Token info structs (type, rate provider, yield flag), sorted in token registration order
* @return balancesRaw Current native decimal balances of the pool tokens, sorted in token registration order
* @return lastBalancesLiveScaled18 Last saved live balances, sorted in token registration order
*/
function getPoolTokenInfo(
address pool
)
external
view
returns (
IERC20[] memory tokens,
TokenInfo[] memory tokenInfo,
uint256[] memory balancesRaw,
uint256[] memory lastBalancesLiveScaled18
);
/**
* @notice Gets current live balances of a given pool (fixed-point, 18 decimals), corresponding to its tokens in
* registration order.
*
* @param pool Address of the pool
* @return balancesLiveScaled18 Token balances after paying yield fees, applying decimal scaling and rates
*/
function getCurrentLiveBalances(address pool) external view returns (uint256[] memory balancesLiveScaled18);
/**
* @notice Gets the configuration parameters of a pool.
* @dev The `PoolConfig` contains liquidity management and other state flags, fee percentages, the pause window.
* @param pool Address of the pool
* @return poolConfig The pool configuration as a `PoolConfig` struct
*/
function getPoolConfig(address pool) external view returns (PoolConfig memory poolConfig);
/**
* @notice Gets the hooks configuration parameters of a pool.
* @dev The `HooksConfig` contains flags indicating which pool hooks are implemented.
* @param pool Address of the pool
* @return hooksConfig The hooks configuration as a `HooksConfig` struct
*/
function getHooksConfig(address pool) external view returns (HooksConfig memory hooksConfig);
/**
* @notice The current rate of a pool token (BPT) = invariant / totalSupply.
* @param pool Address of the pool
* @return rate BPT rate
*/
function getBptRate(address pool) external view returns (uint256 rate);
/*******************************************************************************
Balancer Pool Tokens
*******************************************************************************/
/**
* @notice Gets the total supply of a given ERC20 token.
* @param token The token address
* @return tokenTotalSupply Total supply of the token
*/
function totalSupply(address token) external view returns (uint256 tokenTotalSupply);
/**
* @notice Gets the balance of an account for a given ERC20 token.
* @param token Address of the token
* @param account Address of the account
* @return tokenBalance Token balance of the account
*/
function balanceOf(address token, address account) external view returns (uint256 tokenBalance);
/**
* @notice Gets the allowance of a spender for a given ERC20 token and owner.
* @param token Address of the token
* @param owner Address of the owner
* @param spender Address of the spender
* @return tokenAllowance Amount of tokens the spender is allowed to spend
*/
function allowance(address token, address owner, address spender) external view returns (uint256 tokenAllowance);
/**
* @notice Approves a spender to spend pool tokens on behalf of sender.
* @dev Notice that the pool token address is not included in the params. This function is exclusively called by
* the pool contract, so msg.sender is used as the token address.
*
* @param owner Address of the owner
* @param spender Address of the spender
* @param amount Amount of tokens to approve
* @return success True if successful, false otherwise
*/
function approve(address owner, address spender, uint256 amount) external returns (bool success);
/*******************************************************************************
Pool Pausing
*******************************************************************************/
/**
* @notice Indicates whether a pool is paused.
* @dev If a pool is paused, all non-Recovery Mode state-changing operations will revert.
* @param pool The pool to be checked
* @return poolPaused True if the pool is paused
*/
function isPoolPaused(address pool) external view returns (bool poolPaused);
/**
* @notice Returns the paused status, and end times of the Pool's pause window and buffer period.
* @dev Note that even when set to a paused state, the pool will automatically unpause at the end of
* the buffer period. Balancer timestamps are 32 bits.
*
* @param pool The pool whose data is requested
* @return poolPaused True if the Pool is paused
* @return poolPauseWindowEndTime The timestamp of the end of the Pool's pause window
* @return poolBufferPeriodEndTime The timestamp after which the Pool unpauses itself (if paused)
* @return pauseManager The pause manager, or the zero address
*/
function getPoolPausedState(
address pool
)
external
view
returns (bool poolPaused, uint32 poolPauseWindowEndTime, uint32 poolBufferPeriodEndTime, address pauseManager);
/*******************************************************************************
ERC4626 Buffers
*******************************************************************************/
/**
* @notice Checks if the wrapped token has an initialized buffer in the Vault.
* @dev An initialized buffer should have an asset registered in the Vault.
* @param wrappedToken Address of the wrapped token that implements IERC4626
* @return isBufferInitialized True if the ERC4626 buffer is initialized
*/
function isERC4626BufferInitialized(IERC4626 wrappedToken) external view returns (bool isBufferInitialized);
/**
* @notice Gets the registered asset for a given buffer.
* @dev To avoid malicious wrappers (e.g., that might potentially change their asset after deployment), routers
* should never call `wrapper.asset()` directly, at least without checking it against the asset registered with
* the Vault on initialization.
*
* @param wrappedToken The wrapped token specifying the buffer
* @return asset The underlying asset of the wrapped token
*/
function getERC4626BufferAsset(IERC4626 wrappedToken) external view returns (address asset);
/*******************************************************************************
Fees
*******************************************************************************/
/**
* @notice Returns the accumulated swap fees (including aggregate fees) in `token` collected by the pool.
* @param pool The address of the pool for which aggregate fees have been collected
* @param token The address of the token in which fees have been accumulated
* @return swapFeeAmount The total amount of fees accumulated in the specified token
*/
function getAggregateSwapFeeAmount(address pool, IERC20 token) external view returns (uint256 swapFeeAmount);
/**
* @notice Returns the accumulated yield fees (including aggregate fees) in `token` collected by the pool.
* @param pool The address of the pool for which aggregate fees have been collected
* @param token The address of the token in which fees have been accumulated
* @return yieldFeeAmount The total amount of fees accumulated in the specified token
*/
function getAggregateYieldFeeAmount(address pool, IERC20 token) external view returns (uint256 yieldFeeAmount);
/**
* @notice Fetches the static swap fee percentage for a given pool.
* @param pool The address of the pool whose static swap fee percentage is being queried
* @return swapFeePercentage The current static swap fee percentage for the specified pool
*/
function getStaticSwapFeePercentage(address pool) external view returns (uint256 swapFeePercentage);
/**
* @notice Fetches the role accounts for a given pool (pause manager, swap manager, pool creator)
* @param pool The address of the pool whose roles are being queried
* @return roleAccounts A struct containing the role accounts for the pool (or 0 if unassigned)
*/
function getPoolRoleAccounts(address pool) external view returns (PoolRoleAccounts memory roleAccounts);
/**
* @notice Query the current dynamic swap fee percentage of a pool, given a set of swap parameters.
* @dev Reverts if the hook doesn't return the success flag set to `true`.
* @param pool The pool
* @param swapParams The swap parameters used to compute the fee
* @return dynamicSwapFeePercentage The dynamic swap fee percentage
*/
function computeDynamicSwapFeePercentage(
address pool,
PoolSwapParams memory swapParams
) external view returns (uint256 dynamicSwapFeePercentage);
/**
* @notice Returns the Protocol Fee Controller address.
* @return protocolFeeController Address of the ProtocolFeeController
*/
function getProtocolFeeController() external view returns (IProtocolFeeController protocolFeeController);
/*******************************************************************************
Recovery Mode
*******************************************************************************/
/**
* @notice Checks whether a pool is in Recovery Mode.
* @dev Recovery Mode enables a safe proportional withdrawal path, with no external calls.
* @param pool Address of the pool to check
* @return inRecoveryMode True if the pool is in Recovery Mode, false otherwise
*/
function isPoolInRecoveryMode(address pool) external view returns (bool inRecoveryMode);
/**
* @notice Remove liquidity from a pool specifying exact pool tokens in, with proportional token amounts out.
* The request is implemented by the Vault without any interaction with the pool, ensuring that
* it works the same for all pools, and cannot be disabled by a new pool type.
*
* @param pool Address of the pool
* @param from Address of user to burn pool tokens from
* @param exactBptAmountIn Input pool token amount
* @param minAmountsOut Minimum amounts of tokens to be received, sorted in token registration order
* @return amountsOut Actual calculated amounts of output tokens, sorted in token registration order
*/
function removeLiquidityRecovery(
address pool,
address from,
uint256 exactBptAmountIn,
uint256[] memory minAmountsOut
) external returns (uint256[] memory amountsOut);
/*******************************************************************************
Queries
*******************************************************************************/
/**
* @notice Performs a callback on msg.sender with arguments provided in `data`.
* @dev Used to query a set of operations on the Vault. Only off-chain eth_call are allowed,
* anything else will revert.
*
* Allows querying any operation on the Vault that has the `onlyWhenUnlocked` modifier.
*
* Allows the external calling of a function via the Vault contract to
* access Vault's functions guarded by `onlyWhenUnlocked`.
* `transient` modifier ensuring balances changes within the Vault are settled.
*
* @param data Contains function signature and args to be passed to the msg.sender
* @return result Resulting data from the call
*/
function quote(bytes calldata data) external returns (bytes memory result);
/**
* @notice Performs a callback on msg.sender with arguments provided in `data`.
* @dev Used to query a set of operations on the Vault. Only off-chain eth_call are allowed,
* anything else will revert.
*
* Allows querying any operation on the Vault that has the `onlyWhenUnlocked` modifier.
*
* Allows the external calling of a function via the Vault contract to
* access Vault's functions guarded by `onlyWhenUnlocked`.
* `transient` modifier ensuring balances changes within the Vault are settled.
*
* This call always reverts, returning the result in the revert reason.
*
* @param data Contains function signature and args to be passed to the msg.sender
*/
function quoteAndRevert(bytes calldata data) external;
/**
* @notice Returns true if queries are disabled on the Vault.
* @dev If true, queries might either be disabled temporarily or permanently.
* @return queryDisabled True if query functionality is reversibly disabled
*/
function isQueryDisabled() external view returns (bool queryDisabled);
/**
* @notice Returns true if queries are disabled permanently; false if they are enabled.
* @dev This is a one-way switch. Once queries are disabled permanently, they can never be re-enabled.
* @return queryDisabledPermanently True if query functionality is permanently disabled
*/
function isQueryDisabledPermanently() external view returns (bool queryDisabledPermanently);
/**
* @notice Pools can use this event to emit event data from the Vault.
* @param eventKey Event key
* @param eventData Encoded event data
*/
function emitAuxiliaryEvent(bytes32 eventKey, bytes calldata eventData) external;
/*******************************************************************************
Authentication
*******************************************************************************/
/**
* @notice Returns the Authorizer address.
* @dev The authorizer holds the permissions granted by governance. It is set on Vault deployment,
* and can be changed through a permissioned call.
*
* @return authorizer Address of the authorizer contract
*/
function getAuthorizer() external view returns (IAuthorizer authorizer);
}
"
},
"lib/@balancer-labs/balancer-v3/pkg/solidity-utils/contracts/helpers/RevertCodec.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
// solhint-disable no-inline-assembly
/// @notice Support `quoteAndRevert`: a v2-style query which always reverts, and returns the result in the return data.
library RevertCodec {
/**
* @notice On success of the primary operation in a `quoteAndRevert`, this error is thrown with the return data.
* @param result The result of the query operation
*/
error Result(bytes result);
/// @notice Handle the "reverted without a reason" case (i.e., no return data).
error ErrorSelectorNotFound();
function catchEncodedResult(bytes memory resultRaw) internal pure returns (bytes memory) {
bytes4 errorSelector = RevertCodec.parseSelector(resultRaw);
if (errorSelector != Result.selector) {
// Bubble up error message if the revert reason is not the expected one.
RevertCodec.bubbleUpRevert(resultRaw);
}
uint256 resultRawLength = resultRaw.length;
assembly ("memory-safe") {
resultRaw := add(resultRaw, 0x04) // Slice the sighash
mstore(resultRaw, sub(resultRawLength, 4)) // Set proper length
}
return abi.decode(resultRaw, (bytes));
}
/// @dev Returns the first 4 bytes in an array, reverting if the length is < 4.
function parseSelector(bytes memory callResult) internal pure returns (bytes4 errorSelector) {
if (callResult.length < 4) {
revert ErrorSelectorNotFound();
}
assembly ("memory-safe") {
errorSelector := mload(add(callResult, 0x20)) // Load the first 4 bytes from data (skip length offset)
}
}
/// @dev Taken from Openzeppelin's Address.
function bubbleUpRevert(bytes memory returnData) internal pure {
// Look for revert reason and bubble it up if present.
if (returnData.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly.
assembly ("memory-safe") {
let return_data_size := mload(returnData)
revert(add(32, returnData), return_data_size)
}
} else {
revert ErrorSelectorNotFound();
}
}
}
"
},
"lib/@balancer-labs/balancer-v3/pkg/interfaces/contracts/vault/VaultTypes.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IERC4626 } from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import { IRateProvider } from "../solidity-utils/helpers/IRateProvider.sol";
/**
* @notice Represents a pool's liquidity management configuration.
* @param disableUnbalancedLiquidity If set, liquidity can only be added or removed proportionally
* @param enableAddLiquidityCustom If set, the pool has implemented `onAddLiquidityCustom`
* @param enableRemoveLiquidityCustom If set, the pool has implemented `onRemoveLiquidityCustom`
* @param enableDonation If set, the pool will not revert if liquidity is added with AddLiquidityKind.DONATION
*/
struct LiquidityManagement {
bool disableUnbalancedLiquidity;
bool enableAddLiquidityCustom;
bool enableRemoveLiquidityCustom;
bool enableDonation;
}
// @notice Custom type to store the entire configuration of the pool.
type PoolConfigBits is bytes32;
/**
* @notice Represents a pool's configuration (hooks configuration are separated in another struct).
* @param liquidityManagement Flags related to adding/removing liquidity
* @param staticSwapFeePercentage The pool's native swap fee
* @param aggregateSwapFeePercentage The total swap fee charged, including protocol and pool creator components
* @param aggregateYieldFeePercentage The total swap fee charged, including protocol and pool creator components
* @param tokenDecimalDiffs Compressed storage of the token decimals of each pool token
* @param pauseWindowEndTime Timestamp after which the pool cannot be paused
* @param isPoolRegistered If true, the pool has been registered with the Vault
* @param isPoolInitialized If true, the pool has been initialized with liquidity, and is available for trading
* @param isPoolPaused If true, the pool has been paused (by governance or the pauseManager)
* @param isPoolInRecoveryMode If true, the pool has been placed in recovery mode, enabling recovery mode withdrawals
*/
struct PoolConfig {
LiquidityManagement liquidityManagement;
uint256 staticSwapFeePercentage;
uint256 aggregateSwapFeePercentage;
uint256 aggregateYieldFeePercentage;
uint40 tokenDecimalDiffs;
uint32 pauseWindowEndTime;
bool isPoolRegistered;
bool isPoolInitialized;
bool isPoolPaused;
bool isPoolInRecoveryMode;
}
/**
* @notice The flag portion of the `HooksConfig`.
* @dev `enableHookAdjustedAmounts` must be true for all contracts that modify the `amountCalculated`
* in after hooks. Otherwise, the Vault will ignore any "hookAdjusted" amounts. Setting any "shouldCall"
* flags to true will cause the Vault to call the corresponding hook during operations.
*/
struct HookFlags {
bool enableHookAdjustedAmounts;
bool shouldCallBeforeInitialize;
bool shouldCallAfterInitialize;
bool shouldCallComputeDynamicSwapFee;
bool shouldCallBeforeSwap;
bool shouldCallAfterSwap;
bool shouldCallBeforeAddLiquidity;
bool shouldCallAfterAddLiquidity;
bool shouldCallBeforeRemoveLiquidity;
bool shouldCallAfterRemoveLiquidity;
}
/// @notice Represents a hook contract configuration for a pool (HookFlags + hooksContract address).
struct HooksConfig {
bool enableHookAdjustedAmounts;
bool shouldCallBeforeInitialize;
bool shouldCallAfterInitialize;
bool shouldCallComputeDynamicSwapFee;
bool shouldCallBeforeSwap;
bool shouldCallAfterSwap;
bool shouldCallBeforeAddLiquidity;
bool shouldCallAfterAddLiquidity;
bool shouldCallBeforeRemoveLiquidity;
bool shouldCallAfterRemoveLiquidity;
address hooksContract;
}
/**
* @notice Represents temporary state used during a swap operation.
* @param indexIn The zero-based index of tokenIn
* @param indexOut The zero-based index of tokenOut
* @param amountGivenScaled18 The amountGiven (i.e., tokenIn for ExactIn), adjusted for token decimals
* @param swapFeePercentage The swap fee to be applied (might be static or dynamic)
*/
struct SwapState {
uint256 indexIn;
uint256 indexOut;
uint256 amountGivenScaled18;
uint256 swapFeePercentage;
}
/**
* @notice Represents the Vault's configuration.
* @param isQueryDisabled If set to true, disables query functionality of the Vault. Can be modified by governance
* @param isVaultPaused If set to true, swaps and add/remove liquidity operations are halted
* @param areBuffersPaused If set to true, the Vault wrap/unwrap primitives associated with buffers will be disabled
*/
struct VaultState {
bool isQueryDisabled;
bool isVaultPaused;
bool areBuffersPaused;
}
/**
* @notice Represents the accounts holding certain roles for a given pool. This is passed in on pool registration.
* @param pauseManager Account empowered to pause/unpause the pool (note that governance can always pause a pool)
* @param swapFeeManager Account empowered to set static swap fees for a pool (or 0 to delegate to governance)
* @param poolCreator Account empowered to set the pool creator fee (or 0 if all fees go to the protocol and LPs)
*/
struct PoolRoleAccounts {
address pauseManager;
address swapFeeManager;
address poolCreator;
}
/*******************************************************************************
Tokens
*******************************************************************************/
// Note that the following tokens are unsupported by the Vault. This list is not meant to be exhaustive, but covers
// many common types of tokens that will not work with the Vault architecture. (See https://github.com/d-xo/weird-erc20
// for examples of token features that are problematic for many protocols.)
//
// * Rebasing tokens (e.g., aDAI). The Vault keeps track of token balances in its internal accounting; any token whose
// balance changes asynchronously (i.e., outside a swap or liquidity operation), would get out-of-sync with this
// internal accounting. This category would also include "airdrop" tokens, whose balances can change unexpectedly.
//
// * Double entrypoint (e.g., old Synthetix tokens, now fixed). These could likewise bypass internal accounting by
// registering the token under one address, then accessing it through another. This is especially troublesome
// in v3, with the introduction of ERC4626 buffers.
//
// * Fee on transfer (e.g., PAXG). The Vault issues credits and debits according to given and calculated token amounts,
// and settlement assumes that the send/receive transfer functions transfer exactly the given number of tokens.
// If this is not the case, transactions will not settle. Unlike with the other types, which are fundamentally
// incompatible, it would be possible to design a Router to handle this - but we didn't try it. In any case, it's
// not supported in the current Routers.
//
// * Tokens with more than 18 decimals (e.g., YAM-V2). The Vault handles token scaling: i.e., handling I/O for
// amounts in native token decimals, but doing calculations with full 18-decimal precision. This requires reading
// and storing the decimals for each token. Since virtually all tokens are 18 or fewer decimals, and we have limited
// storage space, 18 was a reasonable maximum. Unlike the other types, this is enforceable by the Vault. Attempting
// to register such tokens will revert with `InvalidTokenDecimals`. Of course, we must also be able to read the token
// decimals, so the Vault only supports tokens that implement `IERC20Metadata.decimals`, and return a value less than
// or equal to 18.
//
// * Token decimals are checked and stored only once, on registration. Valid tokens store their decimals as immutable
// variables or constants. Malicious tokens that don't respect this basic property would not work anywhere in DeFi.
//
// These types of tokens are supported but discouraged, as they don't tend to play well with AMMs generally.
//
// * Very low-decimal tokens (e.g., GUSD). The Vault has been extensively tested with 6-decimal tokens (e.g., USDC),
// but going much below that may lead to unanticipated effects due to precision loss, especially with smaller trade
// values.
//
// * Revert on zero value approval/transfer. The Vault has been tested against these, but peripheral contracts, such
// as hooks, might not have been designed with this in mind.
//
// * Other types from "weird-erc20," such as upgradeable, pausable, or tokens with blocklists. We have seen cases
// where a token upgrade fails, "bricking" the token - and many operations on pools containing that token. Any
// sort of "permissioned" token that can make transfers fail can cause operations on pools containing them to
// revert. Even Recovery Mode cannot help then, as it does a proportional withdrawal of all tokens. If one of
// them is bricked, the whole operation will revert. Since v3 does not have "internal balances" like v2, there
// is no recourse.
//
// Of course, many tokens in common use have some of these "features" (especially centralized stable coins), so
// we have to support them anyway. Working with common centralized tokens is a risk common to all of DeFi.
/**
* @notice Token types supported by the Vault.
* @dev In general, pools may contain any combination of these tokens.
*
* STANDARD tokens (e.g., BAL, WETH) have no rate provider.
* WITH_RATE tokens (e.g., wstETH) require a rate provider. These may be tokens like wstETH, which need to be wrapped
* because the underlying stETH token is rebasing, and such tokens are unsupported by the Vault. They may also be
* tokens like sEUR, which track an underlying asset, but are not yield-bearing. Finally, this encompasses
* yield-bearing ERC4626 tokens, which can be used to facilitate swaps without requiring wrapping or unwrapping
* in most cases. The `paysYieldFees` flag can be used to indicate whether a token is yield-bearing (e.g., waDAI),
* not yield-bearing (e.g., sEUR), or yield-bearing but exempt from fees (e.g., in certain nested pools, where
* yield fees are charged elsewhere).
*
* NB: STANDARD must always be the first enum element, so that newly initialized data structures default to Standard.
*/
enum TokenType {
STANDARD,
WITH_RATE
}
/**
* @notice Encapsulate the data required for the Vault to support a token of the given type.
* @dev For STANDARD tokens, the rate provider address must be 0, and paysYieldFees must be false. All WITH_RATE tokens
* need a rate provider, and may or may not be yield-bearing.
*
* At registration time, it is useful to include the token address along with the token parameters in the structure
* passed to `registerPool`, as the alternative would be parallel arrays, which would be error prone and require
* validation checks. `TokenConfig` is only used for registration, and is never put into storage (see `TokenInfo`).
*
* @param token The token address
* @param tokenType The token type (see the enum for supported types)
* @param rateProvider The rate provider for a token (see further documentation above)
* @param paysYieldFees Flag indicating whether yield fees should be charged on this token
*/
struct TokenConfig {
IERC20 token;
TokenType tokenType;
IRateProvider rateProvider;
bool paysYieldFees;
}
/**
* @notice This data structure is stored in `_poolTokenInfo`, a nested mapping from pool -> (token -> TokenInfo).
* @dev Since the token is already the key of the nested mapping, it would be redundant (and an extra SLOAD) to store
* it again in the struct. When we construct PoolData, the tokens are separated into their own array.
*
* @param tokenType The token type (see the enum for supported types)
* @param rateProvider The rate provider for a token (see further documentation above)
* @param paysYieldFees Flag indicating whether yield fees should be charged on this token
*/
struct TokenInfo {
TokenType tokenType;
IRateProvider rateProvider;
bool paysYieldFees;
}
/**
* @notice Data structure used to represent the current pool state in memory
* @param poolConfigBits Custom type to store the entire configuration of the pool.
* @param tokens Pool tokens, sorted in token registration order
* @param tokenInfo Configuration data for each token, sorted in token registration order
* @param balancesRaw Token balances in native decimals
* @param balancesLiveScaled18 Token balances after paying yield fees, applying decimal scaling and rates
* @param tokenRates 18-decimal FP values for rate tokens (e.g., yield-bearing), or FP(1) for standard tokens
* @param decimalScalingFactors Conversion factor used to adjust for token decimals for uniform precision in
* calculations. It is 1e18 (FP 1) for 18-decimal tokens
*/
struct PoolData {
PoolConfigBits poolConfigBits;
IERC20[] tokens;
TokenInfo[] tokenInfo;
uint256[] balancesRaw;
uint256[] balancesLiveScaled18;
uint256[] tokenRates;
uint256[] decimalScalingFactors;
}
enum Rounding {
ROUND_UP,
ROUND_DOWN
}
/*******************************************************************************
Swaps
*******************************************************************************/
enum SwapKind {
EXACT_IN,
EXACT_OUT
}
// There are two "SwapParams" structs defined below. `VaultSwapParams` corresponds to the external swap API defined
// in the Router contracts, which uses explicit token addresses, the amount given and limit on the calculated amount
// expressed in native token decimals, and optional user data passed in from the caller.
//
// `PoolSwapParams` passes some of this information through (kind, userData), but "translates" the parameters to fit
// the internal swap API used by `IBasePool`. It scales amounts to full 18-decimal precision, adds the token balances,
// converts the raw token addresses to indices, and adds the address of the Router originating the request. It does
// not need the limit, since this is checked at the Router level.
/**
* @notice Data passed into primary Vault `swap` operations.
* @param kind Type of swap (Exact In or Exact Out)
* @param pool The pool with the tokens being swapped
* @param tokenIn The token entering the Vault (balance increases)
* @param tokenOut The token leaving the Vault (balance decreases)
* @param amountGivenRaw Amount specified for tokenIn or tokenOut (depending on the type of swap)
* @param limitRaw Minimum or maximum value of the calculated amount (depending on the type of swap)
* @param userData Additional (optional) user data
*/
struct VaultSwapParams {
SwapKind kind;
address pool;
IERC20 tokenIn;
IERC20 tokenOut;
uint256 amountGivenRaw;
uint256 limitRaw;
bytes userData;
}
/**
* @notice Data for a swap operation, used by contracts implementing `IBasePool`.
* @param kind Type of swap (exact in or exact out)
* @param amountGivenScaled18 Amount given based on kind of the swap (e.g., tokenIn for EXACT_IN)
* @param balancesScaled18 Current pool balances
* @param indexIn Index of tokenIn
* @param indexOut Index of tokenOut
* @param router The address (usually a router contract) that initiated a swap operation on the Vault
* @param userData Additional (optional) data required for the swap
*/
struct PoolSwapParams {
SwapKind kind;
uint256 amountGivenScaled18;
uint256[] balancesScaled18;
uint256 indexIn;
uint256 indexOut;
address router;
bytes userData;
}
/**
* @notice Data for the hook after a swap operation.
* @param kind Type of swap (exact in or exact out)
* @param tokenIn Token to be swapped from
* @param tokenOut Token to be swapped to
* @param amountInScaled18 Amount of tokenIn (entering the Vault)
* @param amountOutScaled18 Amount of tokenOut (leaving the Vault)
* @param tokenInBalanceScaled18 Updated (after swap) balance of tokenIn
* @param tokenOutBalanceScaled18 Updated (after swap) balance of tokenOut
* @param amountCalculatedScaled18 Token amount calculated by the swap
* @param amountCalculatedRaw Token amount calculated by the swap
* @param router The address (usually a router contract) that initiated a swap operation on the Vault
* @param pool Pool address
* @param userData Additional (optional) data required for the swap
*/
struct AfterSwapParams {
SwapKind kind;
IERC20 tokenIn;
IERC20 tokenOut;
uint256 amountInScaled18;
uint256 amountOutScaled18;
uint256 tokenInBalanceScaled18;
uint256 tokenOutBalanceScaled18;
uint256 amountCalculatedScaled18;
uint256 amountCalculatedRaw;
address router;
address pool;
bytes userData;
}
/*******************************************************************************
Add liquidity
*******************************************************************************/
enum AddLiquidityKind {
PROPORTIONAL,
UNBALANCED,
SINGLE_TOKEN_EXACT_OUT,
DONATION,
CUSTOM
}
/**
* @notice Data for an add liquidity operation.
* @param pool Address of the pool
* @param to Address of user to mint to
* @param maxAmountsIn Maximum amounts of input tokens
* @param minBptAmountOut Minimum amount of output pool tokens
* @param kind Add liquidity kind
* @param userData Optional user data
*/
struct AddLiquidityParams {
address pool;
address to;
uint256[] maxAmountsIn;
uint256 minBptAmountOut;
AddLiquidityKind kind;
bytes userData;
}
/*******************************************************************************
Remove liquidity
*******************************************************************************/
enum RemoveLiquidityKind {
PROPORTIONAL,
SINGLE_TOKEN_EXACT_IN,
SINGLE_TOKEN_EXACT_OUT,
CUSTOM
}
/**
* @notice Data for an remove liquidity operation.
* @param pool Address of the pool
* @param from Address of user to burn from
* @param maxBptAmountIn Maximum amount of input pool tokens
* @param minAmountsOut Minimum amounts of output tokens
* @param kind Remove liquidity kind
* @param userData Optional user data
*/
struct RemoveLiquidityParams {
address pool;
address from;
uint256 maxBptAmountIn;
uint256[] minAmountsOut;
RemoveLiquidityKind kind;
bytes userData;
}
/*******************************************************************************
Remove liquidity
*******************************************************************************/
enum WrappingDirection {
WRAP,
UNWRAP
}
/**
* @notice Data for a wrap/unwrap operation.
* @param kind Type of swap (Exact In or Exact Out)
* @param direction Direction of the wrapping operation (Wrap or Unwrap)
* @param wrappedToken Wrapped token, compatible with interface ERC4626
* @param amountGivenRaw Amount specified for tokenIn or tokenOut (depends on the type of swap and wrapping direction)
* @param limitRaw Minimum or maximum amount specified for the other token (depends on the type of swap and wrapping
* direction)
*/
struct BufferWrapOrUnwrapParams {
SwapKind kind;
WrappingDirection direction;
IERC4626 wrappedToken;
uint256 amountGivenRaw;
uint256 limitRaw;
}
// Protocol Fees are 24-bit values. We transform them by multiplying by 1e11, so that they can be set to any value
// between 0% and 100% (step 0.00001%). Protocol and pool creator fees are set in the `ProtocolFeeController`, and
// ensure both constituent and aggregate fees do not exceed this precision.
uint256 constant FEE_BITLENGTH = 24;
uint256 constant FEE_SCALING_FACTOR = 1e11;
// Used to ensure the safety of fee-related math (e.g., pools or hooks don't set it greater than 100%).
// This value should work for practical purposes and is well within the max precision requirements.
uint256 constant MAX_FEE_PERCENTAGE = 99.9999e16; // 99.9999%
"
},
"src/interfaces/IBalancerV3M
Submitted on: 2025-10-27 13:14:55
Comments
Log in to comment.
No comments yet.