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": {
"@balancer-labs/v3-interfaces/contracts/solidity-utils/helpers/IAuthentication.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
/// @notice Simple interface for permissioned calling of external functions.
interface IAuthentication {
/// @notice The sender does not have permission to call a function.
error SenderNotAllowed();
/**
* @notice Returns the action identifier associated with the external function described by `selector`.
* @param selector The 4-byte selector of the permissioned function
* @return actionId The computed actionId
*/
function getActionId(bytes4 selector) external view returns (bytes32 actionId);
}
"
},
"@balancer-labs/v3-interfaces/contracts/solidity-utils/helpers/IRateProvider.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
/// @notice General interface for token exchange rates.
interface IRateProvider {
/**
* @notice An 18 decimal fixed point number representing the exchange rate of one token to another related token.
* @dev The meaning of this rate depends on the context. Note that there may be an error associated with a token
* rate, and the caller might require a certain rounding direction to ensure correctness. This (legacy) interface
* does not take a rounding direction or return an error, so great care must be taken when interpreting and using
* rates in downstream computations.
*
* @return rate The current token rate
*/
function getRate() external view returns (uint256 rate);
}
"
},
"@balancer-labs/v3-interfaces/contracts/standalone-utils/IPoolHelperCommon.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
/// @notice Common interface for helper functions that operate on a subset of pools.
interface IPoolHelperCommon {
/**
* @notice The owner created a new pool set.
* @dev Pools are organized into separate sets, controlled by a manager, which can be changed independently.
* @param poolSetId Id of the set with which the pool is associated
* @param initialManager Address of the pool set manager
*/
event PoolSetCreated(uint256 indexed poolSetId, address indexed initialManager);
/**
* @notice The owner destroyed a pool set.
* @param poolSetId Id of the set with which the pool is associated
* @param manager The address of the set's last manager
*/
event PoolSetDestroyed(uint256 indexed poolSetId, address indexed manager);
/**
* @notice The owner added a pool to the given set.
* @param pool Address of the pool that was added
* @param poolSetId Id of the set with which the pool is associated
*/
event PoolAddedToSet(address indexed pool, uint256 indexed poolSetId);
/**
* @notice The owner removed a pool from the given set.
* @param poolSetId Id of the set with which the pool is associated
* @param pool Address of the pool that was removed
*/
event PoolRemovedFromSet(address indexed pool, uint256 indexed poolSetId);
/**
* @notice The current manager of a pool set transferred ownership to a new address.
* @dev Managers can only control one pool set. Transfers to existing managers of other sets will revert.
* @param poolSetId Id of the set with which the pool is associated
* @param oldManager Address of the previous manager
* @param newManager Address of the new manager
*/
event PoolSetOwnershipTransferred(
uint256 indexed poolSetId,
address indexed oldManager,
address indexed newManager
);
/**
* @notice Cannot add a pool that is already there.
* @param pool Address of the pool being added
* @param poolSetId Id of the set with which the pool is associated
*/
error PoolAlreadyInSet(address pool, uint256 poolSetId);
/**
* @notice Cannot remove a pool that was not added.
* @param pool Address of the pool being removed
* @param poolSetId Id of the set with which the pool is associated
*/
error PoolNotInSet(address pool, uint256 poolSetId);
/**
* @notice Pool set id associated with an operation is invalid.
* @dev This can mean the value is invalid, or it was never created, or it was destroyed.
* @param poolSetId The id of the invalid set
*/
error InvalidPoolSetId(uint256 poolSetId);
/// @notice The initial manager of a pool set cannot be zero.
error InvalidPoolSetManager();
/**
* @notice Pool set managers can only manage a single pool set.
* @dev Otherwise, the contract would not be able to determine the correct pool set from the caller's address.
* @param poolSetManager Address of the manager that is already assigned to another pool set id
*/
error PoolSetManagerNotUnique(address poolSetManager);
/// @notice Permissioned operations on pools can only be performed by the pool set manager.
error SenderIsNotPoolSetManager();
/**
* @notice An index is beyond the current bounds of the set.
* @param poolSetId Id of the set involved in the operation
*/
error IndexOutOfBounds(uint256 poolSetId);
/***************************************************************************
Manage Pool Sets
***************************************************************************/
/**
* @notice Create a new set with an initial manager, optionally initialized with a set of pools.
* @dev The `newPools` list can be empty, in which case this will only create the set. Pools can then be
* added with `addPoolsToSet`, or removed with `removePoolsFromSet`. This is a permissioned function.
* Only the current owner of the helper contract (e.g., Maxis) may create new sets. Also reverts if the
* initial manager address is zero or already a manager of another pool set.
*
* @param initialManager Address of the account authorized to perform operations on the set
* @param newPools Set of pools to add to the set
*/
function createPoolSet(address initialManager, address[] memory newPools) external returns (uint256 poolSetId);
/**
* @notice Create a new empty set with an initial manager.
* @dev Convenience function to create a pool set with no initial pools. Also reverts if the initial manager
* address is zero or already a manager of another pool set.
*
* @param initialManager Address of the account authorized to perform operations on the set
*/
function createPoolSet(address initialManager) external returns (uint256 poolSetId);
/**
* @notice Simple way to remove an entire set of pools from control of the helper function.
* @dev This is a permissioned function. Only the current owner of the helper contract (e.g., Maxis)
* may destroy sets, effectively removing control of any pools in the set from the associated manager.
* Also reverts if the poolSetId is not valid.
*
* @param poolSetId Id of the set being destroyed
*/
function destroyPoolSet(uint256 poolSetId) external;
/**
* @notice Transfer ownership of a pool set from the current manager to a new manager.
* @dev This is a permissioned function. Only the current manager of a set can call this to set a new manager.
* Since managers can only control a single set, there is no need to specify the id in the call. Note that this
* is a one-step migration. If it is done incorrectly, effective control of the set is lost, and the owner of this
* contract will need to destroy the old set and create a new one with the correct initial manager. Also reverts
* if the new manager address is zero or already the manager of a pool set.
*
* @param newManager The address of the new manager
*/
function transferPoolSetOwnership(address newManager) external;
/***************************************************************************
Manage Pools
***************************************************************************/
/**
* @notice Add pools to the set of pools controlled by this helper contract.
* @dev This is a permissioned function. Only the current owner of the helper contract (e.g., Maxis)
* may add pools to a set. Also reverts if the poolSetId is not valid.
*
* @param newPools List of pools to add
* @param poolSetId Id of the set to which the new pools belong
*/
function addPoolsToSet(uint256 poolSetId, address[] memory newPools) external;
/**
* @notice Remove pools from the set of pools controlled by this helper contract.
* @dev This is a permissioned function. Only the current owner of the helper contract (e.g., Maxis)
* may remove pools from a set. Also reverts if the poolSetId is not valid.
*
* @param pools List of pools to remove from the set
* @param poolSetId Id of the set to which the pools belong
*/
function removePoolsFromSet(uint256 poolSetId, address[] memory pools) external;
/***************************************************************************
Getters
***************************************************************************/
/**
* @notice Get the pool set id associated with the caller.
* @return poolSetId The numeric pool set id, or zero if the caller is not a pool set manager
*/
function getPoolSetIdForCaller() external view returns (uint256 poolSetId);
/**
* @notice Get the pool set id associated with a given manager address.
* @return poolSetId The numeric pool set id, or zero if the address given is not a pool set manager
*/
function getPoolSetIdForManager(address manager) external view returns (uint256 poolSetId);
/**
* @notice Get the number of pools associated with the given set.
* @dev Needed to support pagination in case the set is too large to process in a single transaction.
* Reverts if the poolSetId is not valid.
*
* @param poolSetId Id of the set containing the pools
* @return poolCount The current number of pools in the set
*/
function getPoolCountForSet(uint256 poolSetId) external view returns (uint256 poolCount);
/**
* @notice Check whether a poolSetId has been created.
* @param poolSetId Id of the set containing the pools
* @return isValid True if the poolSetId exists
*/
function isValidPoolSetId(uint256 poolSetId) external view returns (bool isValid);
/**
* @notice Check whether a pool is in the set of pools.
* @dev Reverts if the poolSetId is not valid.
* @param pool Address of the pool to check
* @param poolSetId Id of the set containing the pools
* @return poolInSet True if the pool is in the given set, false otherwise
*/
function isPoolInSet(address pool, uint256 poolSetId) external view returns (bool poolInSet);
/**
* @notice Get the full set of pools from a given set.
* @dev Reverts if the poolSetId is not valid.
* @param poolSetId Id of the set containing the pools
* @return pools List of pools
*/
function getAllPoolsInSet(uint256 poolSetId) external view returns (address[] memory pools);
/**
* @notice Get a range of pools from a given set.
* @dev Indexes are 0-based and [start, end) (i.e., inclusive of `start`; exclusive of `end`).
* Reverts if the poolSetId is not valid.
*
* @param poolSetId Id of the set containing the pools
* @param from Start index
* @param to End index
* @return pools List of pools
*/
function getPoolsInSet(uint256 poolSetId, uint256 from, uint256 to) external view returns (address[] memory pools);
/**
* @notice Utility function to predict the next pool set id.
* @return nextPoolSetId The pool set id that will be used on the next call of `createPoolSet`
*/
function getNextPoolSetId() external view returns (uint256 nextPoolSetId);
/**
* @notice Get the manager address associated with a given poolSetId.
* @param poolSetId Id of the set containing the pools
* @return manager The address of the manager of the given poolSetId, or zero if the poolSetId is unassigned
*/
function getManagerForPoolSet(uint256 poolSetId) external view returns (address manager);
}
"
},
"@balancer-labs/v3-interfaces/contracts/standalone-utils/IPoolPauseHelper.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
/**
* @notice Maintain a set of pools that can be paused from this helper contract, vs. directly from the Vault.
* @dev Governance can add a set of pools to this contract, then grant pause permission to accounts here, which
* allows greater granularity than setting the permission directly on the Vault.
*
* Note that governance must grant this contract permission to pause pools from the Vault. Unpausing is not
* addressed here, and must still be done through the Vault.
*/
interface IPoolPauseHelper {
/**
* @notice Pause a set of pools.
* @dev This is a permissioned function. Governance must first grant this contract permission to call `pausePool`
* on the Vault, then grant another account permission to call `pausePools` here. Note that this is not necessarily
* the same account that can add or remove pools from the pausable list.
*
* Note that there is no `unpause`. This is a helper contract designed to react quickly to emergencies. Unpausing
* is a more deliberate action that should be performed by accounts approved by governance for this purpose, or by
* the individual pools' pause managers.
*
* @param pools List of pools to pause
*/
function pausePools(address[] memory pools) external;
}
"
},
"@balancer-labs/v3-interfaces/contracts/vault/IAuthorizer.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
/// @notice Interface to the Vault's permission system.
interface IAuthorizer {
/**
* @notice Returns true if `account` can perform the action described by `actionId` in the contract `where`.
* @param actionId Identifier for the action to be performed
* @param account Account trying to perform the action
* @param where Target contract for the action
* @return success True if the action is permitted
*/
function canPerform(bytes32 actionId, address account, address where) external view returns (bool success);
}
"
},
"@balancer-labs/v3-interfaces/contracts/vault/IHooks.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
// Explicitly import VaultTypes structs because we expect this interface to be heavily used by external developers.
// Internally, when this list gets too long, we usually just do a simple import to keep things tidy.
import {
TokenConfig,
LiquidityManagement,
PoolSwapParams,
AfterSwapParams,
HookFlags,
AddLiquidityKind,
RemoveLiquidityKind,
SwapKind
} from "./VaultTypes.sol";
/**
* @notice Interface for pool hooks.
* @dev Hooks are functions invoked by the Vault at specific points in the flow of each operation. This guarantees that
* they are called in the correct order, and with the correct arguments. To maintain this security, these functions
* should only be called by the Vault. The recommended way to do this is to derive the hook contract from `BaseHooks`,
* then use the `onlyVault` modifier from `VaultGuard`. (See the examples in /pool-hooks.)
*/
interface IHooks {
/***************************************************************************
Register
***************************************************************************/
/**
* @notice Hook executed when a pool is registered with a non-zero hooks contract.
* @dev Returns true if registration was successful, and false to revert the pool registration.
* Make sure this function is properly implemented (e.g. check the factory, and check that the
* given pool is from the factory). The Vault address will be msg.sender.
*
* @param factory Address of the pool factory (contract deploying the pool)
* @param pool Address of the pool
* @param tokenConfig An array of descriptors for the tokens the pool will manage
* @param liquidityManagement Liquidity management flags indicating which functions are enabled
* @return success True if the hook allowed the registration, false otherwise
*/
function onRegister(
address factory,
address pool,
TokenConfig[] memory tokenConfig,
LiquidityManagement calldata liquidityManagement
) external returns (bool success);
/**
* @notice Return the set of hooks implemented by the contract.
* @dev The Vault will only call hooks the pool says it supports, and of course only if a hooks contract is defined
* (i.e., the `poolHooksContract` in `PoolRegistrationParams` is non-zero).
* `onRegister` is the only "mandatory" hook.
*
* @return hookFlags Flags indicating which hooks the contract supports
*/
function getHookFlags() external view returns (HookFlags memory hookFlags);
/***************************************************************************
Initialize
***************************************************************************/
/**
* @notice Hook executed before pool initialization.
* @dev Called if the `shouldCallBeforeInitialize` flag is set in the configuration. Hook contracts should use
* the `onlyVault` modifier to guarantee this is only called by the Vault.
*
* @param exactAmountsIn Exact amounts of input tokens
* @param userData Optional, arbitrary data sent with the encoded request
* @return success True if the pool wishes to proceed with initialization
*/
function onBeforeInitialize(uint256[] memory exactAmountsIn, bytes memory userData) external returns (bool success);
/**
* @notice Hook to be executed after pool initialization.
* @dev Called if the `shouldCallAfterInitialize` flag is set in the configuration. Hook contracts should use
* the `onlyVault` modifier to guarantee this is only called by the Vault.
*
* @param exactAmountsIn Exact amounts of input tokens
* @param bptAmountOut Amount of pool tokens minted during initialization
* @param userData Optional, arbitrary data sent with the encoded request
* @return success True if the pool accepts the initialization results
*/
function onAfterInitialize(
uint256[] memory exactAmountsIn,
uint256 bptAmountOut,
bytes memory userData
) external returns (bool success);
/***************************************************************************
Add Liquidity
***************************************************************************/
/**
* @notice Hook to be executed before adding liquidity.
* @dev Called if the `shouldCallBeforeAddLiquidity` flag is set in the configuration. Hook contracts should use
* the `onlyVault` modifier to guarantee this is only called by the Vault.
*
* @param router The address (usually a router contract) that initiated an add liquidity operation on the Vault
* @param pool Pool address, used to fetch pool information from the Vault (pool config, tokens, etc.)
* @param kind The add liquidity operation type (e.g., proportional, custom)
* @param maxAmountsInScaled18 Maximum amounts of input tokens
* @param minBptAmountOut Minimum amount of output pool tokens
* @param balancesScaled18 Current pool balances, sorted in token registration order
* @param userData Optional, arbitrary data sent with the encoded request
* @return success True if the pool wishes to proceed with settlement
*/
function onBeforeAddLiquidity(
address router,
address pool,
AddLiquidityKind kind,
uint256[] memory maxAmountsInScaled18,
uint256 minBptAmountOut,
uint256[] memory balancesScaled18,
bytes memory userData
) external returns (bool success);
/**
* @notice Hook to be executed after adding liquidity.
* @dev Called if the `shouldCallAfterAddLiquidity` flag is set in the configuration. The Vault will ignore
* `hookAdjustedAmountsInRaw` unless `enableHookAdjustedAmounts` is true. Hook contracts should use the
* `onlyVault` modifier to guarantee this is only called by the Vault.
*
* @param router The address (usually a router contract) that initiated an add liquidity operation on the Vault
* @param pool Pool address, used to fetch pool information from the Vault (pool config, tokens, etc.)
* @param kind The add liquidity operation type (e.g., proportional, custom)
* @param amountsInScaled18 Actual amounts of tokens added, sorted in token registration order
* @param amountsInRaw Actual amounts of tokens added, sorted in token registration order
* @param bptAmountOut Amount of pool tokens minted
* @param balancesScaled18 Current pool balances, sorted in token registration order
* @param userData Additional (optional) data provided by the user
* @return success True if the pool wishes to proceed with settlement
* @return hookAdjustedAmountsInRaw New amountsInRaw, potentially modified by the hook
*/
function onAfterAddLiquidity(
address router,
address pool,
AddLiquidityKind kind,
uint256[] memory amountsInScaled18,
uint256[] memory amountsInRaw,
uint256 bptAmountOut,
uint256[] memory balancesScaled18,
bytes memory userData
) external returns (bool success, uint256[] memory hookAdjustedAmountsInRaw);
/***************************************************************************
Remove Liquidity
***************************************************************************/
/**
* @notice Hook to be executed before removing liquidity.
* @dev Called if the `shouldCallBeforeRemoveLiquidity` flag is set in the configuration. Hook contracts should use
* the `onlyVault` modifier to guarantee this is only called by the Vault.
*
* @param router The address (usually a router contract) that initiated a remove liquidity operation on the Vault
* @param pool Pool address, used to fetch pool information from the Vault (pool config, tokens, etc.)
* @param kind The type of remove liquidity operation (e.g., proportional, custom)
* @param maxBptAmountIn Maximum amount of input pool tokens
* @param minAmountsOutScaled18 Minimum output amounts, sorted in token registration order
* @param balancesScaled18 Current pool balances, sorted in token registration order
* @param userData Optional, arbitrary data sent with the encoded request
* @return success True if the pool wishes to proceed with settlement
*/
function onBeforeRemoveLiquidity(
address router,
address pool,
RemoveLiquidityKind kind,
uint256 maxBptAmountIn,
uint256[] memory minAmountsOutScaled18,
uint256[] memory balancesScaled18,
bytes memory userData
) external returns (bool success);
/**
* @notice Hook to be executed after removing liquidity.
* @dev Called if the `shouldCallAfterRemoveLiquidity` flag is set in the configuration. The Vault will ignore
* `hookAdjustedAmountsOutRaw` unless `enableHookAdjustedAmounts` is true. Hook contracts should use the
* `onlyVault` modifier to guarantee this is only called by the Vault.
*
* @param router The address (usually a router contract) that initiated a remove liquidity operation on the Vault
* @param pool Pool address, used to fetch pool information from the Vault (pool config, tokens, etc.)
* @param kind The type of remove liquidity operation (e.g., proportional, custom)
* @param bptAmountIn Amount of pool tokens to burn
* @param amountsOutScaled18 Scaled amount of tokens to receive, sorted in token registration order
* @param amountsOutRaw Actual amount of tokens to receive, sorted in token registration order
* @param balancesScaled18 Current pool balances, sorted in token registration order
* @param userData Additional (optional) data provided by the user
* @return success True if the pool wishes to proceed with settlement
* @return hookAdjustedAmountsOutRaw New amountsOutRaw, potentially modified by the hook
*/
function onAfterRemoveLiquidity(
address router,
address pool,
RemoveLiquidityKind kind,
uint256 bptAmountIn,
uint256[] memory amountsOutScaled18,
uint256[] memory amountsOutRaw,
uint256[] memory balancesScaled18,
bytes memory userData
) external returns (bool success, uint256[] memory hookAdjustedAmountsOutRaw);
/***************************************************************************
Swap
***************************************************************************/
/**
* @notice Called before a swap to give the Pool an opportunity to perform actions.
* @dev Called if the `shouldCallBeforeSwap` flag is set in the configuration. Hook contracts should use the
* `onlyVault` modifier to guarantee this is only called by the Vault.
*
* @param params Swap parameters (see PoolSwapParams for struct definition)
* @param pool Pool address, used to get pool information from the Vault (poolData, token config, etc.)
* @return success True if the pool wishes to proceed with settlement
*/
function onBeforeSwap(PoolSwapParams calldata params, address pool) external returns (bool success);
/**
* @notice Called after a swap to perform further actions once the balances have been updated by the swap.
* @dev Called if the `shouldCallAfterSwap` flag is set in the configuration. The Vault will ignore
* `hookAdjustedAmountCalculatedRaw` unless `enableHookAdjustedAmounts` is true. Hook contracts should
* use the `onlyVault` modifier to guarantee this is only called by the Vault.
*
* @param params Swap parameters (see above for struct definition)
* @return success True if the pool wishes to proceed with settlement
* @return hookAdjustedAmountCalculatedRaw New amount calculated, potentially modified by the hook
*/
function onAfterSwap(
AfterSwapParams calldata params
) external returns (bool success, uint256 hookAdjustedAmountCalculatedRaw);
/**
* @notice Called after `onBeforeSwap` and before the main swap operation, if the pool has dynamic fees.
* @dev Called if the `shouldCallComputeDynamicSwapFee` flag is set in the configuration. Hook contracts should use
* the `onlyVault` modifier to guarantee this is only called by the Vault.
*
* @param params Swap parameters (see PoolSwapParams for struct definition)
* @param pool Pool address, used to get pool information from the Vault (poolData, token config, etc.)
* @param staticSwapFeePercentage 18-decimal FP value of the static swap fee percentage, for reference
* @return success True if the pool wishes to proceed with settlement
* @return dynamicSwapFeePercentage Value of the swap fee percentage, as an 18-decimal FP value
*/
function onComputeDynamicSwapFeePercentage(
PoolSwapParams calldata params,
address pool,
uint256 staticSwapFeePercentage
) external view returns (bool success, uint256 dynamicSwapFeePercentage);
}
"
},
"@balancer-labs/v3-interfaces/contracts/vault/IProtocolFeeController.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 { IVault } from "./IVault.sol";
/// @notice Contract that handles protocol and pool creator fees for the Vault.
interface IProtocolFeeController {
/**
* @notice Emitted when the protocol swap fee percentage is updated.
* @param swapFeePercentage The updated protocol swap fee percentage
*/
event GlobalProtocolSwapFeePercentageChanged(uint256 swapFeePercentage);
/**
* @notice Emitted when the protocol yield fee percentage is updated.
* @param yieldFeePercentage The updated protocol yield fee percentage
*/
event GlobalProtocolYieldFeePercentageChanged(uint256 yieldFeePercentage);
/**
* @notice Emitted when the protocol swap fee percentage is updated for a specific pool.
* @param pool The pool whose protocol swap fee will be changed
* @param swapFeePercentage The updated protocol swap fee percentage
*/
event ProtocolSwapFeePercentageChanged(address indexed pool, uint256 swapFeePercentage);
/**
* @notice Emitted when the protocol yield fee percentage is updated for a specific pool.
* @param pool The pool whose protocol yield fee will be changed
* @param yieldFeePercentage The updated protocol yield fee percentage
*/
event ProtocolYieldFeePercentageChanged(address indexed pool, uint256 yieldFeePercentage);
/**
* @notice Emitted when the pool creator swap fee percentage of a pool is updated.
* @param pool The pool whose pool creator swap fee will be changed
* @param poolCreatorSwapFeePercentage The new pool creator swap fee percentage for the pool
*/
event PoolCreatorSwapFeePercentageChanged(address indexed pool, uint256 poolCreatorSwapFeePercentage);
/**
* @notice Emitted when the pool creator yield fee percentage of a pool is updated.
* @param pool The pool whose pool creator yield fee will be changed
* @param poolCreatorYieldFeePercentage The new pool creator yield fee percentage for the pool
*/
event PoolCreatorYieldFeePercentageChanged(address indexed pool, uint256 poolCreatorYieldFeePercentage);
/**
* @notice Logs the collection of protocol swap fees in a specific token and amount.
* @dev Note that since charging protocol fees (i.e., distributing tokens between pool and fee balances) occurs
* in the Vault, but fee collection happens in the ProtocolFeeController, the swap fees reported here may encompass
* multiple operations.
*
* @param pool The pool on which the swap fee was charged
* @param token The token in which the swap fee was charged
* @param amount The amount of the token collected in fees
*/
event ProtocolSwapFeeCollected(address indexed pool, IERC20 indexed token, uint256 amount);
/**
* @notice Logs the collection of protocol yield fees in a specific token and amount.
* @dev Note that since charging protocol fees (i.e., distributing tokens between pool and fee balances) occurs
* in the Vault, but fee collection happens in the ProtocolFeeController, the yield fees reported here may encompass
* multiple operations.
*
* @param pool The pool on which the yield fee was charged
* @param token The token in which the yield fee was charged
* @param amount The amount of the token collected in fees
*/
event ProtocolYieldFeeCollected(address indexed pool, IERC20 indexed token, uint256 amount);
/**
* @notice Logs the withdrawal of protocol fees in a specific token and amount.
* @param pool The pool from which protocol fees are being withdrawn
* @param token The token being withdrawn
* @param recipient The recipient of the funds
* @param amount The amount of the fee token that was withdrawn
*/
event ProtocolFeesWithdrawn(address indexed pool, IERC20 indexed token, address indexed recipient, uint256 amount);
/**
* @notice Logs the withdrawal of pool creator fees in a specific token and amount.
* @param pool The pool from which pool creator fees are being withdrawn
* @param token The token being withdrawn
* @param recipient The recipient of the funds (the pool creator if permissionless, or another account)
* @param amount The amount of the fee token that was withdrawn
*/
event PoolCreatorFeesWithdrawn(
address indexed pool,
IERC20 indexed token,
address indexed recipient,
uint256 amount
);
/**
* @notice Emitted on pool registration with the initial aggregate swap fee percentage, for off-chain processes.
* @dev If the pool is registered as protocol fee exempt, this will be zero (until changed). Otherwise, it will
* equal the current global swap fee percentage.
*
* @param pool The pool being registered
* @param aggregateSwapFeePercentage The initial aggregate swap fee percentage
* @param isProtocolFeeExempt True if the pool is exempt from taking protocol fees initially
*/
event InitialPoolAggregateSwapFeePercentage(
address indexed pool,
uint256 aggregateSwapFeePercentage,
bool isProtocolFeeExempt
);
/**
* @notice Emitted on pool registration with the initial aggregate yield fee percentage, for off-chain processes.
* @dev If the pool is registered as protocol fee exempt, this will be zero (until changed). Otherwise, it will
* equal the current global yield fee percentage.
*
* @param pool The pool being registered
* @param aggregateYieldFeePercentage The initial aggregate yield fee percentage
* @param isProtocolFeeExempt True if the pool is exempt from taking protocol fees initially
*/
event InitialPoolAggregateYieldFeePercentage(
address indexed pool,
uint256 aggregateYieldFeePercentage,
bool isProtocolFeeExempt
);
/**
* @notice Emitted as a convenience during pool registration, more focused than the Vault's `PoolRegistered` event.
* @dev The `PoolRegistered` event includes the `roleAccounts` field, which also records the pool creator, but this
* simpler event is also provided for convenience. Though `InitialPoolAggregateSwapFeePercentage` and its yield fee
* counterpart also include the protocol fee exemption flag, we might as well include it here as well.
*
* @param pool The address of the pool being registered
* @param poolCreator The address of the pool creator (non-zero, or the event would not be emitted)
* @param protocolFeeExempt True if the pool is initially exempt from protocol fees
*/
event PoolRegisteredWithFeeController(address indexed pool, address indexed poolCreator, bool protocolFeeExempt);
/**
* @notice Error raised when the protocol swap fee percentage exceeds the maximum allowed value.
* @dev Note that this is checked for both the global and pool-specific protocol swap fee percentages.
*/
error ProtocolSwapFeePercentageTooHigh();
/**
* @notice Error raised when the protocol yield fee percentage exceeds the maximum allowed value.
* @dev Note that this is checked for both the global and pool-specific protocol yield fee percentages.
*/
error ProtocolYieldFeePercentageTooHigh();
/**
* @notice Error raised if there is no pool creator on a withdrawal attempt from the given pool.
* @param pool The pool with no creator
*/
error PoolCreatorNotRegistered(address pool);
/**
* @notice Error raised if the wrong account attempts to withdraw pool creator fees.
* @param caller The account attempting to withdraw pool creator fees
* @param pool The pool the caller tried to withdraw from
*/
error CallerIsNotPoolCreator(address caller, address pool);
/// @notice Error raised when the pool creator swap or yield fee percentage exceeds the maximum allowed value.
error PoolCreatorFeePercentageTooHigh();
/**
* @notice Get the address of the main Vault contract.
* @return vault The Vault address
*/
function vault() external view returns (IVault);
/**
* @notice Collects aggregate fees from the Vault for a given pool.
* @param pool The pool with aggregate fees
*/
function collectAggregateFees(address pool) external;
/**
* @notice Getter for the current global protocol swap fee.
* @return protocolSwapFeePercentage The global protocol swap fee percentage
*/
function getGlobalProtocolSwapFeePercentage() external view returns (uint256 protocolSwapFeePercentage);
/**
* @notice Getter for the current global protocol yield fee.
* @return protocolYieldFeePercentage The global protocol yield fee percentage
*/
function getGlobalProtocolYieldFeePercentage() external view returns (uint256 protocolYieldFeePercentage);
/**
* @notice Getter for pool registration flag.
* @param pool The address of the pool
* @return isRegistered True if the pool configuration has been set (e.g., through `registerPool`)
*/
function isPoolRegistered(address pool) external view returns (bool);
/**
* @notice Getter for the current protocol swap fee for a given pool.
* @param pool The address of the pool
* @return protocolSwapFeePercentage The protocol swap fee percentage for the given pool
* @return isOverride True if the protocol fee has been overridden
*/
function getPoolProtocolSwapFeeInfo(
address pool
) external view returns (uint256 protocolSwapFeePercentage, bool isOverride);
/**
* @notice Getter for the current protocol yield fee for a given pool.
* @param pool The address of the pool
* @return protocolYieldFeePercentage The protocol yield fee percentage for the given pool
* @return isOverride True if the protocol fee has been overridden
*/
function getPoolProtocolYieldFeeInfo(
address pool
) external view returns (uint256 protocolYieldFeePercentage, bool isOverride);
/**
* @notice Getter for the current pool creator swap fee percentage for a given pool.
* @param pool The address of the pool
* @return poolCreatorSwapFeePercentage The pool creator swap fee component of the aggregate swap fee
*/
function getPoolCreatorSwapFeePercentage(address pool) external view returns (uint256);
/**
* @notice Getter for the current pool creator yield fee percentage for a given pool.
* @param pool The address of the pool
* @return poolCreatorSwapFeePercentage The pool creator yield fee component of the aggregate yield fee
*/
function getPoolCreatorYieldFeePercentage(address pool) external view returns (uint256);
/**
* @notice Returns the amount of each pool token allocated to the protocol for withdrawal.
* @dev Includes both swap and yield fees.
* @param pool The address of the pool on which fees were collected
* @return feeAmounts The total amounts of each token available for withdrawal, sorted in token registration order
*/
function getProtocolFeeAmounts(address pool) external view returns (uint256[] memory feeAmounts);
/**
* @notice Returns the amount of each pool token allocated to the pool creator for withdrawal.
* @dev Includes both swap and yield fees.
* @param pool The address of the pool on which fees were collected
* @return feeAmounts The total amounts of each token available for withdrawal, sorted in token registration order
*/
function getPoolCreatorFeeAmounts(address pool) external view returns (uint256[] memory feeAmounts);
/**
* @notice Returns a calculated aggregate percentage from protocol and pool creator fee percentages.
* @dev Not tied to any particular pool; this just performs the low-level "additive fee" calculation. Note that
* pool creator fees are calculated based on creatorAndLpFees, and not in totalFees. Since aggregate fees are
* stored in the Vault with 24-bit precision, this will truncate any values that require greater precision.
* It is expected that pool creators will negotiate with the DAO and agree on reasonable values for these fee
* components, but the truncation ensures it will not revert for any valid set of fee percentages.
*
* See example below:
*
* tokenOutAmount = 10000; poolSwapFeePct = 10%; protocolFeePct = 40%; creatorFeePct = 60%
* totalFees = tokenOutAmount * poolSwapFeePct = 10000 * 10% = 1000
* protocolFees = totalFees * protocolFeePct = 1000 * 40% = 400
* creatorAndLpFees = totalFees - protocolFees = 1000 - 400 = 600
* creatorFees = creatorAndLpFees * creatorFeePct = 600 * 60% = 360
* lpFees (will stay in the pool) = creatorAndLpFees - creatorFees = 600 - 360 = 240
*
* @param protocolFeePercentage The protocol portion of the aggregate fee percentage
* @param poolCreatorFeePercentage The pool creator portion of the aggregate fee percentage
* @return aggregateFeePercentage The computed aggregate percentage
*/
function computeAggregateFeePercentage(
uint256 protocolFeePercentage,
uint256 poolCreatorFeePercentage
) external pure returns (uint256 aggregateFeePercentage);
/**
* @notice Override the protocol swap fee percentage for a specific pool.
* @dev This is a permissionless call, and will set the pool's fee to the current global fee, if it is different
* from the current value, and the fee is not controlled by governance (i.e., has never been overridden).
*
* @param pool The pool for which we are setting the protocol swap fee
*/
function updateProtocolSwapFeePercentage(address pool) external;
/**
* @notice Override the protocol yield fee percentage for a specific pool.
* @dev This is a permissionless call, and will set the pool's fee to the current global fee, if it is different
* from the current value, and the fee is not controlled by governance (i.e., has never been overridden).
*
* @param pool The pool for which we are setting the protocol yield fee
*/
function updateProtocolYieldFeePercentage(address pool) external;
/***************************************************************************
Permissioned Functions
***************************************************************************/
/**
* @notice Add pool-specific entries to the protocol swap and yield percentages.
* @dev This must be called from the Vault during pool registration. It will initialize the pool to the global
* protocol fee percentage values (or 0, if the `protocolFeeExempt` flags is set), and return the initial aggregate
* fee percentages, based on an initial pool creator fee of 0.
*
* @param pool The address of the pool being registered
* @param poolCreator The address of the pool creator (or 0 if there won't be a pool creator fee)
* @param protocolFeeExempt If true, the pool is initially exempt from protocol fees
* @return aggregateSwapFeePercentage The initial aggregate swap fee percentage
* @return aggregateYieldFeePercentage The initial aggregate yield fee percentage
*/
function registerPool(
address pool,
address poolCreator,
bool protocolFeeExempt
) external returns (uint256 aggregateSwapFeePercentage, uint256 aggregateYieldFeePercentage);
/**
* @notice Set the global protocol swap fee percentage, used by standard pools.
* @param newProtocolSwapFeePercentage The new protocol swap fee percentage
*/
function setGlobalProtocolSwapFeePercentage(uint256 newProtocolSwapFeePercentage) external;
/**
* @notice Set the global protocol yield fee percentage, used by standard pools.
* @param newProtocolYieldFeePercentage The new protocol yield fee percentage
*/
function setGlobalProtocolYieldFeePercentage(uint256 newProtocolYieldFeePercentage) external;
/**
* @notice Override the protocol swap fee percentage for a specific pool.
* @param pool The address of the pool for which we are setting the protocol swap fee
* @param newProtocolSwapFeePercentage The new protocol swap fee percentage for the pool
*/
function setProtocolSwapFeePercentage(address pool, uint256 newProtocolSwapFeePercentage) external;
/**
* @notice Override the protocol yield fee percentage for a specific pool.
* @param pool The address of the pool for which we are setting the protocol yield fee
* @param newProtocolYieldFeePercentage The new protocol yield fee percentage for the pool
*/
function setProtocolYieldFeePercentage(address pool, uint256 newProtocolYieldFeePercentage) external;
/**
* @notice Assigns a new pool creator swap fee percentage to the specified pool.
* @dev Fees are divided between the protocol, pool creator, and LPs. The pool creator percentage is applied to
* the "net" amount after protocol fees, and divides the remainder between the pool creator and LPs. If the
* pool creator fee is near 100%, almost none of the fee amount remains in the pool for LPs.
*
* @param pool The address of the pool for which the pool creator fee will be changed
* @param poolCreatorSwapFeePercentage The new pool creator swap fee percentage to apply to the pool
*/
function setPoolCreatorSwapFeePercentage(address pool, uint256 poolCreatorSwapFeePercentage) external;
/**
* @notice Assigns a new pool creator yield fee percentage to the specified pool.
* @dev Fees are divided between the protocol, pool creator, and LPs. The pool creator percentage is applied to
* the "net" amount after protocol fees, and divides the remainder between the pool creator and LPs. If the
* pool creator fee is near 100%, almost none of the fee amount remains in the pool for LPs.
*
* @param pool The address of the pool for which the pool creator fee will be changed
* @param poolCreatorYieldFeePercentage The new pool creator yield fee percentage to apply to the pool
*/
function setPoolCreatorYieldFeePercentage(address pool, uint256 poolCreatorYieldFeePercentage) external;
/**
* @notice Withdraw collected protocol fees for a given pool (all tokens). This is a permissioned function.
* @dev Sends swap and yield protocol fees to the recipient.
* @param pool The pool on which fees were collected
* @param recipient Address to send the tokens
*/
function withdrawProtocolFees(address pool, address recipient) external;
/**
* @notice Withdraw collected protocol fees for a given pool and a given token. This is a permissioned function.
* @dev Sends swap and yield protocol fees to the recipient.
* @param pool The pool on which fees were collected
* @param recipient Address to send the tokens
* @param token Token to withdraw
*/
function withdrawProtocolFeesForToken(address pool, address recipient, IERC20 token) external;
/**
* @notice Withdraw collected pool creator fees for a given pool. This is a permissioned function.
* @dev Sends swap and yield pool creator fees to the recipient.
* @param pool The pool on which fees were collected
* @param recipient Address to send the tokens
*/
function withdrawPoolCreatorFees(address pool, address recipient) external;
/**
* @notice Withdraw collected pool creator fees for a given pool.
* @dev Sends swap and yield pool creator fees to the registered poolCreator. Since this is a known and immutable
* value, this function is permissionless.
*
* @param pool The pool on which fees were collected
*/
function withdrawPoolCreatorFees(address pool) external;
}
"
},
"@balancer-labs/v3-interfaces/contracts/vault/IVault.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
import { IAuthentication } from "../solidity-utils/helpers/IAuthentication.sol";
import { IVaultExtension } from "./IVaultExtension.sol";
import { IVaultErrors } from "./IVaultErrors.sol";
import { IVaultEvents } from "./IVaultEvents.sol";
import { IVaultAdmin } from "./IVaultAdmin.sol";
import { IVaultMain } from "./IVaultMain.sol";
/// @notice Composite interface for all Vault operations: swap, add/remove liquidity, and associated queries.
interface IVault is IVaultMain, IVaultExtension, IVaultAdmin, IVaultErrors, IVaultEvents, IAuthentication {
/// @return vault The main Vault address.
function vault() external view override(IVaultAdmin, IVaultExtension) returns (IVault);
}
"
},
"@balancer-labs/v3-interfaces/contracts/vault/IVaultAdmin.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;
import { IERC4626 } from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import { IProtocolFeeController } from "./IProtocolFeeController.sol";
import { IAuthorizer } from "./IAuthorizer.sol";
import { IVault } from "./IVault.sol";
/**
* @notice Interface for functions defined on the `VaultAdmin` contract.
* @dev `VaultAdmin` is the Proxy extension of `VaultExtension`, and handles the least critical operations,
* as two delegate calls add gas to each call. Most of the permissioned calls are here.
*/
interface IVaultAdmin {
/*******************************************************************************
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 Vault's pause window end time.
* @dev This value is immutable, and represents the timestamp after which the Vault can no longer be paused
* by governance. Balancer timestamps are 32 bits.
*
* @return pauseWindowEndTime The timestamp when the Vault's pause window ends
*/
function getPauseWindowEndTime() external view returns (uint32 pauseWindowEndTime);
/**
* @notice Returns the Vault's buffer period duration.
* @dev This value is immutable. It represents the period during which, if paused, the Vault will remain paused.
* This ensures there is time available to address whatever issue caused the Vault to be paused. Balancer
* timestamps are 32 bits.
*
* @return bufferPeriodDuration The length of the buffer period in seconds
*/
function getBufferPeriodDuration() external view returns (uint32 bufferPeriodDuration);
/**
* @notice Returns the Vault's buffer period end time.
* @dev This value is immutable. If already paused, the Vault can be unpaused until this timestamp. Balancer
* timestamps are 32 bits.
*
* @return bufferPeriodEndTime The timestamp after which the Vault remains permanently unpaused
*/
function getBufferPeriodEndTime() external view returns (uint32 bufferPeriodEndTime);
/**
* @notice Get the minimum number of tokens in a pool.
* @dev We expect the vast majority of pools to be 2-token.
* @return minTokens The minimum token count of a pool
*/
function getMinimumPoolTokens() external pure returns (uint256 minTokens);
/**
* @notice Get the maximum number of tokens in a pool.
* @return maxTokens The maximum token count of a pool
*/
function getMaximumPoolTokens() external pure returns (uint256 maxTokens);
/**
* @notice Get the minimum total supply of pool tokens (BPT) for an initialized pool.
* @dev This prevents pools from being completely drained. When the pool is initialized, this minimum amount of BPT
* is minted to the zero address. This is an 18-decimal floating point number; BPT are always 18 decimals.
*
* @return poolMinimumTotalSupply The minimum total supply a pool can have after initialization
*/
function getPoolMinimumTotalSupply() external pure returns (uint256 poolMinimumTotalSupply);
/**
* @notice Get the minimum total supply of an ERC4626 wrapped token buffer in the Vault.
* @dev This prevents buffers from being completely drained. When the buffer is initialized, this minimum number
* of shares is added to the shares resulting from the initial deposit. Buffer total supply accounting is internal
* to the Vault, as buffers are not tokenized.
*
* @return bufferMinimumTotalSupply The minimum total supply a buffer can have after initialization
*/
function getBufferMinimumTotalSupply() external pure returns (uint256 bufferMinimumTotalSupply);
/**
* @notice Get the minimum trade amount in a pool operation.
* @dev This limit is applied to the 18-decimal "upscaled" amount in any operation (swap, add/remove liquidity).
* @return minimumTradeAmount The minimum trade amount as an 18-decimal floating point number
*/
function getMinimumTradeAmount() external view returns (uint256 minimumTradeAmount);
/**
* @notice Get the minimum wrap amount in a buffer operation.
* @dev This limit is applied to the wrap operation amount, in native underlying token decimals.
* @return minimumWrapAmount The minimum wrap amount in native underlying token decimals
*/
function getMinimumWrapAmount() external view returns (uint256 minimumWrapAmount);
/*******************************************************************************
Vault Pausing
*******************************************************************************/
/**
* @notice Indicates whether the Vault is paused.
* @dev If the Vault is paused, all non-Recovery Mode state-changing operations on pools will revert. Note that
* ERC4626 buffers and the Vault have separate and independent pausing mechanisms. Pausing the Vault does not
* also pause buffers (though we anticipate they would likely be paused and unpaused together). Call
* `areBuffersPaused` to check the pause state of the buffers.
*
* @return vaultPaused True if the Vault is paused
*/
function isVaultPaused() external view returns (bool vaultPaused);
/**
* @notice Returns the paused status, and end times of the Vault's pause window and buffer period.
* @dev Balancer timestamps are 32 bits.
* @return vaultPaused True if the Vault is paused
* @return vaultPauseWindowEndTime The timestamp of the end of the Vault's pause window
* @return vaultBufferPeriodEndTime The timestamp of the end of the Vault's buffer period
*/
function getVaultPausedState()
external
view
returns (bool vaultPaused, uint32 vaultPauseWindowEndTime, uint32 vaultBufferPeriodEndTime);
/**
* @notice Pause the Vault: an emergency action which disables all operational state-changing functions on pools.
* @dev This is a permissioned function that will only work during the Pause Window set during deployment.
* Note that ERC4626 buffer operations have an independent pause mechanism, which is not affected by pausing
* the Vault. Custom routers could still wrap/unwrap using buffers while the Vault is paused, unless buffers
* are also paused (with `pauseVaultBuffers`).
*/
function pauseVault() external;
/**
* @notice Reverse a `pause` operation, and restore Vault pool operations to normal functionality.
* @dev This is a permissioned function that will only work on a paused Vault within the Buffer Period set during
* deployment. Note that the Vault will automatically unpause after the Buffer Period expires. As noted above,
* ERC4626 buffers and Vault operations on pools are independent. Unpausing the Vault does not reverse
* `pauseVaultBuffers`. If buffers were also paused, they will remain in that state until explicitly unpaused.
*/
function unpauseVault() external;
/*******************************************************************************
Pool Pausing
*******************************************************************************/
/**
* @notice Pause the Pool: an emergency action which disables all pool functions.
* @dev This is a permissioned function that will only work during the Pause Window set during pool factory
* deployment.
*
* @param pool The pool being paused
*/
function pausePool(address pool) external;
/**
* @notice Reverse a `pause` operation, and restore the Pool to normal functionality.
* @dev This is a permissioned function that will only work on a paused Pool within the Buffer Period set during
* deployment. Note that the Pool will automatically unpause after the Buffer Period expires.
*
* @param pool The pool being unpaused
*/
function unpausePool(address pool) external;
/*******************************************************************************
Fees
*******************************************************************************/
/**
* @notice Assigns a new static swap fee percentage to the specified pool.
* @dev This is a permissioned function, disabled if the pool is paused. The swap fee percentage must be within
* the bounds specified by the pool's implementation of `ISwapFeePercentageBounds`.
* Emits the SwapFeePercentageChanged event.
*
* @param pool The address of the pool for which the static swap fee will be changed
* @param swapFeePercentage The new swap fee percentage to apply to the pool
*/
function setStaticSwapFeePercentage(address pool, uint256 swapFeePercentage) external;
/**
* @notice Collects accumulated aggregate swap and yield fees for the specified pool.
* @dev Fees are sent to the ProtocolFeeController address.
* @param pool The pool on which all aggregate fees should be collected
* @return swapFeeAmounts An array with the total swap fees collected, sorted in token registration order
* @return yieldFeeAmounts An array with the total yield fees collected, sorted in token registration order
*/
function collectAggregateFees(
address pool
) external returns (uint256[] memory swapFeeAmounts, uint256[] memory yieldFeeAmounts);
/**
* @notice Update an aggregate swap fee percentage.
* @dev Can only be called by the current protocol fee controller. Called when governance overrides a protocol fee
* for a specific pool, or to permissionlessly update a pool to a changed global protocol fee value (if the pool's
* fee has not previously been set by governance). Ensures the aggregate percentage <= FixedPoint.ONE, and also
* that the final value does not lose precision when stored in 24 bits (see `FEE_BITLENGTH` in VaultTypes.sol).
* Emits an `AggregateSwapFeePercentageChanged` event.
*
* @param pool The pool whose swap fee percentage will be updated
* @param newAggregateSwapFeePercentage The new aggregate swap fee percentage
*/
function updateAggregateSwapFeePercentage(address pool, uint256 newAggregateSwapFeePercentage) external;
/**
* @notice Update an aggregate yield fee percentage.
* @dev Can only be called by the current protocol fee controller. Called when governance overrides a protocol fee
* for a specific pool, or to permissionlessly update a pool to a changed global protocol fee value (if the pool's
* fee has not previously been set by governance). Ensures the aggregate percentage <= FixedPoint.ONE, and also
* that the final value does not lose precision when stored in 24 bits (see `FEE_BITLENGTH` in VaultTypes.sol).
* Emits an `AggregateYieldFeePercentageChanged` event.
*
* @param pool The pool whose yield fee percentage will be updated
* @param newAggregateYieldFeePercentage The new aggregate yield fee percentage
*/
function updateAggregateYieldFeePercentage(address pool, uint256 newAggregateYieldFeePercentage) external;
/**
* @notice Sets a new Protocol Fee Controller for the Vault.
* @dev This is a permissioned call. Emits a `ProtocolFeeControllerChanged` event.
* @param newProtocolFeeController The address of the new Protocol Fee Controller
*/
function setProtocolFeeController(IProtocolFeeController newProtocolFeeController) external;
/*******************************************************************************
Recovery Mode
*******************************************************************************/
/**
* @notice Enable recovery mode for a pool.
* @dev This is a permissioned function. It enables a safe proportional withdrawal, with no external calls.
* Since there are no external calls, ensuring that entering Recovery Mode cannot fail, we cannot compute and so
* must forfeit any yield fees between the last operation and enabling Recovery Mode. For the same reason, live
* balances cannot be updated while in Recovery Mode, as doing so might cause withdrawals to fail.
*
* @param pool The address of the pool
*/
function enableRecoveryMode(address pool) external;
/**
* @notice Disable recovery mode for a pool.
* @dev This is a permissioned function. It re-syncs live balances (which could not be updated during
* Recovery Mode), forfeiting any yield fees that accrued while enabled. It makes external calls, and could
* potentially fail if there is an issue with any associated Rate Providers.
*
* @param pool The address of the pool
*/
function disableRecoveryMode(address pool) external;
/*******************************************************************************
Query Functionality
*******************************************************************************/
/**
* @notice Disables query functionality on the Vault. Can only be called by governance.
* @dev The query functions rely on a specific EVM feature to detect static calls. Query operations are exempt from
* settlement constraints, so it's critical that no state changes can occur. We retain the ability to disable
* queries in the unlikely event that EVM changes violate its assumptions (perhaps on an L2).
* This function can be acted upon as an emergency measure in ambiguous contexts where it's not 100% clear whether
* disabling queries is completely necessary; queries can still be re-enabled after this call.
*/
function disableQuery() external;
/**
* @notice Disables query functionality permanently on the Vault. Can only be called by governance.
* @dev Shall only be used when there is no doubt that queries pose a fundamental threat to the system.
*/
function disableQueryPermanently() external;
/**
* @notice Enables query functionality on the Vault. Can only be called by governance.
* @dev Only works if queries are not permanently disabled.
*/
function enableQuery() external;
/*******************************************************************************
ERC4626 Buffers
*******************************************************************************/
/**
* @notice Indicates whether the Vault buffers are paused.
* @dev When bu
Submitted on: 2025-11-06 20:37:12
Comments
Log in to comment.
No comments yet.