364 lines
16 KiB
Solidity
364 lines
16 KiB
Solidity
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
pragma solidity >=0.7.0 <0.9.0;
|
|
|
|
import "../solidity-utils/openzeppelin/IERC20.sol";
|
|
import "../vault/IBasePool.sol";
|
|
|
|
interface IManagedPool is IBasePool {
|
|
event GradualSwapFeeUpdateScheduled(
|
|
uint256 startTime,
|
|
uint256 endTime,
|
|
uint256 startSwapFeePercentage,
|
|
uint256 endSwapFeePercentage
|
|
);
|
|
event GradualWeightUpdateScheduled(
|
|
uint256 startTime,
|
|
uint256 endTime,
|
|
uint256[] startWeights,
|
|
uint256[] endWeights
|
|
);
|
|
event SwapEnabledSet(bool swapEnabled);
|
|
event JoinExitEnabledSet(bool joinExitEnabled);
|
|
event MustAllowlistLPsSet(bool mustAllowlistLPs);
|
|
event AllowlistAddressAdded(address indexed member);
|
|
event AllowlistAddressRemoved(address indexed member);
|
|
event ManagementAumFeePercentageChanged(uint256 managementAumFeePercentage);
|
|
event ManagementAumFeeCollected(uint256 bptAmount);
|
|
event CircuitBreakerSet(
|
|
IERC20 indexed token,
|
|
uint256 bptPrice,
|
|
uint256 lowerBoundPercentage,
|
|
uint256 upperBoundPercentage
|
|
);
|
|
event TokenAdded(IERC20 indexed token, uint256 normalizedWeight);
|
|
event TokenRemoved(IERC20 indexed token);
|
|
|
|
/**
|
|
* @notice Returns the effective BPT supply.
|
|
*
|
|
* @dev The Pool owes debt to the Protocol and the Pool's owner in the form of unminted BPT, which will be minted
|
|
* immediately before the next join or exit. We need to take these into account since, even if they don't yet exist,
|
|
* they will effectively be included in any Pool operation that involves BPT.
|
|
*
|
|
* In the vast majority of cases, this function should be used instead of `totalSupply()`.
|
|
*
|
|
* WARNING: since this function reads balances directly from the Vault, it is potentially subject to manipulation
|
|
* via reentrancy. See https://forum.balancer.fi/t/reentrancy-vulnerability-scope-expanded/4345 for reference.
|
|
*
|
|
* To call this function safely, attempt to trigger the reentrancy guard in the Vault by calling a non-reentrant
|
|
* function before calling `getActualSupply`. That will make the transaction revert in an unsafe context.
|
|
* (See `whenNotInVaultContext` in `ManagedPoolSettings`).
|
|
*/
|
|
function getActualSupply() external view returns (uint256);
|
|
|
|
// Swap fee percentage
|
|
|
|
/**
|
|
* @notice Schedule a gradual swap fee update.
|
|
* @dev The swap fee will change from the given starting value (which may or may not be the current
|
|
* value) to the given ending fee percentage, over startTime to endTime.
|
|
*
|
|
* Note that calling this with a starting swap fee different from the current value will immediately change the
|
|
* current swap fee to `startSwapFeePercentage`, before commencing the gradual change at `startTime`.
|
|
* Emits the GradualSwapFeeUpdateScheduled event.
|
|
* This is a permissioned function.
|
|
*
|
|
* @param startTime - The timestamp when the swap fee change will begin.
|
|
* @param endTime - The timestamp when the swap fee change will end (must be >= startTime).
|
|
* @param startSwapFeePercentage - The starting value for the swap fee change.
|
|
* @param endSwapFeePercentage - The ending value for the swap fee change. If the current timestamp >= endTime,
|
|
* `getSwapFeePercentage()` will return this value.
|
|
*/
|
|
function updateSwapFeeGradually(
|
|
uint256 startTime,
|
|
uint256 endTime,
|
|
uint256 startSwapFeePercentage,
|
|
uint256 endSwapFeePercentage
|
|
) external;
|
|
|
|
/**
|
|
* @notice Returns the current gradual swap fee update parameters.
|
|
* @dev The current swap fee can be retrieved via `getSwapFeePercentage()`.
|
|
* @return startTime - The timestamp when the swap fee update will begin.
|
|
* @return endTime - The timestamp when the swap fee update will end.
|
|
* @return startSwapFeePercentage - The starting swap fee percentage (could be different from the current value).
|
|
* @return endSwapFeePercentage - The final swap fee percentage, when the current timestamp >= endTime.
|
|
*/
|
|
function getGradualSwapFeeUpdateParams()
|
|
external
|
|
view
|
|
returns (
|
|
uint256 startTime,
|
|
uint256 endTime,
|
|
uint256 startSwapFeePercentage,
|
|
uint256 endSwapFeePercentage
|
|
);
|
|
|
|
// Token weights
|
|
|
|
/**
|
|
* @notice Schedule a gradual weight change.
|
|
* @dev The weights will change from their current values to the given endWeights, over startTime to endTime.
|
|
* This is a permissioned function.
|
|
*
|
|
* Since, unlike with swap fee updates, we generally do not want to allow instantaneous weight changes,
|
|
* the weights always start from their current values. This also guarantees a smooth transition when
|
|
* updateWeightsGradually is called during an ongoing weight change.
|
|
* @param startTime - The timestamp when the weight change will begin.
|
|
* @param endTime - The timestamp when the weight change will end (can be >= startTime).
|
|
* @param tokens - The tokens associated with the target weights (must match the current pool tokens).
|
|
* @param endWeights - The target weights. If the current timestamp >= endTime, `getNormalizedWeights()`
|
|
* will return these values.
|
|
*/
|
|
function updateWeightsGradually(
|
|
uint256 startTime,
|
|
uint256 endTime,
|
|
IERC20[] memory tokens,
|
|
uint256[] memory endWeights
|
|
) external;
|
|
|
|
/**
|
|
* @notice Returns all normalized weights, in the same order as the Pool's tokens.
|
|
*/
|
|
function getNormalizedWeights() external view returns (uint256[] memory);
|
|
|
|
/**
|
|
* @notice Returns the current gradual weight change update parameters.
|
|
* @dev The current weights can be retrieved via `getNormalizedWeights()`.
|
|
* @return startTime - The timestamp when the weight update will begin.
|
|
* @return endTime - The timestamp when the weight update will end.
|
|
* @return startWeights - The starting weights, when the weight change was initiated.
|
|
* @return endWeights - The final weights, when the current timestamp >= endTime.
|
|
*/
|
|
function getGradualWeightUpdateParams()
|
|
external
|
|
view
|
|
returns (
|
|
uint256 startTime,
|
|
uint256 endTime,
|
|
uint256[] memory startWeights,
|
|
uint256[] memory endWeights
|
|
);
|
|
|
|
// Join and Exit enable/disable
|
|
|
|
/**
|
|
* @notice Enable or disable joins and exits. Note that this does not affect Recovery Mode exits.
|
|
* @dev Emits the JoinExitEnabledSet event. This is a permissioned function.
|
|
* @param joinExitEnabled - The new value of the join/exit enabled flag.
|
|
*/
|
|
function setJoinExitEnabled(bool joinExitEnabled) external;
|
|
|
|
/**
|
|
* @notice Returns whether joins and exits are enabled.
|
|
*/
|
|
function getJoinExitEnabled() external view returns (bool);
|
|
|
|
// Swap enable/disable
|
|
|
|
/**
|
|
* @notice Enable or disable trading.
|
|
* @dev Emits the SwapEnabledSet event. This is a permissioned function.
|
|
* @param swapEnabled - The new value of the swap enabled flag.
|
|
*/
|
|
function setSwapEnabled(bool swapEnabled) external;
|
|
|
|
/**
|
|
* @notice Returns whether swaps are enabled.
|
|
*/
|
|
function getSwapEnabled() external view returns (bool);
|
|
|
|
// LP Allowlist
|
|
|
|
/**
|
|
* @notice Enable or disable the LP allowlist.
|
|
* @dev Note that any addresses added to the allowlist will be retained if the allowlist is toggled off and
|
|
* back on again, because this action does not affect the list of LP addresses.
|
|
* Emits the MustAllowlistLPsSet event. This is a permissioned function.
|
|
* @param mustAllowlistLPs - The new value of the mustAllowlistLPs flag.
|
|
*/
|
|
function setMustAllowlistLPs(bool mustAllowlistLPs) external;
|
|
|
|
/**
|
|
* @notice Adds an address to the LP allowlist.
|
|
* @dev Will fail if the address is already allowlisted.
|
|
* Emits the AllowlistAddressAdded event. This is a permissioned function.
|
|
* @param member - The address to be added to the allowlist.
|
|
*/
|
|
function addAllowedAddress(address member) external;
|
|
|
|
/**
|
|
* @notice Removes an address from the LP allowlist.
|
|
* @dev Will fail if the address was not previously allowlisted.
|
|
* Emits the AllowlistAddressRemoved event. This is a permissioned function.
|
|
* @param member - The address to be removed from the allowlist.
|
|
*/
|
|
function removeAllowedAddress(address member) external;
|
|
|
|
/**
|
|
* @notice Returns whether the allowlist for LPs is enabled.
|
|
*/
|
|
function getMustAllowlistLPs() external view returns (bool);
|
|
|
|
/**
|
|
* @notice Check whether an LP address is on the allowlist.
|
|
* @dev This simply checks the list, regardless of whether the allowlist feature is enabled.
|
|
* @param member - The address to check against the allowlist.
|
|
* @return true if the given address is on the allowlist.
|
|
*/
|
|
function isAddressOnAllowlist(address member) external view returns (bool);
|
|
|
|
// Management fees
|
|
|
|
/**
|
|
* @notice Collect any accrued AUM fees and send them to the pool manager.
|
|
* @dev This can be called by anyone to collect accrued AUM fees - and will be called automatically
|
|
* whenever the supply changes (e.g., joins and exits, add and remove token), and before the fee
|
|
* percentage is changed by the manager, to prevent fees from being applied retroactively.
|
|
*
|
|
* Correct behavior depends on the current supply, which is potentially manipulable if the pool
|
|
* is reentered during execution of a Vault hook. This is protected where overridden in ManagedPoolSettings,
|
|
* and so is safe to call on ManagedPool.
|
|
*
|
|
* See https://forum.balancer.fi/t/reentrancy-vulnerability-scope-expanded/4345 for reference.
|
|
*
|
|
* @return The amount of BPT minted to the manager.
|
|
*/
|
|
function collectAumManagementFees() external returns (uint256);
|
|
|
|
/**
|
|
* @notice Setter for the yearly percentage AUM management fee, which is payable to the pool manager.
|
|
* @dev Attempting to collect AUM fees in excess of the maximum permitted percentage will revert.
|
|
* To avoid retroactive fee increases, we force collection at the current fee percentage before processing
|
|
* the update. Emits the ManagementAumFeePercentageChanged event. This is a permissioned function.
|
|
*
|
|
* To prevent changing management fees retroactively, this triggers payment of protocol fees before applying
|
|
* the change. Correct behavior depends on the current supply, which is potentially manipulable if the pool
|
|
* is reentered during execution of a Vault hook. This is protected where overridden in ManagedPoolSettings,
|
|
* and so is safe to call on ManagedPool.
|
|
*
|
|
* See https://forum.balancer.fi/t/reentrancy-vulnerability-scope-expanded/4345 for reference.
|
|
*
|
|
* @param managementAumFeePercentage - The new management AUM fee percentage.
|
|
* @return amount - The amount of BPT minted to the manager before the update, if any.
|
|
*/
|
|
function setManagementAumFeePercentage(uint256 managementAumFeePercentage) external returns (uint256);
|
|
|
|
/**
|
|
* @notice Returns the management AUM fee percentage as an 18-decimal fixed point number and the timestamp of the
|
|
* last collection of AUM fees.
|
|
*/
|
|
function getManagementAumFeeParams()
|
|
external
|
|
view
|
|
returns (uint256 aumFeePercentage, uint256 lastCollectionTimestamp);
|
|
|
|
// Circuit Breakers
|
|
|
|
/**
|
|
* @notice Set a circuit breaker for one or more tokens.
|
|
* @dev This is a permissioned function. The lower and upper bounds are percentages, corresponding to a
|
|
* relative change in the token's spot price: e.g., a lower bound of 0.8 means the breaker should prevent
|
|
* trades that result in the value of the token dropping 20% or more relative to the rest of the pool.
|
|
*/
|
|
function setCircuitBreakers(
|
|
IERC20[] memory tokens,
|
|
uint256[] memory bptPrices,
|
|
uint256[] memory lowerBoundPercentages,
|
|
uint256[] memory upperBoundPercentages
|
|
) external;
|
|
|
|
/**
|
|
* @notice Return the full circuit breaker state for the given token.
|
|
* @dev These are the reference values (BPT price and reference weight) passed in when the breaker was set,
|
|
* along with the percentage bounds. It also returns the current BPT price bounds, needed to check whether
|
|
* the circuit breaker should trip.
|
|
*/
|
|
function getCircuitBreakerState(IERC20 token)
|
|
external
|
|
view
|
|
returns (
|
|
uint256 bptPrice,
|
|
uint256 referenceWeight,
|
|
uint256 lowerBound,
|
|
uint256 upperBound,
|
|
uint256 lowerBptPriceBound,
|
|
uint256 upperBptPriceBound
|
|
);
|
|
|
|
// Add/remove tokens
|
|
|
|
/**
|
|
* @notice Adds a token to the Pool's list of tradeable tokens. This is a permissioned function.
|
|
*
|
|
* @dev By adding a token to the Pool's composition, the weights of all other tokens will be decreased. The new
|
|
* token will have no balance - it is up to the owner to provide some immediately after calling this function.
|
|
* Note however that regular join functions will not work while the new token has no balance: the only way to
|
|
* deposit an initial amount is by using an Asset Manager.
|
|
*
|
|
* Token addition is forbidden during a weight change, or if one is scheduled to happen in the future.
|
|
*
|
|
* The caller may additionally pass a non-zero `mintAmount` to have some BPT be minted for them, which might be
|
|
* useful in some scenarios to account for the fact that the Pool will have more tokens.
|
|
*
|
|
* Emits the TokenAdded event. This is a permissioned function.
|
|
*
|
|
* Correct behavior depends on the token balances from the Vault, which may be out of sync with the state of
|
|
* the pool during execution of a Vault hook. This is protected where overridden in ManagedPoolSettings,
|
|
* and so is safe to call on ManagedPool.
|
|
*
|
|
* See https://forum.balancer.fi/t/reentrancy-vulnerability-scope-expanded/4345 for reference.
|
|
*
|
|
* @param tokenToAdd - The ERC20 token to be added to the Pool.
|
|
* @param assetManager - The Asset Manager for the token.
|
|
* @param tokenToAddNormalizedWeight - The normalized weight of `token` relative to the other tokens in the Pool.
|
|
* @param mintAmount - The amount of BPT to be minted as a result of adding `token` to the Pool.
|
|
* @param recipient - The address to receive the BPT minted by the Pool.
|
|
*/
|
|
function addToken(
|
|
IERC20 tokenToAdd,
|
|
address assetManager,
|
|
uint256 tokenToAddNormalizedWeight,
|
|
uint256 mintAmount,
|
|
address recipient
|
|
) external;
|
|
|
|
/**
|
|
* @notice Removes a token from the Pool's list of tradeable tokens.
|
|
* @dev Tokens can only be removed if the Pool has more than 2 tokens, as it can never have fewer than 2 (not
|
|
* including BPT). Token removal is also forbidden during a weight change, or if one is scheduled to happen in
|
|
* the future.
|
|
*
|
|
* Emits the TokenRemoved event. This is a permissioned function.
|
|
* Correct behavior depends on the token balances from the Vault, which may be out of sync with the state of
|
|
* the pool during execution of a Vault hook. This is protected where overridden in ManagedPoolSettings,
|
|
* and so is safe to call on ManagedPool.
|
|
*
|
|
* See https://forum.balancer.fi/t/reentrancy-vulnerability-scope-expanded/4345 for reference.
|
|
*
|
|
* The caller may additionally pass a non-zero `burnAmount` to burn some of their BPT, which might be useful
|
|
* in some scenarios to account for the fact that the Pool now has fewer tokens. This is a permissioned function.
|
|
* @param tokenToRemove - The ERC20 token to be removed from the Pool.
|
|
* @param burnAmount - The amount of BPT to be burned after removing `token` from the Pool.
|
|
* @param sender - The address to burn BPT from.
|
|
*/
|
|
function removeToken(
|
|
IERC20 tokenToRemove,
|
|
uint256 burnAmount,
|
|
address sender
|
|
) external;
|
|
}
|