From a700189aaf8364a55e9625c807191232663eeff8 Mon Sep 17 00:00:00 2001 From: royvardhan Date: Mon, 27 Jan 2025 22:54:56 +0530 Subject: [PATCH] feat: add balancer v2 executor --- cache/solidity-files-cache.json | 1 + .../balancer-labs/v2-interfaces/CHANGELOG.md | 57 ++ .../lib/balancer-labs/v2-interfaces/README.md | 139 ++++ .../distributors/IDistributorCallback.sol | 19 + .../liquidity-mining/IArbitrumFeeProvider.sol | 32 + .../liquidity-mining/IAuthorizerAdaptor.sol | 38 + .../IAuthorizerAdaptorEntrypoint.sol | 27 + .../liquidity-mining/IBalancerMinter.sol | 115 +++ .../liquidity-mining/IBalancerToken.sol | 44 + .../liquidity-mining/IBalancerTokenAdmin.sol | 45 + .../liquidity-mining/IChildChainGauge.sol | 51 ++ .../IChildChainLiquidityGaugeFactory.sol | 60 ++ .../liquidity-mining/IChildChainStreamer.sol | 35 + .../liquidity-mining/IFeeDistributor.sol | 168 ++++ .../liquidity-mining/IGaugeAdder.sol | 97 +++ .../liquidity-mining/IGaugeController.sol | 48 ++ .../liquidity-mining/IL2GaugeCheckpointer.sol | 109 +++ .../contracts/liquidity-mining/ILMGetters.sol | 30 + .../liquidity-mining/ILiquidityGauge.sol | 72 ++ .../ILiquidityGaugeFactory.sol | 25 + .../IMainnetBalancerMinter.sol | 25 + .../IOptimismGasLimitProvider.sol | 21 + .../IRewardTokenDistributor.sol | 49 ++ .../liquidity-mining/IRewardsOnlyGauge.sol | 43 + .../liquidity-mining/ISmartWalletChecker.sol | 19 + .../liquidity-mining/IStakelessGauge.sol | 23 + .../IStakingLiquidityGauge.sol | 35 + .../liquidity-mining/IVeDelegation.sol | 26 + .../liquidity-mining/IVotingEscrow.sol | 51 ++ .../contracts/pool-linear/IERC4626.sol | 67 ++ .../contracts/pool-linear/ILinearPool.sol | 84 ++ .../IComposableStablePoolRates.sol | 32 + .../pool-stable/StablePoolUserData.sol | 68 ++ .../contracts/pool-utils/BasePoolUserData.sol | 32 + .../pool-utils/IBasePoolController.sol | 19 + .../contracts/pool-utils/IBasePoolFactory.sol | 36 + .../contracts/pool-utils/IControlledPool.sol | 21 + .../pool-utils/IFactoryCreatedPoolVersion.sol | 28 + .../pool-utils/ILastCreatedPoolFactory.sol | 28 + .../contracts/pool-utils/IManagedPool.sol | 363 ++++++++ .../contracts/pool-utils/IPoolVersion.sol | 28 + .../pool-utils/IProtocolFeeCache.sol | 29 + .../contracts/pool-utils/IRateProvider.sol | 23 + .../pool-utils/IRateProviderPool.sol | 28 + .../contracts/pool-utils/IRecoveryMode.sol | 41 + .../pool-utils/IRecoveryModeHelper.sol | 52 ++ .../contracts/pool-utils/IVersion.sol | 25 + .../pool-weighted/IExternalWeightedMath.sol | 203 +++++ .../pool-weighted/WeightedPoolUserData.sol | 71 ++ .../solidity-utils/helpers/BalancerErrors.sol | 293 +++++++ .../helpers/IAuthentication.sol | 22 + .../helpers/IOptionalOnlyCaller.sol | 43 + .../helpers/ISignaturesValidator.sol | 30 + .../helpers/ITemporarilyPausable.sol | 37 + .../solidity-utils/misc/IERC4626.sol | 72 ++ .../contracts/solidity-utils/misc/IWETH.sol | 27 + .../solidity-utils/openzeppelin/IERC1271.sol | 19 + .../solidity-utils/openzeppelin/IERC20.sol | 81 ++ .../openzeppelin/IERC20Permit.sol | 59 ++ .../openzeppelin/IERC20PermitDAI.sol | 27 + .../solidity-utils/openzeppelin/LICENSE | 22 + .../solidity-utils/openzeppelin/README.md | 11 + .../contracts/standalone-utils/IAToken.sol | 23 + .../standalone-utils/IBALTokenHolder.sol | 30 + .../IBALTokenHolderFactory.sol | 30 + .../standalone-utils/IBalancerQueries.sol | 62 ++ .../standalone-utils/IBalancerRelayer.sol | 30 + .../standalone-utils/IButtonWrapper.sol | 120 +++ .../contracts/standalone-utils/ICToken.sol | 48 ++ .../standalone-utils/IEulerToken.sol | 52 ++ .../standalone-utils/IGearboxDieselToken.sol | 62 ++ .../IProtocolFeePercentagesProvider.sol | 100 +++ .../standalone-utils/IProtocolFeeSplitter.sol | 136 +++ .../IProtocolFeesWithdrawer.sol | 78 ++ .../standalone-utils/IProtocolIdRegistry.sol | 74 ++ .../standalone-utils/IReaperTokenVault.sol | 54 ++ .../standalone-utils/IShareToken.sol | 31 + .../contracts/standalone-utils/ISilo.sol | 76 ++ .../standalone-utils/IStaticATokenLM.sol | 247 ++++++ .../standalone-utils/ITetuSmartVault.sol | 37 + .../standalone-utils/ITetuStrategy.sol | 19 + .../standalone-utils/IUnbuttonToken.sol | 25 + .../standalone-utils/IYearnTokenVault.sol | 49 ++ .../contracts/standalone-utils/IstETH.sol | 24 + .../contracts/standalone-utils/IwstETH.sol | 92 +++ .../v2-interfaces/contracts/vault/IAsset.sol | 26 + .../contracts/vault/IAuthorizer.sol | 26 + .../contracts/vault/IBasePool.sol | 126 +++ .../contracts/vault/IBasicAuthorizer.sol | 26 + .../contracts/vault/IFlashLoanRecipient.sol | 37 + .../contracts/vault/IGeneralPool.sol | 38 + .../contracts/vault/IMinimalSwapInfoPool.sol | 37 + .../contracts/vault/IPoolSwapStructs.sol | 59 ++ .../vault/IProtocolFeesCollector.sol | 46 ++ .../v2-interfaces/contracts/vault/IVault.sol | 772 ++++++++++++++++++ .../balancer-labs/v2-interfaces/package.json | 58 ++ foundry/remappings.txt | 3 +- foundry/src/executors/BalancerV2Executor.sol | 91 +++ 98 files changed, 6368 insertions(+), 1 deletion(-) create mode 100644 cache/solidity-files-cache.json create mode 100644 foundry/lib/balancer-labs/v2-interfaces/CHANGELOG.md create mode 100644 foundry/lib/balancer-labs/v2-interfaces/README.md create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/distributors/IDistributorCallback.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IArbitrumFeeProvider.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IAuthorizerAdaptor.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IAuthorizerAdaptorEntrypoint.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerMinter.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerToken.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerTokenAdmin.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainGauge.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainLiquidityGaugeFactory.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainStreamer.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IFeeDistributor.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeAdder.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeController.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IL2GaugeCheckpointer.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILMGetters.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGauge.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGaugeFactory.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IMainnetBalancerMinter.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IOptimismGasLimitProvider.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IRewardTokenDistributor.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IRewardsOnlyGauge.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ISmartWalletChecker.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakelessGauge.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakingLiquidityGauge.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IVeDelegation.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IVotingEscrow.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-linear/IERC4626.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-linear/ILinearPool.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-stable/IComposableStablePoolRates.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-stable/StablePoolUserData.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/BasePoolUserData.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IBasePoolController.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IBasePoolFactory.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IControlledPool.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IFactoryCreatedPoolVersion.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/ILastCreatedPoolFactory.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IManagedPool.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IPoolVersion.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IProtocolFeeCache.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRateProvider.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRateProviderPool.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRecoveryMode.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRecoveryModeHelper.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IVersion.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-weighted/IExternalWeightedMath.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/pool-weighted/WeightedPoolUserData.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/BalancerErrors.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/IAuthentication.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/IOptionalOnlyCaller.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ISignaturesValidator.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ITemporarilyPausable.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IERC4626.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IWETH.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC1271.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20Permit.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20PermitDAI.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/LICENSE create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/README.md create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IAToken.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBALTokenHolder.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBALTokenHolderFactory.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBalancerQueries.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBalancerRelayer.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IButtonWrapper.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ICToken.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IEulerToken.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IGearboxDieselToken.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeePercentagesProvider.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeeSplitter.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeesWithdrawer.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolIdRegistry.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IReaperTokenVault.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IShareToken.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ISilo.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IStaticATokenLM.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ITetuSmartVault.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ITetuStrategy.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IUnbuttonToken.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IYearnTokenVault.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IstETH.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IwstETH.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IAsset.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IAuthorizer.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IBasePool.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IBasicAuthorizer.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IFlashLoanRecipient.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IGeneralPool.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IMinimalSwapInfoPool.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IPoolSwapStructs.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IProtocolFeesCollector.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IVault.sol create mode 100644 foundry/lib/balancer-labs/v2-interfaces/package.json create mode 100644 foundry/src/executors/BalancerV2Executor.sol diff --git a/cache/solidity-files-cache.json b/cache/solidity-files-cache.json new file mode 100644 index 0000000..6e6ec61 --- /dev/null +++ b/cache/solidity-files-cache.json @@ -0,0 +1 @@ +{"_format":"","paths":{"artifacts":"out","build_infos":"out/build-info","sources":"src","tests":"test","scripts":"script","libraries":["lib"]},"files":{"test/TychoRouter.t.sol":{"lastModificationDate":1737991455132,"contentHash":"7215ee9c7d9dc229d2921a40e899ec5f","sourceName":"test/TychoRouter.t.sol","imports":[],"versionRequirement":null,"artifacts":{},"seenByCompiler":true}},"builds":[],"profiles":{"default":{"solc":{"optimizer":{"enabled":false,"runs":200},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"outputSelection":{"*":{"*":["abi","evm.bytecode.object","evm.bytecode.sourceMap","evm.bytecode.linkReferences","evm.deployedBytecode.object","evm.deployedBytecode.sourceMap","evm.deployedBytecode.linkReferences","evm.deployedBytecode.immutableReferences","evm.methodIdentifiers","metadata"]}},"evmVersion":"cancun","viaIR":false,"libraries":{}},"vyper":{"evmVersion":"cancun","outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode"]}}}}}} \ No newline at end of file diff --git a/foundry/lib/balancer-labs/v2-interfaces/CHANGELOG.md b/foundry/lib/balancer-labs/v2-interfaces/CHANGELOG.md new file mode 100644 index 0000000..2343f27 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/CHANGELOG.md @@ -0,0 +1,57 @@ +# Changelog + +## 0.4.0 (20223-03-15) + +- Added `IERC4626`. +- Added `IChildChainGauge`. +- Added `ILMGetters`. + +### Breaking changes + +- Removed `IBaseGaugeFactory`. +- Refactor: renamed `IBalancerMinter` to `IMainnetBalancerMinter`. + - `IMainnetBalancerMinter` now implements reduced version of previous `IBalancerMinter` and `ILMGetters`. + +## 0.3.0 (20223-02-08) + +### New Features + +- Added `checkpointGaugesOfTypeAboveRelativeWeight` to `IL2GaugeCheckpointer`. +- Added `IComposableStablePoolRates`. +- Added `IProtocolFeeCache`. +- Added `setTargets` and `setSwapFeePercentage` to `ILinearPool`. + +### Breaking changes + +- `IL2GaugeCheckpointer`: `getGaugeAt` renamed to `getGaugeAtIndex`. + +## 0.2.1 (2022-12-12) + +### Misc + +- Added examples to readme. + +## 0.2.0 (2022-12-01) + +### New Interfaces + +- Added `IProtocolFeeSplitter`. +- Added `IL2GaugeCheckpointer`. +- Added `IAuthorizerAdaptorEntrypoint`. +- Added `IRateProviderPool`. +- Added `IVersion`. +- Added `IFactoryCreatedPoolVersion`. +- Added `IRecoveryModeHelper`. + +### New Features + +- Extended the valid compiler version range to any of the 0.7.x and 0.8.x line. + +### Breaking Changes + +- Removed `IAssetManager`, which was unused. +- `IGaugeAdder`: authorizer adaptor getter replaced with authorizer adaptor entrypoint getter. + +## 0.1.0 (2022-10-25) + +- Initial release. diff --git a/foundry/lib/balancer-labs/v2-interfaces/README.md b/foundry/lib/balancer-labs/v2-interfaces/README.md new file mode 100644 index 0000000..f6eb9ad --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/README.md @@ -0,0 +1,139 @@ +# Balancer + +# Balancer V2 Interfaces + +[![NPM Package](https://img.shields.io/npm/v/@balancer-labs/v2-interfaces.svg)](https://www.npmjs.org/package/@balancer-labs/v2-interfaces) + +This package contains interfaces used in dependent packages, which makes building systems that interact with Balancer contracts simpler, as the implementation information is not included. + +## Overview + +### Installation + +```console +$ npm install @balancer-labs/v2-interfaces +``` + +### Usage + +This package can be used in multiple ways, including interacting with already deployed Pools, or performing local testing. It contains all interfaces used in the system, from the foundational [Vault](contracts/vault/IVault.sol) to very specific contracts (e.g., [Optimism Gas Limit Provider](contracts/liquidity-mining/IOptimismGasLimitProvider.sol)). + +The following are a couple code samples to help get you started. To get the address of deployed contracts in both production and test networks, see [`v2-deployments`](../deployments). + +Sample contract that joins a Balancer Pool: + +````solidity +pragma solidity ^0.7.0; + +// Import Vault interface, error messages, and library for decoding join/exit data. +import "@balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/BalancerErrors.sol"; +import "@balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20.sol"; +import "@balancer-labs/v2-interfaces/contracts/pool-weighted/WeightedPoolUserData.sol"; +import "@balancer-labs/v2-interfaces/contracts/vault/IVault.sol"; +import "@balancer-labs/v2-interfaces/contracts/vault/IAsset.sol"; + +// Import ERC20Helpers for `_asIAsset` +import "@balancer-labs/v2-solidity-utils/contracts/helpers/ERC20Helpers.sol"; + +contract JoinBalancerPool { + IVault private constant vault = "0xBA12222222228d8Ba445958a75a0704d566BF2C8"; + + function joinBalancerPool(bytes32 poolId, address sender, address recipient, uint256[] memory amountsIn, uint256 minBptAmountOut) external { + (IERC20[] memory tokens, , ) = vault.getPoolTokens(poolId); + + // Use BalancerErrors to validate input + _require(amountsIn.length == tokens.length, Errors.INPUT_LENGTH_MISMATCH); + + // Encode the userData for a multi-token join + bytes memory userData = abi.encode(WeightedPoolUserData.JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT, amountsIn, minBptAmountOut); + + IVault.JoinPoolRequest memory request = IVault.JoinPoolRequest({ + assets: _asIAsset(tokens), + maxAmountsIn: amountsIn, + userData: userData, + fromInternalBalance: false + }); + + // Call the Vault to join the pool + vault.joinPool(poolId, sender, recipient, request); + } + + ... +} +``` + +Sample contract that performs Internal Balance deposits: + +```solidity +pragma solidity ^0.7.0; + +import "@balancer-labs/v2-interfaces/contracts/vault/IVault.sol"; + +contract SimpleDepositor { + IVault private constant vault = "0xBA12222222228d8Ba445958a75a0704d566BF2C8"; + + function depositFunds( + IERC20[] memory tokens, + uint256[] memory amounts, + ) external { + IVault.UserBalanceOp[] memory ops = new IVault.UserBalanceOp[](tokens.length); + + for (uint256 i = 0; i < tokens.length; ++i) { + ops[i] = IVault.UserBalanceOp({ + kind: IVault.UserBalanceOpKind.DEPOSIT_INTERNAL, + asset: IAsset(tokens[i]), + amount: amounts[i], + sender: address(this), + recipient: address(this) + }); + } + + vault.manageUserBalance(ops); + } +} +```` + +Sample contract that performs Flash Loans: + +```solidity +pragma solidity ^0.7.0; + +import "@balancer-labs/v2-interfaces/contracts/vault/IVault.sol"; +import "@balancer-labs/v2-interfaces/contracts/vault/IFlashLoanRecipient.sol"; + +contract FlashLoanRecipient is IFlashLoanRecipient { + IVault private constant vault = "0xBA12222222228d8Ba445958a75a0704d566BF2C8"; + + function makeFlashLoan( + IERC20[] memory tokens, + uint256[] memory amounts, + bytes memory userData + ) external { + vault.flashLoan(this, tokens, amounts, userData); + } + + function receiveFlashLoan( + IERC20[] memory tokens, + uint256[] memory amounts, + uint256[] memory feeAmounts, + bytes memory userData + ) external override { + require(msg.sender == vault); + ... + } +} +``` + +### Notes + +In addition to interfaces, it also includes a small number of libraries that encapsulate enum types for particular pools (e.g., [StablePoolUserData](contracts/pool-stable/StablePoolUserData.sol), and functions for working with encoding and decoding `userData`. (See the `balancer-js` package for TypeScript versions of these utilities.) + +One of the most commonly included libraries is [BalancerErrors](contracts/solidity-utils/helpers/BalancerErrors.sol). To save bytecode, Balancer V2 does not use the standard `require(, 'error string')`. Instead, BalancerErrors defines `_require` and `_revert` functions. These take a numerical constant instead of a string, and return a fixed-length code, which can be converted to plain text using TypeScript utilities. + +## Licensing + +[GNU General Public License Version 3 (GPL v3)](../../LICENSE). + +``` + +``` diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/distributors/IDistributorCallback.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/distributors/IDistributorCallback.sol new file mode 100644 index 0000000..f656ebf --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/distributors/IDistributorCallback.sol @@ -0,0 +1,19 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface IDistributorCallback { + function distributorCallback(bytes calldata callbackData) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IArbitrumFeeProvider.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IArbitrumFeeProvider.sol new file mode 100644 index 0000000..951e4a1 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IArbitrumFeeProvider.sol @@ -0,0 +1,32 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface IArbitrumFeeProvider { + function getArbitrumFees() + external + view + returns ( + uint256 gasLimit, + uint256 gasPrice, + uint256 maxSubmissionCost + ); + + function setArbitrumFees( + uint64 gasLimit, + uint64 gasPrice, + uint64 maxSubmissionCost + ) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IAuthorizerAdaptor.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IAuthorizerAdaptor.sol new file mode 100644 index 0000000..25e4ffb --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IAuthorizerAdaptor.sol @@ -0,0 +1,38 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/helpers/IAuthentication.sol"; +import "../vault/IVault.sol"; + +interface IAuthorizerAdaptor is IAuthentication { + /** + * @notice Returns the Balancer Vault + */ + function getVault() external view returns (IVault); + + /** + * @notice Returns the Authorizer + */ + function getAuthorizer() external view returns (IAuthorizer); + + /** + * @notice Performs an arbitrary function call on a target contract, provided the caller is authorized to do so. + * @param target - Address of the contract to be called + * @param data - Calldata to be sent to the target contract + * @return The bytes encoded return value from the performed function call + */ + function performAction(address target, bytes calldata data) external payable returns (bytes memory); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IAuthorizerAdaptorEntrypoint.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IAuthorizerAdaptorEntrypoint.sol new file mode 100644 index 0000000..b77db5b --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IAuthorizerAdaptorEntrypoint.sol @@ -0,0 +1,27 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "./IAuthorizerAdaptor.sol"; + +/** + * @notice Interface for `AuthorizerAdaptorEntrypoint`. + */ +interface IAuthorizerAdaptorEntrypoint is IAuthorizerAdaptor { + /** + * @notice Returns the Authorizer Adaptor + */ + function getAuthorizerAdaptor() external view returns (IAuthorizerAdaptor); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerMinter.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerMinter.sol new file mode 100644 index 0000000..9e6fbca --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerMinter.sol @@ -0,0 +1,115 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +/** + * @dev Base minter interface, applicable to Mainnet minter or L2 pseudo minters. + */ +interface IBalancerMinter { + event Minted(address indexed recipient, address gauge, uint256 minted); + + /** + * @notice Returns the address of the Balancer Governance Token + */ + function getBalancerToken() external view returns (IERC20); + + /** + * @notice Mint everything which belongs to `msg.sender` and send to them + * @param gauge `LiquidityGauge` address to get mintable amount from + */ + function mint(address gauge) external returns (uint256); + + /** + * @notice Mint everything which belongs to `msg.sender` across multiple gauges + * @param gauges List of `LiquidityGauge` addresses + */ + function mintMany(address[] calldata gauges) external returns (uint256); + + /** + * @notice Mint tokens for `user` + * @dev Only possible when `msg.sender` has been approved by `user` to mint on their behalf + * @param gauge `LiquidityGauge` address to get mintable amount from + * @param user Address to mint to + */ + function mintFor(address gauge, address user) external returns (uint256); + + /** + * @notice Mint tokens for `user` across multiple gauges + * @dev Only possible when `msg.sender` has been approved by `user` to mint on their behalf + * @param gauges List of `LiquidityGauge` addresses + * @param user Address to mint to + */ + function mintManyFor(address[] calldata gauges, address user) external returns (uint256); + + /** + * @notice The total number of tokens minted for `user` from `gauge` + */ + function minted(address user, address gauge) external view returns (uint256); + + /** + * @notice Whether `minter` is approved to mint tokens for `user` + */ + function getMinterApproval(address minter, address user) external view returns (bool); + + /** + * @notice Set whether `minter` is approved to mint tokens on your behalf + */ + function setMinterApproval(address minter, bool approval) external; + + /** + * @notice Set whether `minter` is approved to mint tokens on behalf of `user`, who has signed a message authorizing + * them. + */ + function setMinterApprovalWithSignature( + address minter, + bool approval, + address user, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; + + // The below functions are near-duplicates of functions available above. + // They are included for ABI compatibility with snake_casing as used in vyper contracts. + // solhint-disable func-name-mixedcase + + /** + * @notice Whether `minter` is approved to mint tokens for `user` + */ + function allowed_to_mint_for(address minter, address user) external view returns (bool); + + /** + * @notice Mint everything which belongs to `msg.sender` across multiple gauges + * @dev This function is not recommended as `mintMany()` is more flexible and gas efficient + * @param gauges List of `LiquidityGauge` addresses + */ + function mint_many(address[8] calldata gauges) external; + + /** + * @notice Mint tokens for `user` + * @dev Only possible when `msg.sender` has been approved by `user` to mint on their behalf + * @param gauge `LiquidityGauge` address to get mintable amount from + * @param user Address to mint to + */ + function mint_for(address gauge, address user) external; + + /** + * @notice Toggle whether `minter` is approved to mint tokens for `user` + */ + function toggle_approve_mint(address minter) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerToken.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerToken.sol new file mode 100644 index 0000000..9a60577 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerToken.sol @@ -0,0 +1,44 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface IBalancerToken is IERC20 { + function mint(address to, uint256 amount) external; + + function getRoleMemberCount(bytes32 role) external view returns (uint256); + + function getRoleMember(bytes32 role, uint256 index) external view returns (address); + + function hasRole(bytes32 role, address account) external view returns (bool); + + function getRoleAdmin(bytes32 role) external view returns (bytes32); + + function grantRole(bytes32 role, address account) external; + + function revokeRole(bytes32 role, address account) external; + + // solhint-disable-next-line func-name-mixedcase + function DEFAULT_ADMIN_ROLE() external view returns (bytes32); + + // solhint-disable-next-line func-name-mixedcase + function MINTER_ROLE() external view returns (bytes32); + + // solhint-disable-next-line func-name-mixedcase + function SNAPSHOT_ROLE() external view returns (bytes32); + + function snapshot() external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerTokenAdmin.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerTokenAdmin.sol new file mode 100644 index 0000000..3334591 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerTokenAdmin.sol @@ -0,0 +1,45 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/helpers/IAuthentication.sol"; + +import "./IBalancerToken.sol"; + +interface IBalancerTokenAdmin is IAuthentication { + // solhint-disable func-name-mixedcase + function INITIAL_RATE() external view returns (uint256); + + function RATE_REDUCTION_TIME() external view returns (uint256); + + function RATE_REDUCTION_COEFFICIENT() external view returns (uint256); + + function RATE_DENOMINATOR() external view returns (uint256); + + // solhint-enable func-name-mixedcase + + /** + * @notice Returns the address of the Balancer Governance Token + */ + function getBalancerToken() external view returns (IBalancerToken); + + function activate() external; + + function rate() external view returns (uint256); + + function startEpochTimeWrite() external returns (uint256); + + function mint(address to, uint256 amount) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainGauge.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainGauge.sol new file mode 100644 index 0000000..d4df179 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainGauge.sol @@ -0,0 +1,51 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../pool-utils/IVersion.sol"; +import "./ILiquidityGaugeFactory.sol"; + +// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case +// naming convention. +// solhint-disable func-name-mixedcase +// solhint-disable func-param-name-mixedcase + +interface IChildChainGauge is IVersion { + /** + * @notice Proxy constructor. + * @param lpToken Pool allowed to stake in this gauge. + * @param version Gauge version string identifier. + */ + function initialize(address lpToken, string memory version) external; + + /** + * @notice Returns BAL liquidity emissions calculated during checkpoints for the given user. + * @param user User address. + * @return uint256 BAL amount to issue for the address. + */ + function integrate_fraction(address user) external view returns (uint256); + + /** + * @notice Records a checkpoint for a given user. + * @param user User address. + * @return bool Always true. + */ + function user_checkpoint(address user) external returns (bool); + + /** + * @notice Returns gauge factory address. + */ + function factory() external view returns (ILiquidityGaugeFactory); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainLiquidityGaugeFactory.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainLiquidityGaugeFactory.sol new file mode 100644 index 0000000..7f6fc89 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainLiquidityGaugeFactory.sol @@ -0,0 +1,60 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "./IChildChainStreamer.sol"; +import "./ILiquidityGauge.sol"; +import "./ILiquidityGaugeFactory.sol"; +import "./IRewardsOnlyGauge.sol"; + +interface IChildChainLiquidityGaugeFactory is ILiquidityGaugeFactory { + event RewardsOnlyGaugeCreated(address indexed gauge, address indexed pool, address streamer); + + /** + * @notice Returns the address of the implementation used for gauge deployments. + */ + function getGaugeImplementation() external view returns (ILiquidityGauge); + + /** + * @notice Returns the address of the implementation used for streamer deployments. + */ + function getChildChainStreamerImplementation() external view returns (IChildChainStreamer); + + /** + * @notice Returns the address of the gauge belonging to `pool`. + */ + function getPoolGauge(address pool) external view returns (ILiquidityGauge); + + /** + * @notice Returns the address of the streamer belonging to `gauge`. + */ + function getGaugeStreamer(address gauge) external view returns (address); + + /** + * @notice Returns true if `streamer` was created by this factory. + */ + function isStreamerFromFactory(address streamer) external view returns (bool); + + /** + * @notice Returns the address of the pool which `gauge` belongs. + */ + function getGaugePool(address gauge) external view returns (IERC20); + + /** + * @notice Returns the address of the streamer belonging to `pool`'s gauge. + */ + function getPoolStreamer(address pool) external view returns (address); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainStreamer.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainStreamer.sol new file mode 100644 index 0000000..93f8f25 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IChildChainStreamer.sol @@ -0,0 +1,35 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case +// naming convention. +// solhint-disable func-name-mixedcase + +interface IChildChainStreamer { + function initialize(address gauge) external; + + function get_reward() external; + + function reward_tokens(uint256 index) external view returns (IERC20); + + function add_reward( + IERC20 rewardToken, + address distributor, + uint256 duration + ) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IFeeDistributor.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IFeeDistributor.sol new file mode 100644 index 0000000..42e0a6a --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IFeeDistributor.sol @@ -0,0 +1,168 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +import "./IVotingEscrow.sol"; + +/** + * @title Fee Distributor + * @notice Distributes any tokens transferred to the contract (e.g. Protocol fees and any BAL emissions) among veBAL + * holders proportionally based on a snapshot of the week at which the tokens are sent to the FeeDistributor contract. + * @dev Supports distributing arbitrarily many different tokens. In order to start distributing a new token to veBAL + * holders simply transfer the tokens to the `FeeDistributor` contract and then call `checkpointToken`. + */ +interface IFeeDistributor { + event TokenCheckpointed(IERC20 token, uint256 amount, uint256 lastCheckpointTimestamp); + event TokensClaimed(address user, IERC20 token, uint256 amount, uint256 userTokenTimeCursor); + + /** + * @notice Returns the VotingEscrow (veBAL) token contract + */ + function getVotingEscrow() external view returns (IVotingEscrow); + + /** + * @notice Returns the global time cursor representing the most earliest uncheckpointed week. + */ + function getTimeCursor() external view returns (uint256); + + /** + * @notice Returns the user-level time cursor representing the most earliest uncheckpointed week. + * @param user - The address of the user to query. + */ + function getUserTimeCursor(address user) external view returns (uint256); + + /** + * @notice Returns the token-level time cursor storing the timestamp at up to which tokens have been distributed. + * @param token - The ERC20 token address to query. + */ + function getTokenTimeCursor(IERC20 token) external view returns (uint256); + + /** + * @notice Returns the user-level time cursor storing the timestamp of the latest token distribution claimed. + * @param user - The address of the user to query. + * @param token - The ERC20 token address to query. + */ + function getUserTokenTimeCursor(address user, IERC20 token) external view returns (uint256); + + /** + * @notice Returns the user's cached balance of veBAL as of the provided timestamp. + * @dev Only timestamps which fall on Thursdays 00:00:00 UTC will return correct values. + * This function requires `user` to have been checkpointed past `timestamp` so that their balance is cached. + * @param user - The address of the user of which to read the cached balance of. + * @param timestamp - The timestamp at which to read the `user`'s cached balance at. + */ + function getUserBalanceAtTimestamp(address user, uint256 timestamp) external view returns (uint256); + + /** + * @notice Returns the cached total supply of veBAL as of the provided timestamp. + * @dev Only timestamps which fall on Thursdays 00:00:00 UTC will return correct values. + * This function requires the contract to have been checkpointed past `timestamp` so that the supply is cached. + * @param timestamp - The timestamp at which to read the cached total supply at. + */ + function getTotalSupplyAtTimestamp(uint256 timestamp) external view returns (uint256); + + /** + * @notice Returns the FeeDistributor's cached balance of `token`. + */ + function getTokenLastBalance(IERC20 token) external view returns (uint256); + + /** + * @notice Returns the amount of `token` which the FeeDistributor received in the week beginning at `timestamp`. + * @param token - The ERC20 token address to query. + * @param timestamp - The timestamp corresponding to the beginning of the week of interest. + */ + function getTokensDistributedInWeek(IERC20 token, uint256 timestamp) external view returns (uint256); + + // Depositing + + /** + * @notice Deposits tokens to be distributed in the current week. + * @dev Sending tokens directly to the FeeDistributor instead of using `depositTokens` may result in tokens being + * retroactively distributed to past weeks, or for the distribution to carry over to future weeks. + * + * If for some reason `depositTokens` cannot be called, in order to ensure that all tokens are correctly distributed + * manually call `checkpointToken` before and after the token transfer. + * @param token - The ERC20 token address to distribute. + * @param amount - The amount of tokens to deposit. + */ + function depositToken(IERC20 token, uint256 amount) external; + + /** + * @notice Deposits tokens to be distributed in the current week. + * @dev A version of `depositToken` which supports depositing multiple `tokens` at once. + * See `depositToken` for more details. + * @param tokens - An array of ERC20 token addresses to distribute. + * @param amounts - An array of token amounts to deposit. + */ + function depositTokens(IERC20[] calldata tokens, uint256[] calldata amounts) external; + + // Checkpointing + + /** + * @notice Caches the total supply of veBAL at the beginning of each week. + * This function will be called automatically before claiming tokens to ensure the contract is properly updated. + */ + function checkpoint() external; + + /** + * @notice Caches the user's balance of veBAL at the beginning of each week. + * This function will be called automatically before claiming tokens to ensure the contract is properly updated. + * @param user - The address of the user to be checkpointed. + */ + function checkpointUser(address user) external; + + /** + * @notice Assigns any newly-received tokens held by the FeeDistributor to weekly distributions. + * @dev Any `token` balance held by the FeeDistributor above that which is returned by `getTokenLastBalance` + * will be distributed evenly across the time period since `token` was last checkpointed. + * + * This function will be called automatically before claiming tokens to ensure the contract is properly updated. + * @param token - The ERC20 token address to be checkpointed. + */ + function checkpointToken(IERC20 token) external; + + /** + * @notice Assigns any newly-received tokens held by the FeeDistributor to weekly distributions. + * @dev A version of `checkpointToken` which supports checkpointing multiple tokens. + * See `checkpointToken` for more details. + * @param tokens - An array of ERC20 token addresses to be checkpointed. + */ + function checkpointTokens(IERC20[] calldata tokens) external; + + // Claiming + + /** + * @notice Claims all pending distributions of the provided token for a user. + * @dev It's not necessary to explicitly checkpoint before calling this function, it will ensure the FeeDistributor + * is up to date before calculating the amount of tokens to be claimed. + * @param user - The user on behalf of which to claim. + * @param token - The ERC20 token address to be claimed. + * @return The amount of `token` sent to `user` as a result of claiming. + */ + function claimToken(address user, IERC20 token) external returns (uint256); + + /** + * @notice Claims a number of tokens on behalf of a user. + * @dev A version of `claimToken` which supports claiming multiple `tokens` on behalf of `user`. + * See `claimToken` for more details. + * @param user - The user on behalf of which to claim. + * @param tokens - An array of ERC20 token addresses to be claimed. + * @return An array of the amounts of each token in `tokens` sent to `user` as a result of claiming. + */ + function claimTokens(address user, IERC20[] calldata tokens) external returns (uint256[] memory); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeAdder.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeAdder.sol new file mode 100644 index 0000000..5966841 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeAdder.sol @@ -0,0 +1,97 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "./IAuthorizerAdaptorEntrypoint.sol"; +import "./IGaugeController.sol"; +import "./ILiquidityGauge.sol"; +import "./ILiquidityGaugeFactory.sol"; +import "./IStakingLiquidityGauge.sol"; + +interface IGaugeAdder is IAuthentication { + enum GaugeType { LiquidityMiningCommittee, veBAL, Ethereum, Polygon, Arbitrum, Optimism, Gnosis, ZKSync } + + event GaugeFactoryAdded(GaugeType indexed gaugeType, ILiquidityGaugeFactory gaugeFactory); + + /** + * @notice Returns the address of the Authorizer adaptor entrypoint contract. + */ + function getAuthorizerAdaptorEntrypoint() external view returns (IAuthorizerAdaptorEntrypoint); + + /** + * @notice Returns the address of the Gauge Controller + */ + function getGaugeController() external view returns (IGaugeController); + + /** + * @notice Returns the `index`'th factory for gauge type `gaugeType` + */ + function getFactoryForGaugeType(GaugeType gaugeType, uint256 index) external view returns (address); + + /** + * @notice Returns the number of factories for gauge type `gaugeType` + */ + function getFactoryForGaugeTypeCount(GaugeType gaugeType) external view returns (uint256); + + /** + * @notice Returns whether `gauge` has been deployed by one of the listed factories for the gauge type `gaugeType` + */ + function isGaugeFromValidFactory(address gauge, GaugeType gaugeType) external view returns (bool); + + /** + * @notice Adds a new gauge to the GaugeController for the "Ethereum" type. + */ + function addEthereumGauge(IStakingLiquidityGauge gauge) external; + + /** + * @notice Adds a new gauge to the GaugeController for the "Polygon" type. + * This function must be called with the address of the *root* gauge which is deployed on Ethereum mainnet. + * It should not be called with the address of the gauge which is deployed on Polygon + */ + function addPolygonGauge(address rootGauge) external; + + /** + * @notice Adds a new gauge to the GaugeController for the "Arbitrum" type. + * This function must be called with the address of the *root* gauge which is deployed on Ethereum mainnet. + * It should not be called with the address of the gauge which is deployed on Arbitrum + */ + function addArbitrumGauge(address rootGauge) external; + + /** + * @notice Adds a new gauge to the GaugeController for the "Optimism" type. + * This function must be called with the address of the *root* gauge which is deployed on Ethereum mainnet. + * It should not be called with the address of the gauge which is deployed on Optimism. + */ + function addOptimismGauge(address rootGauge) external; + + /** + * @notice Adds a new gauge to the GaugeController for the "Gnosis" type. + * This function must be called with the address of the *root* gauge which is deployed on Ethereum mainnet. + * It should not be called with the address of the gauge which is deployed on Gnosis Chain. + */ + function addGnosisGauge(address rootGauge) external; + + /** + * @notice Adds a new gauge to the GaugeController for the "ZKSync" type. + * This function must be called with the address of the *root* gauge which is deployed on Ethereum mainnet. + * It should not be called with the address of the gauge which is deployed on ZKSync. + */ + function addZKSyncGauge(address rootGauge) external; + + /** + * @notice Adds `factory` as an allowlisted factory contract for gauges with type `gaugeType`. + */ + function addGaugeFactory(ILiquidityGaugeFactory factory, GaugeType gaugeType) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeController.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeController.sol new file mode 100644 index 0000000..88390fb --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeController.sol @@ -0,0 +1,48 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +import "./IAuthorizerAdaptor.sol"; +import "./IVotingEscrow.sol"; + +// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case +// naming convention. +// solhint-disable func-name-mixedcase + +interface IGaugeController { + function checkpoint_gauge(address gauge) external; + + function gauge_relative_weight(address gauge, uint256 time) external view returns (uint256); + + function voting_escrow() external view returns (IVotingEscrow); + + function token() external view returns (IERC20); + + function add_type(string calldata name, uint256 weight) external; + + function change_type_weight(int128 typeId, uint256 weight) external; + + function add_gauge(address gauge, int128 gaugeType) external; + + function n_gauge_types() external view returns (int128); + + function gauge_types(address gauge) external view returns (int128); + + function admin() external view returns (IAuthorizerAdaptor); + + function gauge_exists(address gauge) external view returns (bool); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IL2GaugeCheckpointer.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IL2GaugeCheckpointer.sol new file mode 100644 index 0000000..11023cb --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IL2GaugeCheckpointer.sol @@ -0,0 +1,109 @@ +// 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 . + +pragma solidity ^0.7.0; + +import "./IGaugeAdder.sol"; +import "./IStakelessGauge.sol"; + +/** + * @title L2 Gauge Checkpointer interface + * @notice Manages checkpoints for L2 gauges, allowing to perform mutiple checkpoints in a single call. + * @dev Supports Polygon, Arbitrum, Optimism, Gnosis and ZKSync stakeless root gauges. Gauges to be checkpointed need + * to be added to the controller beforehand. + */ +interface IL2GaugeCheckpointer { + /** + * @dev Emitted when a gauge is added to the checkpointer. + */ + event GaugeAdded(IGaugeAdder.GaugeType indexed gaugeType, IStakelessGauge indexed gauge); + + /** + * @dev Emitted when a gauge is removed from the checkpointer. + */ + event GaugeRemoved(IGaugeAdder.GaugeType indexed gaugeType, IStakelessGauge indexed gauge); + + /** + * @dev Adds an array of gauges from the given type. + * Gauges added will be considered when performing checkpoints. + * The gauges to add should meet the following preconditions: + * - They must have been created in a valid GaugeFactory, according to GaugeAdder#isGaugeFromValidFactory. + * - They must exist in the GaugeController, according to GaugeController#gauge_exists. + * - They must not be killed. + * - They must not have been previously added to the checkpointer. + * @param gaugeType - Type of the gauge. + * @param gauges - Gauges to add. + */ + function addGauges(IGaugeAdder.GaugeType gaugeType, IStakelessGauge[] calldata gauges) external; + + /** + * @dev Removes an array of gauges from the given type. + * Removed gauges will not be considered when performing checkpoints. To remove gauges: + * - They must be killed. + * - They must have been previously added to the checkpointer. + * @param gaugeType - Type of the gauge. + * @param gauges - Gauges to remove. + */ + function removeGauges(IGaugeAdder.GaugeType gaugeType, IStakelessGauge[] calldata gauges) external; + + /** + * @dev Returns true if the given gauge was added for the given type; false otherwise. + * @param gaugeType - Type of the gauge. + * @param gauge - Gauge to check. + */ + function hasGauge(IGaugeAdder.GaugeType gaugeType, IStakelessGauge gauge) external view returns (bool); + + /** + * @dev Returns the amount of added gauges for a given type. + * @param gaugeType - Type of the gauge. + */ + function getTotalGauges(IGaugeAdder.GaugeType gaugeType) external view returns (uint256); + + /** + * @dev Returns the gauge of a given type at the given index. + * Reverts if the index is greater than or equal to the amount of added gauges for the given type. + * @param gaugeType - Type of the gauge. + * @param index - Index of the added gauge. + */ + function getGaugeAtIndex(IGaugeAdder.GaugeType gaugeType, uint256 index) external view returns (IStakelessGauge); + + /** + * @dev Performs a checkpoint for all added gauges above the given relative weight threshold. + * Reverts if the ETH sent in the call is not enough to cover bridge costs. + * @param minRelativeWeight - Threshold to filter out gauges below it. + */ + function checkpointGaugesAboveRelativeWeight(uint256 minRelativeWeight) external payable; + + /** + * @dev Performs a checkpoint for all added gauges of a given type above the given relative weight threshold. + * Reverts if the ETH sent in the call is not enough to cover bridge costs. + * @param gaugeType - Type of the gauge. + * @param minRelativeWeight - Threshold to filter out gauges below it. + */ + function checkpointGaugesOfTypeAboveRelativeWeight(IGaugeAdder.GaugeType gaugeType, uint256 minRelativeWeight) + external + payable; + + /** + * @dev Returns the ETH cost to checkpoint all gauges for a given minimum relative weight. + * A lower minimum relative weight might return higher costs, since more gauges could potentially be included + * in the checkpoint. + */ + function getTotalBridgeCost(uint256 minRelativeWeight) external view returns (uint256); + + /** + * @dev Returns true if gauge type is Polygon, Arbitrum, Optimism, Gnosis or ZKSync; false otherwise. + */ + function isSupportedGaugeType(IGaugeAdder.GaugeType gaugeType) external pure returns (bool); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILMGetters.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILMGetters.sol new file mode 100644 index 0000000..de8505a --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILMGetters.sol @@ -0,0 +1,30 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "./IBalancerTokenAdmin.sol"; +import "./IGaugeController.sol"; + +interface ILMGetters { + /** + * @notice Returns the address of the Balancer Token Admin contract + */ + function getBalancerTokenAdmin() external view returns (IBalancerTokenAdmin); + + /** + * @notice Returns the address of the Gauge Controller + */ + function getGaugeController() external view returns (IGaugeController); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGauge.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGauge.sol new file mode 100644 index 0000000..c6323ee --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGauge.sol @@ -0,0 +1,72 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case +// naming convention. +// solhint-disable func-name-mixedcase +// solhint-disable func-param-name-mixedcase + +interface ILiquidityGauge { + // solhint-disable-next-line var-name-mixedcase + event RelativeWeightCapChanged(uint256 new_relative_weight_cap); + + /** + * @notice Returns BAL liquidity emissions calculated during checkpoints for the given user. + * @param user User address. + * @return uint256 BAL amount to issue for the address. + */ + function integrate_fraction(address user) external view returns (uint256); + + /** + * @notice Record a checkpoint for a given user. + * @param user User address. + * @return bool Always true. + */ + function user_checkpoint(address user) external returns (bool); + + /** + * @notice Returns true if gauge is killed; false otherwise. + */ + function is_killed() external view returns (bool); + + /** + * @notice Kills the gauge so it cannot mint BAL. + */ + function killGauge() external; + + /** + * @notice Unkills the gauge so it can mint BAL again. + */ + function unkillGauge() external; + + /** + * @notice Sets a new relative weight cap for the gauge. + * The value shall be normalized to 1e18, and not greater than MAX_RELATIVE_WEIGHT_CAP. + * @param relativeWeightCap New relative weight cap. + */ + function setRelativeWeightCap(uint256 relativeWeightCap) external; + + /** + * @notice Gets the relative weight cap for the gauge. + */ + function getRelativeWeightCap() external view returns (uint256); + + /** + * @notice Returns the gauge's relative weight for a given time, capped to its relative weight cap attribute. + * @param time Timestamp in the past or present. + */ + function getCappedRelativeWeight(uint256 time) external view returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGaugeFactory.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGaugeFactory.sol new file mode 100644 index 0000000..c7698e5 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGaugeFactory.sol @@ -0,0 +1,25 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "./ILiquidityGauge.sol"; + +interface ILiquidityGaugeFactory { + /** + * @notice Returns true if `gauge` was created by this factory. + */ + function isGaugeFromFactory(address gauge) external view returns (bool); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IMainnetBalancerMinter.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IMainnetBalancerMinter.sol new file mode 100644 index 0000000..9f855a1 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IMainnetBalancerMinter.sol @@ -0,0 +1,25 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "./IBalancerMinter.sol"; +import "./ILMGetters.sol"; + +/** + * @dev Full L1 Balancer minter interface with singleton getters. + */ +interface IMainnetBalancerMinter is IBalancerMinter, ILMGetters { + // solhint-disable-previous-line no-empty-blocks +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IOptimismGasLimitProvider.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IOptimismGasLimitProvider.sol new file mode 100644 index 0000000..a165d93 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IOptimismGasLimitProvider.sol @@ -0,0 +1,21 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface IOptimismGasLimitProvider { + function getOptimismGasLimit() external view returns (uint32 gasLimit); + + function setOptimismGasLimit(uint32 gasLimit) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IRewardTokenDistributor.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IRewardTokenDistributor.sol new file mode 100644 index 0000000..0b0ed3a --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IRewardTokenDistributor.sol @@ -0,0 +1,49 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case +// naming convention. +// solhint-disable func-name-mixedcase, var-name-mixedcase + +interface IRewardTokenDistributor { + struct Reward { + IERC20 token; + address distributor; + uint256 period_finish; + uint256 rate; + uint256 last_update; + uint256 integral; + } + + function reward_tokens(uint256 index) external view returns (IERC20); + + function reward_data(IERC20 token) external view returns (Reward memory); + + function claim_rewards(address user) external; + + function add_reward(IERC20 rewardToken, address distributor) external; + + function set_reward_distributor(IERC20 rewardToken, address distributor) external; + + function deposit_reward_token(IERC20 rewardToken, uint256 amount) external; + + function claimable_reward(address rewardToken, address user) external view returns (uint256); + + function claimable_reward_write(address rewardToken, address user) external returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IRewardsOnlyGauge.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IRewardsOnlyGauge.sol new file mode 100644 index 0000000..0ff1cce --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IRewardsOnlyGauge.sol @@ -0,0 +1,43 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "./IChildChainStreamer.sol"; +import "./IRewardTokenDistributor.sol"; + +// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case +// naming convention. +// solhint-disable func-name-mixedcase + +interface IRewardsOnlyGauge is IRewardTokenDistributor { + function initialize( + address pool, + address streamer, + bytes32 claimSignature + ) external; + + // solhint-disable-next-line func-name-mixedcase + function lp_token() external view returns (IERC20); + + function reward_contract() external view returns (IChildChainStreamer); + + function set_rewards( + address childChainStreamer, + bytes32 claimSig, + address[8] calldata rewardTokens + ) external; + + function last_claim() external view returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ISmartWalletChecker.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ISmartWalletChecker.sol new file mode 100644 index 0000000..f7d6d8c --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/ISmartWalletChecker.sol @@ -0,0 +1,19 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface ISmartWalletChecker { + function check(address contractAddress) external view returns (bool); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakelessGauge.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakelessGauge.sol new file mode 100644 index 0000000..a63f126 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakelessGauge.sol @@ -0,0 +1,23 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "./ILiquidityGauge.sol"; + +interface IStakelessGauge is ILiquidityGauge { + function checkpoint() external payable returns (bool); + + function getRecipient() external view returns (address); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakingLiquidityGauge.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakingLiquidityGauge.sol new file mode 100644 index 0000000..eb801e9 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakingLiquidityGauge.sol @@ -0,0 +1,35 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +import "./ILiquidityGauge.sol"; +import "./IRewardTokenDistributor.sol"; + +// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case +// naming convention. +// solhint-disable func-name-mixedcase, var-name-mixedcase + +interface IStakingLiquidityGauge is IRewardTokenDistributor, ILiquidityGauge, IERC20 { + function initialize(address lpToken, uint256 relativeWeightCap) external; + + function lp_token() external view returns (IERC20); + + function deposit(uint256 value, address recipient) external; + + function withdraw(uint256 value) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IVeDelegation.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IVeDelegation.sol new file mode 100644 index 0000000..8b9e40c --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IVeDelegation.sol @@ -0,0 +1,26 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case +// naming convention. +// solhint-disable func-name-mixedcase + +interface IVeDelegation { + // solhint-disable-next-line func-name-mixedcase + function adjusted_balance_of(address user) external view returns (uint256); + + function totalSupply() external view returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IVotingEscrow.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IVotingEscrow.sol new file mode 100644 index 0000000..5a8ac65 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/liquidity-mining/IVotingEscrow.sol @@ -0,0 +1,51 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "./IAuthorizerAdaptor.sol"; + +// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case +// naming convention. +// solhint-disable func-name-mixedcase + +interface IVotingEscrow { + struct Point { + int128 bias; + int128 slope; // - dweight / dt + uint256 ts; + uint256 blk; // block + } + + function epoch() external view returns (uint256); + + function totalSupply(uint256 timestamp) external view returns (uint256); + + function user_point_epoch(address user) external view returns (uint256); + + function point_history(uint256 timestamp) external view returns (Point memory); + + function user_point_history(address user, uint256 timestamp) external view returns (Point memory); + + function checkpoint() external; + + function admin() external view returns (IAuthorizerAdaptor); + + function smart_wallet_checker() external view returns (address); + + function commit_smart_wallet_checker(address newSmartWalletChecker) external; + + function apply_smart_wallet_checker() external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-linear/IERC4626.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-linear/IERC4626.sol new file mode 100644 index 0000000..107bc0d --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-linear/IERC4626.sol @@ -0,0 +1,67 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @title IERC4626, to support the yield-bearing token standard. + * @notice Used for ERC4626-derived Linear Pools. + * @dev There is another version of this in /solidity-utils/misc, used in standalone-utils tests. + * This version has an additional `previewMint` function, and is used in tests of derived Linear Pools. + */ +interface IERC4626 { + /** + * @dev Mints `shares` Vault shares to `receiver` by depositing exactly `amount` of underlying tokens. + */ + function deposit(uint256 assets, address receiver) external returns (uint256 shares); + + /** + * @dev Burns exactly `shares` from `owner` and sends `assets` of underlying tokens to `receiver`. + */ + function redeem( + uint256 shares, + address receiver, + address owner + ) external returns (uint256 assets); + + /** + * @dev The address of the underlying token that the Vault uses for accounting, depositing, and withdrawing. + */ + function asset() external view returns (address); + + /** + * @dev Total amount of the underlying asset that is “managed” by Vault. + */ + function totalAssets() external view returns (uint256); + + /** + * @dev The amount of `assets` that the Vault would exchange for the amount + * of `shares` provided, in an ideal scenario where all the conditions are met. + */ + function convertToAssets(uint256 shares) external view returns (uint256 assets); + + /** + * @dev The amount of `shares` that the Vault would exchange for the amount + * of `assets` provided, in an ideal scenario where all the conditions are met. + */ + function convertToShares(uint256 assets) external view returns (uint256 shares); + + /** + * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, + * given current on-chain conditions. MUST return as close to and no fewer than the exact amount of assets that + * would be deposited in a mint call in the same transaction. I.e. mint should return the same or fewer assets + * as previewMint if called in the same transaction. + */ + function previewMint(uint256 shares) external view returns (uint256 assets); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-linear/ILinearPool.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-linear/ILinearPool.sol new file mode 100644 index 0000000..bc06538 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-linear/ILinearPool.sol @@ -0,0 +1,84 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../solidity-utils/openzeppelin/IERC20.sol"; +import "../vault/IBasePool.sol"; + +interface ILinearPool is IBasePool { + /** + * @dev Returns the Pool's main token. + */ + function getMainToken() external view returns (IERC20); + + /** + * @dev Returns the Pool's wrapped token. + */ + function getWrappedToken() external view returns (IERC20); + + /** + * @dev Returns the index of the Pool's BPT in the Pool tokens array (as returned by IVault.getPoolTokens). + */ + function getBptIndex() external view returns (uint256); + + /** + * @dev Returns the index of the Pool's main token in the Pool tokens array (as returned by IVault.getPoolTokens). + */ + function getMainIndex() external view returns (uint256); + + /** + * @dev Returns the index of the Pool's wrapped token in the Pool tokens array (as returned by + * IVault.getPoolTokens). + */ + function getWrappedIndex() external view returns (uint256); + + /** + * @dev Returns the Pool's targets for the main token balance. These values have had the main token's scaling + * factor applied to them. + */ + function getTargets() external view returns (uint256 lowerTarget, uint256 upperTarget); + + /** + * @notice Set the lower and upper bounds of the zero-fee trading range for the main token balance. + * @dev For a new target range to be valid: + * - the current balance must be between the current targets (meaning no fees are currently pending) + * - the current balance must be between the new targets (meaning setting them does not create pending fees) + * + * The first requirement could be relaxed, as the LPs actually benefit from the pending fees not being paid out, + * but being stricter makes analysis easier at little expense. + * + * This is a permissioned function, reserved for the pool owner. It will revert when called within a Vault context + * (i.e. in the middle of a join or an exit). + * + * 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. + * + * See https://forum.balancer.fi/t/reentrancy-vulnerability-scope-expanded/4345 for reference. + */ + function setTargets(uint256 newLowerTarget, uint256 newUpperTarget) external; + + /** + * @notice Set the swap fee percentage. + * @dev This is a permissioned function, reserved for the pool owner. It will revert when called within a Vault + * context (i.e. in the middle of a join or an exit). + * + * 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. + * + * See https://forum.balancer.fi/t/reentrancy-vulnerability-scope-expanded/4345 for reference. + */ + function setSwapFeePercentage(uint256 swapFeePercentage) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-stable/IComposableStablePoolRates.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-stable/IComposableStablePoolRates.sol new file mode 100644 index 0000000..b1a5d30 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-stable/IComposableStablePoolRates.sol @@ -0,0 +1,32 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface IComposableStablePoolRates { + /** + * @dev Forces a rate cache hit for a token. + * It will revert if the requested token does not have an associated rate provider. + */ + function updateTokenRateCache(IERC20 token) external; + + /** + * @dev Sets a new duration for a token rate cache. It reverts if there was no rate provider set initially. + * Note this function also updates the current cached value. + * @param duration Number of seconds until the current token rate is fetched again. + */ + function setTokenRateCacheDuration(IERC20 token, uint256 duration) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-stable/StablePoolUserData.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-stable/StablePoolUserData.sol new file mode 100644 index 0000000..3c66a1f --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-stable/StablePoolUserData.sol @@ -0,0 +1,68 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +library StablePoolUserData { + enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT, TOKEN_IN_FOR_EXACT_BPT_OUT, ALL_TOKENS_IN_FOR_EXACT_BPT_OUT } + enum ExitKind { EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, BPT_IN_FOR_EXACT_TOKENS_OUT, EXACT_BPT_IN_FOR_ALL_TOKENS_OUT } + + function joinKind(bytes memory self) internal pure returns (JoinKind) { + return abi.decode(self, (JoinKind)); + } + + function exitKind(bytes memory self) internal pure returns (ExitKind) { + return abi.decode(self, (ExitKind)); + } + + // Joins + + function initialAmountsIn(bytes memory self) internal pure returns (uint256[] memory amountsIn) { + (, amountsIn) = abi.decode(self, (JoinKind, uint256[])); + } + + function exactTokensInForBptOut(bytes memory self) + internal + pure + returns (uint256[] memory amountsIn, uint256 minBPTAmountOut) + { + (, amountsIn, minBPTAmountOut) = abi.decode(self, (JoinKind, uint256[], uint256)); + } + + function tokenInForExactBptOut(bytes memory self) internal pure returns (uint256 bptAmountOut, uint256 tokenIndex) { + (, bptAmountOut, tokenIndex) = abi.decode(self, (JoinKind, uint256, uint256)); + } + + function allTokensInForExactBptOut(bytes memory self) internal pure returns (uint256 bptAmountOut) { + (, bptAmountOut) = abi.decode(self, (JoinKind, uint256)); + } + + // Exits + + function exactBptInForTokenOut(bytes memory self) internal pure returns (uint256 bptAmountIn, uint256 tokenIndex) { + (, bptAmountIn, tokenIndex) = abi.decode(self, (ExitKind, uint256, uint256)); + } + + function exactBptInForTokensOut(bytes memory self) internal pure returns (uint256 bptAmountIn) { + (, bptAmountIn) = abi.decode(self, (ExitKind, uint256)); + } + + function bptInForExactTokensOut(bytes memory self) + internal + pure + returns (uint256[] memory amountsOut, uint256 maxBPTAmountIn) + { + (, amountsOut, maxBPTAmountIn) = abi.decode(self, (ExitKind, uint256[], uint256)); + } +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/BasePoolUserData.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/BasePoolUserData.sol new file mode 100644 index 0000000..0703ac8 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/BasePoolUserData.sol @@ -0,0 +1,32 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +library BasePoolUserData { + // Special ExitKind for all pools, used in Recovery Mode. Use the max 8-bit value to prevent conflicts + // with future additions to the ExitKind enums (or any front-end code that maps to existing values) + uint8 public constant RECOVERY_MODE_EXIT_KIND = 255; + + // Return true if this is the special exit kind. + function isRecoveryModeExitKind(bytes memory self) internal pure returns (bool) { + // Check for the "no data" case, or abi.decode would revert + return self.length > 0 && abi.decode(self, (uint8)) == RECOVERY_MODE_EXIT_KIND; + } + + // Parse the bptAmountIn out of the userData + function recoveryModeExit(bytes memory self) internal pure returns (uint256 bptAmountIn) { + (, bptAmountIn) = abi.decode(self, (uint8, uint256)); + } +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IBasePoolController.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IBasePoolController.sol new file mode 100644 index 0000000..f752a82 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IBasePoolController.sol @@ -0,0 +1,19 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface IBasePoolController { + function initialize(address poolAddress) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IBasePoolFactory.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IBasePoolFactory.sol new file mode 100644 index 0000000..694485f --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IBasePoolFactory.sol @@ -0,0 +1,36 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../solidity-utils/helpers/IAuthentication.sol"; + +interface IBasePoolFactory is IAuthentication { + /** + * @dev Returns true if `pool` was created by this factory. + */ + function isPoolFromFactory(address pool) external view returns (bool); + + /** + * @dev Check whether the derived factory has been disabled. + */ + function isDisabled() external view returns (bool); + + /** + * @dev Disable the factory, preventing the creation of more pools. Already existing pools are unaffected. + * Once a factory is disabled, it cannot be re-enabled. + */ + function disable() external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IControlledPool.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IControlledPool.sol new file mode 100644 index 0000000..a03d277 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IControlledPool.sol @@ -0,0 +1,21 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface IControlledPool { + function setSwapFeePercentage(uint256 swapFeePercentage) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IFactoryCreatedPoolVersion.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IFactoryCreatedPoolVersion.sol new file mode 100644 index 0000000..62e4b24 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IFactoryCreatedPoolVersion.sol @@ -0,0 +1,28 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @notice Simple interface to retrieve the version of pools deployed by a pool factory. + */ +interface IFactoryCreatedPoolVersion { + /** + * @dev Returns a JSON representation of the deployed pool version containing name, version number and task ID. + * + * This is typically only useful in complex Pool deployment schemes, where multiple subsystems need to know about + * each other. Note that this value will only be updated at factory creation time. + */ + function getPoolVersion() external view returns (string memory); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/ILastCreatedPoolFactory.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/ILastCreatedPoolFactory.sol new file mode 100644 index 0000000..2ac07ed --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/ILastCreatedPoolFactory.sol @@ -0,0 +1,28 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "./IBasePoolFactory.sol"; + +interface ILastCreatedPoolFactory is IBasePoolFactory { + /** + * @dev Returns the address of the last Pool created by this factory. + * + * This is typically only useful in complex Pool deployment schemes, where multiple subsystems need to know about + * each other. Note that this value will only be updated once construction of the last created Pool finishes. + */ + function getLastCreatedPool() external view returns (address); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IManagedPool.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IManagedPool.sol new file mode 100644 index 0000000..3094888 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IManagedPool.sol @@ -0,0 +1,363 @@ +// 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 . + +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; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IPoolVersion.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IPoolVersion.sol new file mode 100644 index 0000000..56d3e4c --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IPoolVersion.sol @@ -0,0 +1,28 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @notice Simple interface to retrieve the version of pools deployed by a pool factory. + */ +interface IPoolVersion { + /** + * @dev Returns a JSON representation of the deployed pool version containing name, version number and task ID. + * + * This is typically only useful in complex Pool deployment schemes, where multiple subsystems need to know about + * each other. Note that this value will only be updated at factory creation time. + */ + function getPoolVersion() external view returns (string memory); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IProtocolFeeCache.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IProtocolFeeCache.sol new file mode 100644 index 0000000..887c840 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IProtocolFeeCache.sol @@ -0,0 +1,29 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface IProtocolFeeCache { + /** + * @notice Updates the cache to the latest value set by governance. + * @dev Can be called by anyone to update the cached fee percentages. + * + * 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 by a call to `ensureNotInVaultContext` in + * VaultReentrancyLib where overridden in `ProtocolFeeCache`, and so is safe to call on ManagedPool. + * + * See https://forum.balancer.fi/t/reentrancy-vulnerability-scope-expanded/4345 for reference. + */ + function updateProtocolFeePercentageCache() external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRateProvider.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRateProvider.sol new file mode 100644 index 0000000..86ba490 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRateProvider.sol @@ -0,0 +1,23 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface IRateProvider { + /** + * @dev Returns an 18 decimal fixed point number that is the exchange rate of the token to some other underlying + * token. The meaning of this rate depends on the context. + */ + function getRate() external view returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRateProviderPool.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRateProviderPool.sol new file mode 100644 index 0000000..c2c6124 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRateProviderPool.sol @@ -0,0 +1,28 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "./IRateProvider.sol"; + +/** + * @dev Interface for Pools that assign rate providers to their tokens. + */ +interface IRateProviderPool { + /** + * @dev Returns the rate provider for each of the Pool's tokens. A zero-address entry means there's no rate provider + * for that token. + */ + function getRateProviders() external view returns (IRateProvider[] memory); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRecoveryMode.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRecoveryMode.sol new file mode 100644 index 0000000..9590de2 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRecoveryMode.sol @@ -0,0 +1,41 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @dev Interface for the RecoveryMode module. + */ +interface IRecoveryMode { + /** + * @dev Emitted when the Recovery Mode status changes. + */ + event RecoveryModeStateChanged(bool enabled); + + /** + * @notice Enables Recovery Mode in the Pool, disabling protocol fee collection and allowing for safe proportional + * exits with low computational complexity and no dependencies. + */ + function enableRecoveryMode() external; + + /** + * @notice Disables Recovery Mode in the Pool, restoring protocol fee collection and disallowing proportional exits. + */ + function disableRecoveryMode() external; + + /** + * @notice Returns true if the Pool is in Recovery Mode. + */ + function inRecoveryMode() external view returns (bool); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRecoveryModeHelper.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRecoveryModeHelper.sol new file mode 100644 index 0000000..b948f13 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IRecoveryModeHelper.sol @@ -0,0 +1,52 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../vault/IVault.sol"; + +/** + * Interface for an auxiliary contract that computes Recovery Mode exits, removing logic from the core Pool contract + * that would otherwise take up a lot of bytecode size at the cost of some slight gas overhead. Since Recovery Mode + * exits are expected to be highly infrequent (and ideally never occur), this tradeoff makes sense. + */ +interface IRecoveryModeHelper { + /** + * @notice Returns the Balancer Vault + */ + function getVault() external view returns (IVault); + + /** + * @dev Computes a Recovery Mode Exit BPT and token amounts for a Pool. Only 'cash' balances are considered, to + * avoid scenarios where the last LPs to attempt to exit the Pool cannot do it because only 'managed' balance + * remains. + * + * The Pool is assumed to be a Composable Pool that uses ComposablePoolLib, meaning BPT will be its first token. It + * is also assumed that there is no 'managed' balance for BPT. + + * 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 `calcComposableRecoveryAmountsOut`. That will make the transaction revert in an unsafe + * context. + * + * (See `VaultReentrancyLib.ensureNotInVaultContext`). + */ + function calcComposableRecoveryAmountsOut( + bytes32 poolId, + bytes memory userData, + uint256 totalSupply + ) external view returns (uint256 bptAmountIn, uint256[] memory amountsOut); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IVersion.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IVersion.sol new file mode 100644 index 0000000..9079808 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-utils/IVersion.sol @@ -0,0 +1,25 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @notice Simple interface to retrieve the version of a deployed contract. + */ +interface IVersion { + /** + * @dev Returns a JSON representation of the contract version containing name, version number and task ID. + */ + function version() external view returns (string memory); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-weighted/IExternalWeightedMath.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-weighted/IExternalWeightedMath.sol new file mode 100644 index 0000000..f26b3ea --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-weighted/IExternalWeightedMath.sol @@ -0,0 +1,203 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @notice Interface for ExternalWeightedMath, a contract-wrapper for Weighted Math, Joins and Exits. + */ +interface IExternalWeightedMath { + /** + * @dev See `WeightedMath._calculateInvariant`. + */ + function calculateInvariant(uint256[] memory normalizedWeights, uint256[] memory balances) + external + pure + returns (uint256); + + /** + * @dev See `WeightedMath._calcOutGivenIn`. + */ + function calcOutGivenIn( + uint256 balanceIn, + uint256 weightIn, + uint256 balanceOut, + uint256 weightOut, + uint256 amountIn + ) external pure returns (uint256); + + /** + * @dev See `WeightedMath._calcInGivenOut`. + */ + function calcInGivenOut( + uint256 balanceIn, + uint256 weightIn, + uint256 balanceOut, + uint256 weightOut, + uint256 amountOut + ) external pure returns (uint256); + + /** + * @dev See `WeightedMath._calcBptOutGivenExactTokensIn`. + */ + function calcBptOutGivenExactTokensIn( + uint256[] memory balances, + uint256[] memory normalizedWeights, + uint256[] memory amountsIn, + uint256 bptTotalSupply, + uint256 swapFeePercentage + ) external pure returns (uint256); + + /** + * @dev See `WeightedMath._calcBptOutGivenExactTokenIn`. + */ + function calcBptOutGivenExactTokenIn( + uint256 balance, + uint256 normalizedWeight, + uint256 amountIn, + uint256 bptTotalSupply, + uint256 swapFeePercentage + ) external pure returns (uint256); + + /** + * @dev See `WeightedMath._calcTokenInGivenExactBptOut`. + */ + function calcTokenInGivenExactBptOut( + uint256 balance, + uint256 normalizedWeight, + uint256 bptAmountOut, + uint256 bptTotalSupply, + uint256 swapFeePercentage + ) external pure returns (uint256); + + /** + * @dev See `WeightedMath._calcAllTokensInGivenExactBptOut`. + */ + function calcAllTokensInGivenExactBptOut( + uint256[] memory balances, + uint256 bptAmountOut, + uint256 totalBPT + ) external pure returns (uint256[] memory); + + /** + * @dev See `WeightedMath._calcBptInGivenExactTokensOut`. + */ + function calcBptInGivenExactTokensOut( + uint256[] memory balances, + uint256[] memory normalizedWeights, + uint256[] memory amountsOut, + uint256 bptTotalSupply, + uint256 swapFeePercentage + ) external pure returns (uint256); + + /** + * @dev See `WeightedMath._calcBptInGivenExactTokenOut`. + */ + function calcBptInGivenExactTokenOut( + uint256 balance, + uint256 normalizedWeight, + uint256 amountOut, + uint256 bptTotalSupply, + uint256 swapFeePercentage + ) external pure returns (uint256); + + /** + * @dev See `WeightedMath._calcTokenOutGivenExactBptIn`. + */ + function calcTokenOutGivenExactBptIn( + uint256 balance, + uint256 normalizedWeight, + uint256 bptAmountIn, + uint256 bptTotalSupply, + uint256 swapFeePercentage + ) external pure returns (uint256); + + /** + * @dev See `WeightedMath._calcTokensOutGivenExactBptIn`. + */ + function calcTokensOutGivenExactBptIn( + uint256[] memory balances, + uint256 bptAmountIn, + uint256 totalBPT + ) external pure returns (uint256[] memory); + + /** + * @dev See `WeightedMath._calcBptOutAddToken`. + */ + function calcBptOutAddToken(uint256 totalSupply, uint256 normalizedWeight) external pure returns (uint256); + + /** + * @dev See `WeightedJoinsLib.joinExactTokensInForBPTOut`. + */ + function joinExactTokensInForBPTOut( + uint256[] memory balances, + uint256[] memory normalizedWeights, + uint256[] memory scalingFactors, + uint256 totalSupply, + uint256 swapFeePercentage, + bytes memory userData + ) external pure returns (uint256, uint256[] memory); + + /** + * @dev See `WeightedJoinsLib.joinTokenInForExactBPTOut`. + */ + function joinTokenInForExactBPTOut( + uint256[] memory balances, + uint256[] memory normalizedWeights, + uint256 totalSupply, + uint256 swapFeePercentage, + bytes memory userData + ) external pure returns (uint256, uint256[] memory); + + /** + * @dev See `WeightedJoinsLib.joinAllTokensInForExactBPTOut`. + */ + function joinAllTokensInForExactBPTOut( + uint256[] memory balances, + uint256 totalSupply, + bytes memory userData + ) external pure returns (uint256 bptAmountOut, uint256[] memory amountsIn); + + /** + * @dev See `WeightedExitsLib.exitExactBPTInForTokenOut`. + */ + function exitExactBPTInForTokenOut( + uint256[] memory balances, + uint256[] memory normalizedWeights, + uint256 totalSupply, + uint256 swapFeePercentage, + bytes memory userData + ) external pure returns (uint256, uint256[] memory); + + /** + * @dev See `WeightedExitsLib.exitExactBPTInForTokensOut`. + */ + function exitExactBPTInForTokensOut( + uint256[] memory balances, + uint256 totalSupply, + bytes memory userData + ) external pure returns (uint256 bptAmountIn, uint256[] memory amountsOut); + + /** + * @dev See `WeightedExitsLib.exitBPTInForExactTokensOut`. + */ + function exitBPTInForExactTokensOut( + uint256[] memory balances, + uint256[] memory normalizedWeights, + uint256[] memory scalingFactors, + uint256 totalSupply, + uint256 swapFeePercentage, + bytes memory userData + ) external pure returns (uint256, uint256[] memory); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-weighted/WeightedPoolUserData.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-weighted/WeightedPoolUserData.sol new file mode 100644 index 0000000..e192e5a --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/pool-weighted/WeightedPoolUserData.sol @@ -0,0 +1,71 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +library WeightedPoolUserData { + // In order to preserve backwards compatibility, make sure new join and exit kinds are added at the end of the enum. + enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT, TOKEN_IN_FOR_EXACT_BPT_OUT, ALL_TOKENS_IN_FOR_EXACT_BPT_OUT } + enum ExitKind { EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, EXACT_BPT_IN_FOR_TOKENS_OUT, BPT_IN_FOR_EXACT_TOKENS_OUT } + + function joinKind(bytes memory self) internal pure returns (JoinKind) { + return abi.decode(self, (JoinKind)); + } + + function exitKind(bytes memory self) internal pure returns (ExitKind) { + return abi.decode(self, (ExitKind)); + } + + // Joins + + function initialAmountsIn(bytes memory self) internal pure returns (uint256[] memory amountsIn) { + (, amountsIn) = abi.decode(self, (JoinKind, uint256[])); + } + + function exactTokensInForBptOut(bytes memory self) + internal + pure + returns (uint256[] memory amountsIn, uint256 minBPTAmountOut) + { + (, amountsIn, minBPTAmountOut) = abi.decode(self, (JoinKind, uint256[], uint256)); + } + + function tokenInForExactBptOut(bytes memory self) internal pure returns (uint256 bptAmountOut, uint256 tokenIndex) { + (, bptAmountOut, tokenIndex) = abi.decode(self, (JoinKind, uint256, uint256)); + } + + function allTokensInForExactBptOut(bytes memory self) internal pure returns (uint256 bptAmountOut) { + (, bptAmountOut) = abi.decode(self, (JoinKind, uint256)); + } + + // Exits + + function exactBptInForTokenOut(bytes memory self) internal pure returns (uint256 bptAmountIn, uint256 tokenIndex) { + (, bptAmountIn, tokenIndex) = abi.decode(self, (ExitKind, uint256, uint256)); + } + + function exactBptInForTokensOut(bytes memory self) internal pure returns (uint256 bptAmountIn) { + (, bptAmountIn) = abi.decode(self, (ExitKind, uint256)); + } + + function bptInForExactTokensOut(bytes memory self) + internal + pure + returns (uint256[] memory amountsOut, uint256 maxBPTAmountIn) + { + (, amountsOut, maxBPTAmountIn) = abi.decode(self, (ExitKind, uint256[], uint256)); + } +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/BalancerErrors.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/BalancerErrors.sol new file mode 100644 index 0000000..f9bf4b6 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/BalancerErrors.sol @@ -0,0 +1,293 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +// solhint-disable + +/** + * @dev Reverts if `condition` is false, with a revert reason containing `errorCode`. Only codes up to 999 are + * supported. + * Uses the default 'BAL' prefix for the error code + */ +function _require(bool condition, uint256 errorCode) pure { + if (!condition) _revert(errorCode); +} + +/** + * @dev Reverts if `condition` is false, with a revert reason containing `errorCode`. Only codes up to 999 are + * supported. + */ +function _require( + bool condition, + uint256 errorCode, + bytes3 prefix +) pure { + if (!condition) _revert(errorCode, prefix); +} + +/** + * @dev Reverts with a revert reason containing `errorCode`. Only codes up to 999 are supported. + * Uses the default 'BAL' prefix for the error code + */ +function _revert(uint256 errorCode) pure { + _revert(errorCode, 0x42414c); // This is the raw byte representation of "BAL" +} + +/** + * @dev Reverts with a revert reason containing `errorCode`. Only codes up to 999 are supported. + */ +function _revert(uint256 errorCode, bytes3 prefix) pure { + uint256 prefixUint = uint256(uint24(prefix)); + // We're going to dynamically create a revert string based on the error code, with the following format: + // 'BAL#{errorCode}' + // where the code is left-padded with zeroes to three digits (so they range from 000 to 999). + // + // We don't have revert strings embedded in the contract to save bytecode size: it takes much less space to store a + // number (8 to 16 bits) than the individual string characters. + // + // The dynamic string creation algorithm that follows could be implemented in Solidity, but assembly allows for a + // much denser implementation, again saving bytecode size. Given this function unconditionally reverts, this is a + // safe place to rely on it without worrying about how its usage might affect e.g. memory contents. + assembly { + // First, we need to compute the ASCII representation of the error code. We assume that it is in the 0-999 + // range, so we only need to convert three digits. To convert the digits to ASCII, we add 0x30, the value for + // the '0' character. + + let units := add(mod(errorCode, 10), 0x30) + + errorCode := div(errorCode, 10) + let tenths := add(mod(errorCode, 10), 0x30) + + errorCode := div(errorCode, 10) + let hundreds := add(mod(errorCode, 10), 0x30) + + // With the individual characters, we can now construct the full string. + // We first append the '#' character (0x23) to the prefix. In the case of 'BAL', it results in 0x42414c23 ('BAL#') + // Then, we shift this by 24 (to provide space for the 3 bytes of the error code), and add the + // characters to it, each shifted by a multiple of 8. + // The revert reason is then shifted left by 200 bits (256 minus the length of the string, 7 characters * 8 bits + // per character = 56) to locate it in the most significant part of the 256 slot (the beginning of a byte + // array). + let formattedPrefix := shl(24, add(0x23, shl(8, prefixUint))) + + let revertReason := shl(200, add(formattedPrefix, add(add(units, shl(8, tenths)), shl(16, hundreds)))) + + // We can now encode the reason in memory, which can be safely overwritten as we're about to revert. The encoded + // message will have the following layout: + // [ revert reason identifier ] [ string location offset ] [ string length ] [ string contents ] + + // The Solidity revert reason identifier is 0x08c739a0, the function selector of the Error(string) function. We + // also write zeroes to the next 28 bytes of memory, but those are about to be overwritten. + mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000) + // Next is the offset to the location of the string, which will be placed immediately after (20 bytes away). + mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020) + // The string length is fixed: 7 characters. + mstore(0x24, 7) + // Finally, the string itself is stored. + mstore(0x44, revertReason) + + // Even if the string is only 7 bytes long, we need to return a full 32 byte slot containing it. The length of + // the encoded message is therefore 4 + 32 + 32 + 32 = 100. + revert(0, 100) + } +} + +library Errors { + // Math + uint256 internal constant ADD_OVERFLOW = 0; + uint256 internal constant SUB_OVERFLOW = 1; + uint256 internal constant SUB_UNDERFLOW = 2; + uint256 internal constant MUL_OVERFLOW = 3; + uint256 internal constant ZERO_DIVISION = 4; + uint256 internal constant DIV_INTERNAL = 5; + uint256 internal constant X_OUT_OF_BOUNDS = 6; + uint256 internal constant Y_OUT_OF_BOUNDS = 7; + uint256 internal constant PRODUCT_OUT_OF_BOUNDS = 8; + uint256 internal constant INVALID_EXPONENT = 9; + + // Input + uint256 internal constant OUT_OF_BOUNDS = 100; + uint256 internal constant UNSORTED_ARRAY = 101; + uint256 internal constant UNSORTED_TOKENS = 102; + uint256 internal constant INPUT_LENGTH_MISMATCH = 103; + uint256 internal constant ZERO_TOKEN = 104; + uint256 internal constant INSUFFICIENT_DATA = 105; + + // Shared pools + uint256 internal constant MIN_TOKENS = 200; + uint256 internal constant MAX_TOKENS = 201; + uint256 internal constant MAX_SWAP_FEE_PERCENTAGE = 202; + uint256 internal constant MIN_SWAP_FEE_PERCENTAGE = 203; + uint256 internal constant MINIMUM_BPT = 204; + uint256 internal constant CALLER_NOT_VAULT = 205; + uint256 internal constant UNINITIALIZED = 206; + uint256 internal constant BPT_IN_MAX_AMOUNT = 207; + uint256 internal constant BPT_OUT_MIN_AMOUNT = 208; + uint256 internal constant EXPIRED_PERMIT = 209; + uint256 internal constant NOT_TWO_TOKENS = 210; + uint256 internal constant DISABLED = 211; + + // Pools + uint256 internal constant MIN_AMP = 300; + uint256 internal constant MAX_AMP = 301; + uint256 internal constant MIN_WEIGHT = 302; + uint256 internal constant MAX_STABLE_TOKENS = 303; + uint256 internal constant MAX_IN_RATIO = 304; + uint256 internal constant MAX_OUT_RATIO = 305; + uint256 internal constant MIN_BPT_IN_FOR_TOKEN_OUT = 306; + uint256 internal constant MAX_OUT_BPT_FOR_TOKEN_IN = 307; + uint256 internal constant NORMALIZED_WEIGHT_INVARIANT = 308; + uint256 internal constant INVALID_TOKEN = 309; + uint256 internal constant UNHANDLED_JOIN_KIND = 310; + uint256 internal constant ZERO_INVARIANT = 311; + uint256 internal constant ORACLE_INVALID_SECONDS_QUERY = 312; + uint256 internal constant ORACLE_NOT_INITIALIZED = 313; + uint256 internal constant ORACLE_QUERY_TOO_OLD = 314; + uint256 internal constant ORACLE_INVALID_INDEX = 315; + uint256 internal constant ORACLE_BAD_SECS = 316; + uint256 internal constant AMP_END_TIME_TOO_CLOSE = 317; + uint256 internal constant AMP_ONGOING_UPDATE = 318; + uint256 internal constant AMP_RATE_TOO_HIGH = 319; + uint256 internal constant AMP_NO_ONGOING_UPDATE = 320; + uint256 internal constant STABLE_INVARIANT_DIDNT_CONVERGE = 321; + uint256 internal constant STABLE_GET_BALANCE_DIDNT_CONVERGE = 322; + uint256 internal constant RELAYER_NOT_CONTRACT = 323; + uint256 internal constant BASE_POOL_RELAYER_NOT_CALLED = 324; + uint256 internal constant REBALANCING_RELAYER_REENTERED = 325; + uint256 internal constant GRADUAL_UPDATE_TIME_TRAVEL = 326; + uint256 internal constant SWAPS_DISABLED = 327; + uint256 internal constant CALLER_IS_NOT_LBP_OWNER = 328; + uint256 internal constant PRICE_RATE_OVERFLOW = 329; + uint256 internal constant INVALID_JOIN_EXIT_KIND_WHILE_SWAPS_DISABLED = 330; + uint256 internal constant WEIGHT_CHANGE_TOO_FAST = 331; + uint256 internal constant LOWER_GREATER_THAN_UPPER_TARGET = 332; + uint256 internal constant UPPER_TARGET_TOO_HIGH = 333; + uint256 internal constant UNHANDLED_BY_LINEAR_POOL = 334; + uint256 internal constant OUT_OF_TARGET_RANGE = 335; + uint256 internal constant UNHANDLED_EXIT_KIND = 336; + uint256 internal constant UNAUTHORIZED_EXIT = 337; + uint256 internal constant MAX_MANAGEMENT_SWAP_FEE_PERCENTAGE = 338; + uint256 internal constant UNHANDLED_BY_MANAGED_POOL = 339; + uint256 internal constant UNHANDLED_BY_PHANTOM_POOL = 340; + uint256 internal constant TOKEN_DOES_NOT_HAVE_RATE_PROVIDER = 341; + uint256 internal constant INVALID_INITIALIZATION = 342; + uint256 internal constant OUT_OF_NEW_TARGET_RANGE = 343; + uint256 internal constant FEATURE_DISABLED = 344; + uint256 internal constant UNINITIALIZED_POOL_CONTROLLER = 345; + uint256 internal constant SET_SWAP_FEE_DURING_FEE_CHANGE = 346; + uint256 internal constant SET_SWAP_FEE_PENDING_FEE_CHANGE = 347; + uint256 internal constant CHANGE_TOKENS_DURING_WEIGHT_CHANGE = 348; + uint256 internal constant CHANGE_TOKENS_PENDING_WEIGHT_CHANGE = 349; + uint256 internal constant MAX_WEIGHT = 350; + uint256 internal constant UNAUTHORIZED_JOIN = 351; + uint256 internal constant MAX_MANAGEMENT_AUM_FEE_PERCENTAGE = 352; + uint256 internal constant FRACTIONAL_TARGET = 353; + uint256 internal constant ADD_OR_REMOVE_BPT = 354; + uint256 internal constant INVALID_CIRCUIT_BREAKER_BOUNDS = 355; + uint256 internal constant CIRCUIT_BREAKER_TRIPPED = 356; + uint256 internal constant MALICIOUS_QUERY_REVERT = 357; + uint256 internal constant JOINS_EXITS_DISABLED = 358; + + // Lib + uint256 internal constant REENTRANCY = 400; + uint256 internal constant SENDER_NOT_ALLOWED = 401; + uint256 internal constant PAUSED = 402; + uint256 internal constant PAUSE_WINDOW_EXPIRED = 403; + uint256 internal constant MAX_PAUSE_WINDOW_DURATION = 404; + uint256 internal constant MAX_BUFFER_PERIOD_DURATION = 405; + uint256 internal constant INSUFFICIENT_BALANCE = 406; + uint256 internal constant INSUFFICIENT_ALLOWANCE = 407; + uint256 internal constant ERC20_TRANSFER_FROM_ZERO_ADDRESS = 408; + uint256 internal constant ERC20_TRANSFER_TO_ZERO_ADDRESS = 409; + uint256 internal constant ERC20_MINT_TO_ZERO_ADDRESS = 410; + uint256 internal constant ERC20_BURN_FROM_ZERO_ADDRESS = 411; + uint256 internal constant ERC20_APPROVE_FROM_ZERO_ADDRESS = 412; + uint256 internal constant ERC20_APPROVE_TO_ZERO_ADDRESS = 413; + uint256 internal constant ERC20_TRANSFER_EXCEEDS_ALLOWANCE = 414; + uint256 internal constant ERC20_DECREASED_ALLOWANCE_BELOW_ZERO = 415; + uint256 internal constant ERC20_TRANSFER_EXCEEDS_BALANCE = 416; + uint256 internal constant ERC20_BURN_EXCEEDS_ALLOWANCE = 417; + uint256 internal constant SAFE_ERC20_CALL_FAILED = 418; + uint256 internal constant ADDRESS_INSUFFICIENT_BALANCE = 419; + uint256 internal constant ADDRESS_CANNOT_SEND_VALUE = 420; + uint256 internal constant SAFE_CAST_VALUE_CANT_FIT_INT256 = 421; + uint256 internal constant GRANT_SENDER_NOT_ADMIN = 422; + uint256 internal constant REVOKE_SENDER_NOT_ADMIN = 423; + uint256 internal constant RENOUNCE_SENDER_NOT_ALLOWED = 424; + uint256 internal constant BUFFER_PERIOD_EXPIRED = 425; + uint256 internal constant CALLER_IS_NOT_OWNER = 426; + uint256 internal constant NEW_OWNER_IS_ZERO = 427; + uint256 internal constant CODE_DEPLOYMENT_FAILED = 428; + uint256 internal constant CALL_TO_NON_CONTRACT = 429; + uint256 internal constant LOW_LEVEL_CALL_FAILED = 430; + uint256 internal constant NOT_PAUSED = 431; + uint256 internal constant ADDRESS_ALREADY_ALLOWLISTED = 432; + uint256 internal constant ADDRESS_NOT_ALLOWLISTED = 433; + uint256 internal constant ERC20_BURN_EXCEEDS_BALANCE = 434; + uint256 internal constant INVALID_OPERATION = 435; + uint256 internal constant CODEC_OVERFLOW = 436; + uint256 internal constant IN_RECOVERY_MODE = 437; + uint256 internal constant NOT_IN_RECOVERY_MODE = 438; + uint256 internal constant INDUCED_FAILURE = 439; + uint256 internal constant EXPIRED_SIGNATURE = 440; + uint256 internal constant MALFORMED_SIGNATURE = 441; + uint256 internal constant SAFE_CAST_VALUE_CANT_FIT_UINT64 = 442; + uint256 internal constant UNHANDLED_FEE_TYPE = 443; + uint256 internal constant BURN_FROM_ZERO = 444; + + // Vault + uint256 internal constant INVALID_POOL_ID = 500; + uint256 internal constant CALLER_NOT_POOL = 501; + uint256 internal constant SENDER_NOT_ASSET_MANAGER = 502; + uint256 internal constant USER_DOESNT_ALLOW_RELAYER = 503; + uint256 internal constant INVALID_SIGNATURE = 504; + uint256 internal constant EXIT_BELOW_MIN = 505; + uint256 internal constant JOIN_ABOVE_MAX = 506; + uint256 internal constant SWAP_LIMIT = 507; + uint256 internal constant SWAP_DEADLINE = 508; + uint256 internal constant CANNOT_SWAP_SAME_TOKEN = 509; + uint256 internal constant UNKNOWN_AMOUNT_IN_FIRST_SWAP = 510; + uint256 internal constant MALCONSTRUCTED_MULTIHOP_SWAP = 511; + uint256 internal constant INTERNAL_BALANCE_OVERFLOW = 512; + uint256 internal constant INSUFFICIENT_INTERNAL_BALANCE = 513; + uint256 internal constant INVALID_ETH_INTERNAL_BALANCE = 514; + uint256 internal constant INVALID_POST_LOAN_BALANCE = 515; + uint256 internal constant INSUFFICIENT_ETH = 516; + uint256 internal constant UNALLOCATED_ETH = 517; + uint256 internal constant ETH_TRANSFER = 518; + uint256 internal constant CANNOT_USE_ETH_SENTINEL = 519; + uint256 internal constant TOKENS_MISMATCH = 520; + uint256 internal constant TOKEN_NOT_REGISTERED = 521; + uint256 internal constant TOKEN_ALREADY_REGISTERED = 522; + uint256 internal constant TOKENS_ALREADY_SET = 523; + uint256 internal constant TOKENS_LENGTH_MUST_BE_2 = 524; + uint256 internal constant NONZERO_TOKEN_BALANCE = 525; + uint256 internal constant BALANCE_TOTAL_OVERFLOW = 526; + uint256 internal constant POOL_NO_TOKENS = 527; + uint256 internal constant INSUFFICIENT_FLASH_LOAN_BALANCE = 528; + + // Fees + uint256 internal constant SWAP_FEE_PERCENTAGE_TOO_HIGH = 600; + uint256 internal constant FLASH_LOAN_FEE_PERCENTAGE_TOO_HIGH = 601; + uint256 internal constant INSUFFICIENT_FLASH_LOAN_FEE_AMOUNT = 602; + uint256 internal constant AUM_FEE_PERCENTAGE_TOO_HIGH = 603; + + // FeeSplitter + uint256 internal constant SPLITTER_FEE_PERCENTAGE_TOO_HIGH = 700; + + // Misc + uint256 internal constant UNIMPLEMENTED = 998; + uint256 internal constant SHOULD_NOT_HAPPEN = 999; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/IAuthentication.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/IAuthentication.sol new file mode 100644 index 0000000..35ed541 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/IAuthentication.sol @@ -0,0 +1,22 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface IAuthentication { + /** + * @dev Returns the action identifier associated with the external function described by `selector`. + */ + function getActionId(bytes4 selector) external view returns (bytes32); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/IOptionalOnlyCaller.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/IOptionalOnlyCaller.sol new file mode 100644 index 0000000..adbbcc3 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/IOptionalOnlyCaller.sol @@ -0,0 +1,43 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @dev Interface for the OptionalOnlyCaller helper, used to opt in to a caller + * verification for a given address to methods that are otherwise callable by any address. + */ +interface IOptionalOnlyCaller { + /** + * @dev Emitted every time setOnlyCallerCheck is called. + */ + event OnlyCallerOptIn(address user, bool enabled); + + /** + * @dev Enables / disables verification mechanism for caller. + * @param enabled - True if caller verification shall be enabled, false otherwise. + */ + function setOnlyCallerCheck(bool enabled) external; + + function setOnlyCallerCheckWithSignature( + address user, + bool enabled, + bytes memory signature + ) external; + + /** + * @dev Returns true if caller verification is enabled for the given user, false otherwise. + */ + function isOnlyCallerEnabled(address user) external view returns (bool); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ISignaturesValidator.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ISignaturesValidator.sol new file mode 100644 index 0000000..cd89f24 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ISignaturesValidator.sol @@ -0,0 +1,30 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @dev Interface for the SignatureValidator helper, used to support meta-transactions. + */ +interface ISignaturesValidator { + /** + * @dev Returns the EIP712 domain separator. + */ + function getDomainSeparator() external view returns (bytes32); + + /** + * @dev Returns the next nonce used by an address to sign messages. + */ + function getNextNonce(address user) external view returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ITemporarilyPausable.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ITemporarilyPausable.sol new file mode 100644 index 0000000..9895f71 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ITemporarilyPausable.sol @@ -0,0 +1,37 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @dev Interface for the TemporarilyPausable helper. + */ +interface ITemporarilyPausable { + /** + * @dev Emitted every time the pause state changes by `_setPaused`. + */ + event PausedStateChanged(bool paused); + + /** + * @dev Returns the current paused state. + */ + function getPausedState() + external + view + returns ( + bool paused, + uint256 pauseWindowEndTime, + uint256 bufferPeriodEndTime + ); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IERC4626.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IERC4626.sol new file mode 100644 index 0000000..2f52637 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IERC4626.sol @@ -0,0 +1,72 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../openzeppelin/IERC20.sol"; + +interface IERC4626 is IERC20 { + /** + * @dev `caller` has exchanged `assets` for `shares`, and transferred those `shares` to `owner`. + */ + event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); + + /** + * @dev `caller` has exchanged `shares`, owned by `owner`, for `assets`, + * and transferred those `assets` to `receiver`. + */ + event Withdraw( + address indexed caller, + address indexed receiver, + address indexed owner, + uint256 assets, + uint256 shares + ); + + /** + * @dev Mints `shares` Vault shares to `receiver` by depositing exactly `amount` of underlying tokens. + */ + function deposit(uint256 assets, address receiver) external returns (uint256 shares); + + /** + * @dev Burns exactly `shares` from `owner` and sends `assets` of underlying tokens to `receiver`. + */ + function redeem( + uint256 shares, + address receiver, + address owner + ) external returns (uint256 assets); + + /** + * @dev The address of the underlying token that the Vault uses for accounting, depositing, and withdrawing. + */ + function asset() external view returns (address); + + /** + * @dev Total amount of the underlying asset that is “managed” by Vault. + */ + function totalAssets() external view returns (uint256); + + /** + * @dev The amount of `assets` that the Vault would exchange for the amount + * of `shares` provided, in an ideal scenario where all the conditions are met. + */ + function convertToAssets(uint256 shares) external view returns (uint256 assets); + + /** + * @dev The amount of `shares` that the Vault would exchange for the amount + * of `assets` provided, in an ideal scenario where all the conditions are met. + */ + function convertToShares(uint256 assets) external view returns (uint256 shares); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IWETH.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IWETH.sol new file mode 100644 index 0000000..c9a519a --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IWETH.sol @@ -0,0 +1,27 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../openzeppelin/IERC20.sol"; + +/** + * @dev Interface for WETH9. + * See https://github.com/gnosis/canonical-weth/blob/0dd1ea3e295eef916d0c6223ec63141137d22d67/contracts/WETH9.sol + */ +interface IWETH is IERC20 { + function deposit() external payable; + + function withdraw(uint256 amount) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC1271.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC1271.sol new file mode 100644 index 0000000..bc56e73 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC1271.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @dev Interface of the ERC1271 standard signature validation method for + * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. + * + * _Available since v4.1._ + */ +interface IERC1271 { + /** + * @dev Should return whether the signature provided is valid for the provided data + * @param hash Hash of the data to be signed + * @param signature Signature byte array associated with _data + */ + function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20.sol new file mode 100644 index 0000000..7cd1c14 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address recipient, uint256 amount) 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 `amount` 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 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `sender` to `recipient` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address sender, + address recipient, + uint256 amount + ) external returns (bool); + + /** + * @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); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20Permit.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20Permit.sol new file mode 100644 index 0000000..0259cbb --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20Permit.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in + * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. + * + * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by + * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't + * need to send a transaction, and thus is not required to hold Ether at all. + */ +interface IERC20Permit { + /** + * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens, + * given `owner`'s signed approval. + * + * IMPORTANT: The same issues {IERC20-approve} has related to transaction + * ordering also apply here. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `deadline` must be a timestamp in the future. + * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` + * over the EIP712-formatted function arguments. + * - the signature must use ``owner``'s current nonce (see {nonces}). + * + * For more information on the signature format, see the + * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP + * section]. + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; + + /** + * @dev Returns the current nonce for `owner`. This value must be + * included whenever a signature is generated for {permit}. + * + * Every successful call to {permit} increases ``owner``'s nonce by one. This + * prevents a signature from being used multiple times. + */ + function nonces(address owner) external view returns (uint256); + + /** + * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}. + */ + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view returns (bytes32); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20PermitDAI.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20PermitDAI.sol new file mode 100644 index 0000000..e69d98b --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20PermitDAI.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT + +pragma solidity >=0.7.0 <0.9.0; + +interface IERC20PermitDAI { + /** + * @notice update allowance with a signed permit + * @param holder Token owner's address (Authorizer) + * @param spender Spender's address + * @param nonce The permit nonce + * @param expiry The time at which this expires (unix time) + * @param allowed Whether the spender is allowed or disallowed from spending + * @param v v of the signature + * @param r r of the signature + * @param s s of the signature + */ + function permit( + address holder, + address spender, + uint256 nonce, + uint256 expiry, + bool allowed, + uint8 v, + bytes32 r, + bytes32 s + ) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/LICENSE b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/LICENSE new file mode 100644 index 0000000..ade2b70 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016-2020 zOS Global Limited + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/README.md b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/README.md new file mode 100644 index 0000000..98659b1 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/README.md @@ -0,0 +1,11 @@ +## Ports from OpenZeppelin Contracts + +Files in this directory are based on the [OpenZeppelin Contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) library, and as such are licensed under the MIT License: see [LICENSE](./LICENSE). + +Most of the modifications fall under one of these categories: + +- removal of functions unused in Balancer V2 source code +- replacement of `require` statements with the `_require` function from the `BalancerErrors.sol` contract +- modification or addition of functionality to reduce bytecode size (see `ReentrancyGuard.sol`) or gas usage (see `EnumerableSet`, `EnumerableMap` or `SafeERC20`) + +Non-trivial modifications in this last category have associated source code comments that explain the changes and motivation. diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IAToken.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IAToken.sol new file mode 100644 index 0000000..6b2ca63 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IAToken.sol @@ -0,0 +1,23 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface IAToken { + /** + * @dev returns the address of the aToken's underlying asset + */ + // solhint-disable-next-line func-name-mixedcase + function UNDERLYING_ASSET_ADDRESS() external view returns (address); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBALTokenHolder.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBALTokenHolder.sol new file mode 100644 index 0000000..a73613c --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBALTokenHolder.sol @@ -0,0 +1,30 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/helpers/IAuthentication.sol"; +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface IBALTokenHolder is IAuthentication { + function getName() external view returns (string memory); + + function withdrawFunds(address recipient, uint256 amount) external; + + function sweepTokens( + IERC20 token, + address recipient, + uint256 amount + ) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBALTokenHolderFactory.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBALTokenHolderFactory.sol new file mode 100644 index 0000000..0836b96 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBALTokenHolderFactory.sol @@ -0,0 +1,30 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../vault/IVault.sol"; +import "../liquidity-mining/IBalancerToken.sol"; + +import "./IBALTokenHolder.sol"; + +interface IBALTokenHolderFactory { + function getBalancerToken() external view returns (IBalancerToken); + + function getVault() external view returns (IVault); + + function isHolderFromFactory(address holder) external view returns (bool); + + function create(string memory name) external returns (IBALTokenHolder); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBalancerQueries.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBalancerQueries.sol new file mode 100644 index 0000000..435f0ea --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBalancerQueries.sol @@ -0,0 +1,62 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../vault/IVault.sol"; + +/** + * @dev Provides a way to perform queries on swaps, joins and exits, simulating these operations and returning the exact + * result they would have if called on the Vault given the current state. Note that the results will be affected by + * other transactions interacting with the Pools involved. + * + * All query functions can be called both on-chain and off-chain. + * + * If calling them from a contract, note that all query functions are not `view`. Despite this, these functions produce + * no net state change, and for all intents and purposes can be thought of as if they were indeed `view`. However, + * calling them via STATICCALL will fail. + * + * If calling them from an off-chain client, make sure to use eth_call: most clients default to eth_sendTransaction for + * non-view functions. + * + * In all cases, the `fromInternalBalance` and `toInternalBalance` fields are entirely ignored: we just use the same + * structs for simplicity. + */ +interface IBalancerQueries { + function querySwap(IVault.SingleSwap memory singleSwap, IVault.FundManagement memory funds) + external + returns (uint256); + + function queryBatchSwap( + IVault.SwapKind kind, + IVault.BatchSwapStep[] memory swaps, + IAsset[] memory assets, + IVault.FundManagement memory funds + ) external returns (int256[] memory assetDeltas); + + function queryJoin( + bytes32 poolId, + address sender, + address recipient, + IVault.JoinPoolRequest memory request + ) external returns (uint256 bptOut, uint256[] memory amountsIn); + + function queryExit( + bytes32 poolId, + address sender, + address recipient, + IVault.ExitPoolRequest memory request + ) external returns (uint256 bptIn, uint256[] memory amountsOut); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBalancerRelayer.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBalancerRelayer.sol new file mode 100644 index 0000000..57b93fc --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IBalancerRelayer.sol @@ -0,0 +1,30 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../vault/IVault.sol"; + +/** + * @title IBalancerRelayer + * @notice Allows safe multicall execution of a relayer's functions + */ +interface IBalancerRelayer { + function getLibrary() external view returns (address); + + function getVault() external view returns (IVault); + + function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IButtonWrapper.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IButtonWrapper.sol new file mode 100644 index 0000000..b4473e8 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IButtonWrapper.sol @@ -0,0 +1,120 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +// Source: https://github.com/buttonwood-protocol/button-wrappers/blob/main/contracts/interfaces/IButtonWrapper.sol +// Interface definition for ButtonWrapper contract, which wraps an +// underlying ERC20 token into a new ERC20 with different characteristics. +// NOTE: "uAmount" => underlying token (wrapped) amount and +// "amount" => wrapper token amount +interface IButtonWrapper { + //-------------------------------------------------------------------------- + // ButtonWrapper write methods + + /// @notice Transfers underlying tokens from {msg.sender} to the contract and + /// mints wrapper tokens. + /// @param amount The amount of wrapper tokens to mint. + /// @return The amount of underlying tokens deposited. + function mint(uint256 amount) external returns (uint256); + + /// @notice Transfers underlying tokens from {msg.sender} to the contract and + /// mints wrapper tokens to the specified beneficiary. + /// @param to The beneficiary account. + /// @param amount The amount of wrapper tokens to mint. + /// @return The amount of underlying tokens deposited. + function mintFor(address to, uint256 amount) external returns (uint256); + + /// @notice Burns wrapper tokens from {msg.sender} and transfers + /// the underlying tokens back. + /// @param amount The amount of wrapper tokens to burn. + /// @return The amount of underlying tokens withdrawn. + function burn(uint256 amount) external returns (uint256); + + /// @notice Burns wrapper tokens from {msg.sender} and transfers + /// the underlying tokens to the specified beneficiary. + /// @param to The beneficiary account. + /// @param amount The amount of wrapper tokens to burn. + /// @return The amount of underlying tokens withdrawn. + function burnTo(address to, uint256 amount) external returns (uint256); + + /// @notice Burns all wrapper tokens from {msg.sender} and transfers + /// the underlying tokens back. + /// @return The amount of underlying tokens withdrawn. + function burnAll() external returns (uint256); + + /// @notice Burns all wrapper tokens from {msg.sender} and transfers + /// the underlying tokens back. + /// @param to The beneficiary account. + /// @return The amount of underlying tokens withdrawn. + function burnAllTo(address to) external returns (uint256); + + /// @notice Transfers underlying tokens from {msg.sender} to the contract and + /// mints wrapper tokens to the specified beneficiary. + /// @param uAmount The amount of underlying tokens to deposit. + /// @return The amount of wrapper tokens mint. + function deposit(uint256 uAmount) external returns (uint256); + + /// @notice Transfers underlying tokens from {msg.sender} to the contract and + /// mints wrapper tokens to the specified beneficiary. + /// @param to The beneficiary account. + /// @param uAmount The amount of underlying tokens to deposit. + /// @return The amount of wrapper tokens mint. + function depositFor(address to, uint256 uAmount) external returns (uint256); + + /// @notice Burns wrapper tokens from {msg.sender} and transfers + /// the underlying tokens back. + /// @param uAmount The amount of underlying tokens to withdraw. + /// @return The amount of wrapper tokens burnt. + function withdraw(uint256 uAmount) external returns (uint256); + + /// @notice Burns wrapper tokens from {msg.sender} and transfers + /// the underlying tokens back to the specified beneficiary. + /// @param to The beneficiary account. + /// @param uAmount The amount of underlying tokens to withdraw. + /// @return The amount of wrapper tokens burnt. + function withdrawTo(address to, uint256 uAmount) external returns (uint256); + + /// @notice Burns all wrapper tokens from {msg.sender} and transfers + /// the underlying tokens back. + /// @return The amount of wrapper tokens burnt. + function withdrawAll() external returns (uint256); + + /// @notice Burns all wrapper tokens from {msg.sender} and transfers + /// the underlying tokens back. + /// @param to The beneficiary account. + /// @return The amount of wrapper tokens burnt. + function withdrawAllTo(address to) external returns (uint256); + + //-------------------------------------------------------------------------- + // ButtonWrapper view methods + + /// @return The address of the underlying token. + function underlying() external view returns (address); + + /// @return The total underlying tokens held by the wrapper contract. + function totalUnderlying() external view returns (uint256); + + /// @param who The account address. + /// @return The underlying token balance of the account. + function balanceOfUnderlying(address who) external view returns (uint256); + + /// @param uAmount The amount of underlying tokens. + /// @return The amount of wrapper tokens exchangeable. + function underlyingToWrapper(uint256 uAmount) external view returns (uint256); + + /// @param amount The amount of wrapper tokens. + /// @return The amount of underlying tokens exchangeable. + function wrapperToUnderlying(uint256 amount) external view returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ICToken.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ICToken.sol new file mode 100644 index 0000000..0473a01 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ICToken.sol @@ -0,0 +1,48 @@ +// 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 . + +pragma solidity ^0.7.0; + +// Interface for MidasCapital. An open interest protocol based on +// modified Fuse contracts. Anyone can create an deploy isolated +// lending and borrowing pools with custom parameters. + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface ICToken is IERC20 { + // Error codes referenced in this file can be found here: + // https://github.com/compound-finance/compound-protocol/blob/a3214f67b73310d547e00fc578e8355911c9d376/contracts/ErrorReporter.sol + // solhint-disable-previous-line max-line-length + + /** + * @dev Underlying asset for this CToken + */ + function underlying() external view returns (address); + + /** + * @notice Sender supplies assets into the market and receives cTokens in exchange + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param mintAmount The amount of the underlying asset to supply + * @return uint 0=success, otherwise an error code (see ErrorReporter.sol link above for details) + */ + function mint(uint256 mintAmount) external returns (uint256); + + /** + * @notice Sender redeems cTokens in exchange for the underlying asset + * @dev Accrues interest whether or not the operation succeeds, unless reverted + * @param redeemTokens The number of cTokens to redeem into underlying + * @return uint 0=success, otherwise an error code (see ErrorReporter.sol link above for details) + */ + function redeem(uint256 redeemTokens) external returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IEulerToken.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IEulerToken.sol new file mode 100644 index 0000000..2cf453e --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IEulerToken.sol @@ -0,0 +1,52 @@ +// 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 . + +pragma solidity ^0.7.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface IEulerToken is IERC20 { + /** + * @dev Convert an eToken balance to an underlying amount, taking into account current exchange rate + * @param balance eToken balance, in internal book-keeping units (18 decimals) + * @return Amount in underlying units, (same decimals as underlying token) + */ + // https://github.com/euler-xyz/euler-contracts/blob/b1ee3265853628d5a529081d7908c38404201b4e/contracts/modules/EToken.sol#L104 + // solhint-disable-previous-line max-line-length + function convertBalanceToUnderlying(uint256 balance) external view returns (uint256); + + /** + * @dev Convert an underlying amount to an eToken balance, taking into account current exchange rate + * @param underlyingAmount Amount in underlying units (same decimals as underlying token) + * @return eToken balance, in internal book-keeping units (18 decimals) + */ + // https://github.com/euler-xyz/euler-contracts/blob/b1ee3265853628d5a529081d7908c38404201b4e/contracts/modules/EToken.sol#L114 + // solhint-disable-previous-line max-line-length + function convertUnderlyingToBalance(uint256 underlyingAmount) external view returns (uint256); + + /** + * @dev Transfer underlying tokens from sender to the Euler pool, and increase account's eTokens + */ + function deposit(uint256 subAccountId, uint256 amount) external; + + /** + * @dev Transfer underlying tokens from Euler pool to sender, and decrease account's eTokens + */ + function withdraw(uint256 subAccountId, uint256 amount) external; + + /** + * @dev Address of underlying asset + */ + function underlyingAsset() external view returns (address); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IGearboxDieselToken.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IGearboxDieselToken.sol new file mode 100644 index 0000000..04241de --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IGearboxDieselToken.sol @@ -0,0 +1,62 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface IGearboxDieselToken is IERC20 { + /** + * @dev returns the address of the vault + */ + function owner() external view returns (address); +} + +interface IGearboxVault { + /** + * @dev returns the address of the underlying asset + */ + function underlyingToken() external view returns (address); + + /** + * @dev returns a 27 decimal fixed point 'ray' value so a rate of 1 is represented as 1e27 + */ + // solhint-disable-next-line func-name-mixedcase + function getDieselRate_RAY() external view returns (uint256); + + /** + * @dev converts diesel token amount to main token amount + */ + function fromDiesel(uint256) external view returns (uint256); + + /** + * @dev converts main token amount to diesel token amount + */ + function toDiesel(uint256) external view returns (uint256); + + /** + * @dev Adds liquidity to pool and sends diesel (LP) tokens back to the liquidity provider + * The Referral code can be 0 + */ + function addLiquidity( + uint256 underlyingAmount, + address onBehalfOf, + uint256 referralCode + ) external; + + /** + * @dev Removes liquidity from the pool and sends the underlying tokens to the `to` address + */ + function removeLiquidity(uint256 dieselAmount, address to) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeePercentagesProvider.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeePercentagesProvider.sol new file mode 100644 index 0000000..d368079 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeePercentagesProvider.sol @@ -0,0 +1,100 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +/** + * @dev Source of truth for all Protocol Fee percentages, that is, how much the protocol charges certain actions. Some + * of these values may also be retrievable from other places (such as the swap fee percentage), but this is the + * preferred source nonetheless. + */ +interface IProtocolFeePercentagesProvider { + // All fee percentages are 18-decimal fixed point numbers, so e.g. 1e18 = 100% and 1e16 = 1%. + + // Emitted when a new fee type is registered. + event ProtocolFeeTypeRegistered(uint256 indexed feeType, string name, uint256 maximumPercentage); + + // Emitted when the value of a fee type changes. + // IMPORTANT: it is possible for a third party to modify the SWAP and FLASH_LOAN fee type values directly in the + // ProtocolFeesCollector, which will result in this event not being emitted despite their value changing. Such usage + // of the ProtocolFeesCollector is however discouraged: all state-changing interactions with it should originate in + // this contract. + event ProtocolFeePercentageChanged(uint256 indexed feeType, uint256 percentage); + + /** + * @dev Registers a new fee type in the system, making it queryable via `getFeeTypePercentage` and `getFeeTypeName`, + * as well as configurable via `setFeeTypePercentage`. + * + * `feeType` can be any arbitrary value (that is not in use). + * + * It is not possible to de-register fee types, nor change their name or maximum value. + */ + function registerFeeType( + uint256 feeType, + string memory name, + uint256 maximumValue, + uint256 initialValue + ) external; + + /** + * @dev Returns true if `feeType` has been registered and can be queried. + */ + function isValidFeeType(uint256 feeType) external view returns (bool); + + /** + * @dev Returns true if `value` is a valid percentage value for `feeType`. + */ + function isValidFeeTypePercentage(uint256 feeType, uint256 value) external view returns (bool); + + /** + * @dev Sets the percentage value for `feeType` to `newValue`. + * + * IMPORTANT: it is possible for a third party to modify the SWAP and FLASH_LOAN fee type values directly in the + * ProtocolFeesCollector, without invoking this function. This will result in the `ProtocolFeePercentageChanged` + * event not being emitted despite their value changing. Such usage of the ProtocolFeesCollector is however + * discouraged: only this contract should be granted permission to call `setSwapFeePercentage` and + * `setFlashLoanFeePercentage`. + */ + function setFeeTypePercentage(uint256 feeType, uint256 newValue) external; + + /** + * @dev Returns the current percentage value for `feeType`. This is the preferred mechanism for querying these - + * whenever possible, use this fucntion instead of e.g. querying the ProtocolFeesCollector. + */ + function getFeeTypePercentage(uint256 feeType) external view returns (uint256); + + /** + * @dev Returns `feeType`'s maximum value. + */ + function getFeeTypeMaximumPercentage(uint256 feeType) external view returns (uint256); + + /** + * @dev Returns `feeType`'s name. + */ + function getFeeTypeName(uint256 feeType) external view returns (string memory); +} + +library ProtocolFeeType { + // This list is not exhaustive - more fee types can be added to the system. It is expected for this list to be + // extended with new fee types as they are registered, to keep them all in one place and reduce + // likelihood of user error. + + // solhint-disable private-vars-leading-underscore + uint256 internal constant SWAP = 0; + uint256 internal constant FLASH_LOAN = 1; + uint256 internal constant YIELD = 2; + uint256 internal constant AUM = 3; + // solhint-enable private-vars-leading-underscore +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeeSplitter.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeeSplitter.sol new file mode 100644 index 0000000..934d262 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeeSplitter.sol @@ -0,0 +1,136 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../vault/IVault.sol"; +import "./IProtocolFeesWithdrawer.sol"; + +/** + * @title ProtocolFeeSplitter + * @author Daoism Systems + * @notice Distributes protocol fees collected from a particular pool between a DAO fund recipient + * (e.g., the Balancer DAO treasury), and a beneficiary designated by the pool owner. + * @dev By default, all funds go to the DAO. To claim a share of the protocol fees, pool owners + * may call `setPoolBeneficiary`. + */ +interface IProtocolFeeSplitter { + event FeesCollected( + bytes32 indexed poolId, + address indexed beneficiary, + uint256 poolEarned, + address indexed daoFundsRecipient, + uint256 daoEarned + ); + + event PoolRevenueShareChanged(bytes32 indexed poolId, uint256 revenueSharePercentage); + event PoolRevenueShareCleared(bytes32 indexed poolId); + event PoolBeneficiaryChanged(bytes32 indexed poolId, address newBeneficiary); + event DefaultRevenueSharePercentageChanged(uint256 revenueSharePercentage); + event DAOFundsRecipientChanged(address newDaoFundsRecipient); + + // Fund recipients + + /** + * @notice Returns the DAO funds recipient that will receive any balance not due to the pool beneficiary. + */ + function getDaoFundsRecipient() external view returns (address); + + /** + * @notice Allows a authorized user to change the DAO funds recipient. + * @dev This is a permissioned function. + * @param newDaoFundsRecipient - address of the new DAO funds recipient. + */ + function setDaoFundsRecipient(address newDaoFundsRecipient) external; + + /** + * @notice Allows a pool owner to change the revenue share beneficiary for a given pool. + * @dev This is a permissioned function. + * @param poolId - the poolId of the pool where the beneficiary will change. + * @param newBeneficiary - address of the new beneficiary. + */ + function setPoolBeneficiary(bytes32 poolId, address newBeneficiary) external; + + // Revenue share settings + + /** + * @dev Returns the current protocol fee split configuration for a given pool. + * @param poolId - the poolId of a pool with accrued protocol fees. + * @return revenueSharePercentageOverride - the percentage of the split sent to the pool beneficiary. + * @return beneficiary - the address of the pool beneficiary. + */ + function getRevenueShareSettings(bytes32 poolId) + external + view + returns ( + uint256 revenueSharePercentageOverride, + address beneficiary, + bool overrideSet + ); + + /** + * @dev Returns the default revenue share percentage a pool will receive, unless overridden by a call + * to `setRevenueSharePercentage`. + */ + function getDefaultRevenueSharePercentage() external view returns (uint256); + + /** + * @notice Allows an authorized user to change the default revenue share percentage. + * @dev Set the default revenue share percentage, applied to pools where no override has been set + * through `setRevenueSharePercentage`. Must be below the maximum allowed split. + * This is a permissioned function. + * @param defaultRevenueSharePercentage - new default revenue share percentage + */ + function setDefaultRevenueSharePercentage(uint256 defaultRevenueSharePercentage) external; + + /** + * @notice Allows an authorized user to change the revenueShare for a given pool. + * @dev This is a permissioned function. + * @param poolId - the poolId of the pool where the revenue share will change. + * @param revenueSharePercentage - the new revenue share percentage. + */ + function setRevenueSharePercentage(bytes32 poolId, uint256 revenueSharePercentage) external; + + /** + * @notice Allows an authorized user to change the revenueShare for a given pool. + * @dev This is a permissioned function. + * @param poolId - the poolId of the pool where the revenue share will change. + */ + function clearRevenueSharePercentage(bytes32 poolId) external; + + // Permissionless fee collection functions + + /** + * @dev Returns the amount of fees that would be sent to each beneficiary in a call to `collectFees`. + * @param poolId - the poolId of a pool with accrued protocol fees. + * @return beneficiaryAmount - the BPT amount that would be sent to the pool beneficiary. + * @return daoAmount - the BPT amount that would be sent to the DAO funds recipient. + */ + function getAmounts(bytes32 poolId) external view returns (uint256 beneficiaryAmount, uint256 daoAmount); + + /** + * @dev Permissionless function to collect and distribute any accrued protocol fees for the given pool. + * @param poolId - the poolId of a pool with accrued protocol fees. + * @return beneficiaryAmount - the BPT amount sent to the pool beneficiary. + * @return daoAmount - the BPT amount sent to the DAO funds recipient. + */ + function collectFees(bytes32 poolId) external returns (uint256 beneficiaryAmount, uint256 daoAmount); + + // Misc getters + + /** + * @notice Returns the `ProtocolFeesWithdrawer`, used to withdraw funds from the `ProtocolFeesCollector`. + */ + function getProtocolFeesWithdrawer() external view returns (IProtocolFeesWithdrawer); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeesWithdrawer.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeesWithdrawer.sol new file mode 100644 index 0000000..04272ce --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolFeesWithdrawer.sol @@ -0,0 +1,78 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../vault/IProtocolFeesCollector.sol"; + +/** + * @author Balancer Labs + * @title Protocol Fees Withdrawer + * @notice Safety layer around the Protocol Fees Collector which allows withdrawals of specific tokens to be blocked. + * This is useful for the case in where tokens that shouldn't be distributed are unexpectedly paid into the Protocol + * Fees Collector. + */ +interface IProtocolFeesWithdrawer { + event TokenAllowlisted(IERC20 token); + event TokenDenylisted(IERC20 token); + + /** + * @notice Returns the address of the Protocol Fee Collector. + */ + function getProtocolFeesCollector() external view returns (IProtocolFeesCollector); + + /** + * @notice Returns whether the provided token may be withdrawn from the Protocol Fee Collector + */ + function isWithdrawableToken(IERC20 token) external view returns (bool); + + /** + * @notice Returns whether the provided array of tokens may be withdrawn from the Protocol Fee Collector + * @dev Returns false if any token is denylisted. + */ + function isWithdrawableTokens(IERC20[] calldata tokens) external view returns (bool); + + /** + * @notice Returns the denylisted token at the given `index`. + */ + function getDenylistedToken(uint256 index) external view returns (IERC20); + + /** + * @notice Returns the number of denylisted tokens. + */ + function getDenylistedTokensLength() external view returns (uint256); + + /** + * @notice Withdraws fees from the Protocol Fee Collector. + * @dev Reverts if attempting to withdraw a denylisted token. + * @param tokens - an array of token addresses to withdraw. + * @param amounts - an array of the amounts of each token to withdraw. + * @param recipient - the address to which to send the withdrawn tokens. + */ + function withdrawCollectedFees( + IERC20[] calldata tokens, + uint256[] calldata amounts, + address recipient + ) external; + + /** + * @notice Marks the provided token as ineligible for withdrawal from the Protocol Fee Collector + */ + function denylistToken(IERC20 token) external; + + /** + * @notice Marks the provided token as eligible for withdrawal from the Protocol Fee Collector + */ + function allowlistToken(IERC20 token) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolIdRegistry.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolIdRegistry.sol new file mode 100644 index 0000000..4aafa79 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IProtocolIdRegistry.sol @@ -0,0 +1,74 @@ +// 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 . + +pragma solidity ^0.7.0; + +/** + * @dev Registry of protocol IDs for external integrations with Balancer. The IDs chosen are arbitrary and do not affect + * behavior of any Balancer contracts. They are used only to tag specific contracts (usually pools) at the data layer. + */ +interface IProtocolIdRegistry { + // Emitted when a new protocol ID is registered. + event ProtocolIdRegistered(uint256 indexed protocolId, string name); + + // Emitted when a protocol IDs name has been updated. + event ProtocolIdRenamed(uint256 indexed protocolId, string name); + + /** + * @dev Registers an ID (and name) to differentiate among protocols. Protocol IDs cannot be deregistered. + */ + function registerProtocolId(uint256 protocolId, string memory name) external; + + /** + * @dev Changes the name of an existing protocol ID. Should only be used to update in the case of mistakes. + */ + function renameProtocolId(uint256 protocolId, string memory newName) external; + + /** + * @dev Returns true if `protocolId` has been registered and can be queried. + */ + function isValidProtocolId(uint256 protocolId) external view returns (bool); + + /** + * @dev Returns the name associated with a given `protocolId`. + */ + function getProtocolName(uint256 protocolId) external view returns (string memory); +} + +library ProtocolId { + // This list is not exhaustive - more protocol IDs can be added to the system. It is expected for this list to be + // extended with new protocol IDs as they are registered, to keep them all in one place and reduce + // likelihood of user error. + // solhint-disable private-vars-leading-underscore + uint256 internal constant AAVE_V1 = 0; + uint256 internal constant AAVE_V2 = 1; + uint256 internal constant AAVE_V3 = 2; + uint256 internal constant AMPLEFORTH = 3; + uint256 internal constant BEEFY = 4; + uint256 internal constant EULER = 5; + uint256 internal constant GEARBOX = 6; + uint256 internal constant IDLE = 7; + uint256 internal constant MORPHO = 8; + uint256 internal constant RADIANT = 9; + uint256 internal constant REAPER = 10; + uint256 internal constant SILO = 11; + uint256 internal constant STARGATE = 12; + uint256 internal constant STURDY = 13; + uint256 internal constant TESSERA = 14; + uint256 internal constant TETU = 15; + uint256 internal constant YEARN = 16; + uint256 internal constant MIDAS = 17; + uint256 internal constant AGAVE = 18; + // solhint-enable private-vars-leading-underscore +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IReaperTokenVault.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IReaperTokenVault.sol new file mode 100644 index 0000000..1f3df5a --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IReaperTokenVault.sol @@ -0,0 +1,54 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +// Source: https://github.com/Byte-Masons/beet-strat/blob/master/contracts/ReaperVaultv1_4.sol +// Interface definition for the ReaperTokenVault contract, a single strategy vault +// for Reaper Farm crypts. The pricePerFullShare is always represented with 18 decimals, +// regardless of the underlying token decimals. +// ie: If ppfs === 1e18, 1 USDC === 0.000_000_000_001_000_000 rfUSDC +// ie: If ppfs === 1e18, 1 DAI === 1 rfDAI +interface IReaperTokenVault is IERC20 { + /** + * @dev returns the address of the vault's underlying asset (mainToken) + */ + function token() external view returns (address); + + /** + * @dev returns the price for a single Vault share (ie rf-scfUSDT). The getPricePerFullShare is always in 1e18 + */ + function getPricePerFullShare() external view returns (uint256); + + /** + * @notice Deposits `_amount` `token`, issuing shares to the caller. + * If Panic is activated, deposits will not be accepted and this call will fail. + * @param _amount The quantity of tokens to deposit. + **/ + function deposit(uint256 _amount) external; + + /** + * @notice Withdraws the calling account's tokens from this Vault, + * redeeming amount `_shares` for an appropriate amount of tokens. + **/ + function withdraw(uint256 _shares) external; + + /** + * @dev returns the number of decimals for this vault token. + * For reaper single-strat vaults, the decimals are fixed to 18. + */ + function decimals() external view returns (uint8); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IShareToken.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IShareToken.sol new file mode 100644 index 0000000..0bcfd4e --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IShareToken.sol @@ -0,0 +1,31 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +import "./ISilo.sol"; + +interface IShareToken is IERC20 { + /** + * @dev returns the underlying asset + */ + function asset() external view returns (address); + + /** + * @dev returns the address of the silo + */ + function silo() external view returns (ISilo); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ISilo.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ISilo.sol new file mode 100644 index 0000000..7acc7a4 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ISilo.sol @@ -0,0 +1,76 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "./IShareToken.sol"; + +interface IBaseSilo { + /// Storage struct that holds all required data for a single token market + struct AssetStorage { + // Token that represents a share in totalDeposits of Silo + IShareToken collateralToken; + // Token that represents a share in collateralOnlyDeposits of Silo + IShareToken collateralOnlyToken; + // Token that represents a share in totalBorrowAmount of Silo + IShareToken debtToken; + // COLLATERAL: Amount of asset token that has been deposited to Silo with interest earned by depositors. + // It also includes token amount that has been borrowed. + uint256 totalDeposits; + // COLLATERAL ONLY: Amount of asset token that has been deposited to Silo that can ONLY be used + // as collateral. These deposits do NOT earn interest and CANNOT be borrowed. + uint256 collateralOnlyDeposits; + // DEBT: Amount of asset token that has been borrowed with accrued interest. + uint256 totalBorrowAmount; + } + + /** + * @dev returns the asset storage struct + * @dev AssetStorage struct contains necessary information for calculating shareToken exchange rates + */ + function assetStorage(address _asset) external view returns (AssetStorage memory); +} + +interface ISilo is IBaseSilo { + /** + * @dev Deposits funds into the Silo + * @param _asset The address of the token to deposit + * @param _depositor The address of the recipient of collateral tokens + * @param _amount The amount of the token to deposit + * @param _collateralOnly: True means your shareToken is protected (cannot be swapped for interest) + * @return collateralAmount deposited amount + * @return collateralShare user collateral shares based on deposited amount + */ + function depositFor( + address _asset, + address _depositor, + uint256 _amount, + bool _collateralOnly + ) external returns (uint256 collateralAmount, uint256 collateralShare); + + /** + * @dev Withdraw `_amount` of `_asset` tokens from the Silo to `msg.sender` + * @param _asset The address of the token to withdraw + * @param _amount The amount of the token to withdraw + * @param _collateralOnly True if withdrawing collateral only deposit + * @return withdrawnAmount withdrawn amount that was transferred to user + * @return withdrawnShare burned share based on `withdrawnAmount` + */ + function withdraw( + address _asset, + uint256 _amount, + bool _collateralOnly + ) external returns (uint256 withdrawnAmount, uint256 withdrawnShare); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IStaticATokenLM.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IStaticATokenLM.sol new file mode 100644 index 0000000..e9125f7 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IStaticATokenLM.sol @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +// solhint-disable-next-line max-line-length +// Based on https://github.com/aave/protocol-v2/blob/ac58fea62bb8afee23f66197e8bce6d79ecda292/contracts/interfaces/IStaticATokenLM.sol + +interface IStaticATokenLM is IERC20 { + struct SignatureParams { + uint8 v; + bytes32 r; + bytes32 s; + } + + /** + * @notice Deposits `ASSET` in the Aave protocol and mints static aTokens to msg.sender + * @param recipient The address that will receive the static aTokens + * @param amount The amount of underlying `ASSET` to deposit (e.g. deposit of 100 USDC) + * @param referralCode Code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + * @param fromUnderlying bool + * - `true` if the msg.sender comes with underlying tokens (e.g. USDC) + * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC) + * @return uint256 The amount of StaticAToken minted, static balance + **/ + function deposit( + address recipient, + uint256 amount, + uint16 referralCode, + bool fromUnderlying + ) external returns (uint256); + + /** + * @notice Burns `amount` of static aToken, with recipient receiving the corresponding amount of `ASSET` + * @param recipient The address that will receive the amount of `ASSET` withdrawn from the Aave protocol + * @param amount The amount to withdraw, in static balance of StaticAToken + * @param toUnderlying bool + * - `true` for the recipient to get underlying tokens (e.g. USDC) + * - `false` for the recipient to get aTokens (e.g. aUSDC) + * @return amountToBurn: StaticATokens burnt, static balance + * @return amountToWithdraw: underlying/aToken send to `recipient`, dynamic balance + **/ + function withdraw( + address recipient, + uint256 amount, + bool toUnderlying + ) external returns (uint256, uint256); + + /** + * @notice Burns `amount` of static aToken, with recipient receiving the corresponding amount of `ASSET` + * @param recipient The address that will receive the amount of `ASSET` withdrawn from the Aave protocol + * @param amount The amount to withdraw, in dynamic balance of aToken/underlying asset + * @param toUnderlying bool + * - `true` for the recipient to get underlying tokens (e.g. USDC) + * - `false` for the recipient to get aTokens (e.g. aUSDC) + * @return amountToBurn: StaticATokens burnt, static balance + * @return amountToWithdraw: underlying/aToken send to `recipient`, dynamic balance + **/ + function withdrawDynamicAmount( + address recipient, + uint256 amount, + bool toUnderlying + ) external returns (uint256, uint256); + + /** + * @notice Implements the permit function as for + * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md + * @param owner The owner of the funds + * @param spender The spender + * @param value The amount + * @param deadline The deadline timestamp, type(uint256).max for max deadline + * @param v Signature param + * @param s Signature param + * @param r Signature param + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; + + /** + * @notice Allows to deposit on Aave via meta-transaction + * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md + * @param depositor Address from which the funds to deposit are going to be pulled + * @param recipient Address that will receive the staticATokens, in the average case, same as the `depositor` + * @param value The amount to deposit + * @param referralCode Code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + * @param fromUnderlying bool + * - `true` if the msg.sender comes with underlying tokens (e.g. USDC) + * - `false` if the msg.sender comes already with aTokens (e.g. aUSDC) + * @param deadline The deadline timestamp, type(uint256).max for max deadline + * @param sigParams Signature params: v,r,s + * @return uint256 The amount of StaticAToken minted, static balance + */ + function metaDeposit( + address depositor, + address recipient, + uint256 value, + uint16 referralCode, + bool fromUnderlying, + uint256 deadline, + SignatureParams calldata sigParams + ) external returns (uint256); + + /** + * @notice Allows to withdraw from Aave via meta-transaction + * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md + * @param owner Address owning the staticATokens + * @param recipient Address that will receive the underlying withdrawn from Aave + * @param staticAmount The amount of staticAToken to withdraw. If > 0, `dynamicAmount` needs to be 0 + * @param dynamicAmount The amount of underlying/aToken to withdraw. If > 0, `staticAmount` needs to be 0 + * @param toUnderlying bool + * - `true` for the recipient to get underlying tokens (e.g. USDC) + * - `false` for the recipient to get aTokens (e.g. aUSDC) + * @param deadline The deadline timestamp, type(uint256).max for max deadline + * @param sigParams Signature params: v,r,s + * @return amountToBurn: StaticATokens burnt, static balance + * @return amountToWithdraw: underlying/aToken send to `recipient`, dynamic balance + */ + function metaWithdraw( + address owner, + address recipient, + uint256 staticAmount, + uint256 dynamicAmount, + bool toUnderlying, + uint256 deadline, + SignatureParams calldata sigParams + ) external returns (uint256, uint256); + + /** + * @notice Utility method to get the current aToken balance of an user, from his staticAToken balance + * @param account The address of the user + * @return uint256 The aToken balance + **/ + function dynamicBalanceOf(address account) external view returns (uint256); + + /** + * @notice Converts a static amount (scaled balance on aToken) to the aToken/underlying value, + * using the current liquidity index on Aave + * @param amount The amount to convert from + * @return uint256 The dynamic amount + **/ + function staticToDynamicAmount(uint256 amount) external view returns (uint256); + + /** + * @notice Converts an aToken or underlying amount to the what it is denominated on the aToken as + * scaled balance, function of the principal and the liquidity index + * @param amount The amount to convert from + * @return uint256 The static (scaled) amount + **/ + function dynamicToStaticAmount(uint256 amount) external view returns (uint256); + + /** + * @notice Returns the Aave liquidity index of the underlying aToken, denominated rate here + * as it can be considered as an ever-increasing exchange rate + * @return The liquidity index + **/ + function rate() external view returns (uint256); + + /** + * @notice Function to return a dynamic domain separator, in order to be compatible with forks changing chainId + * @return bytes32 The domain separator + **/ + function getDomainSeparator() external view returns (bytes32); + + /** + * @notice Claims rewards from `INCENTIVES_CONTROLLER` and updates internal accounting of rewards. + */ + function collectAndUpdateRewards() external; + + /** + * @notice Claim rewards on behalf of a user and send them to a receiver + * @dev Only callable by if sender is onBehalfOf or sender is approved claimer + * @param onBehalfOf The address to claim on behalf of + * @param receiver The address to receive the rewards + * @param forceUpdate Flag to retrieve latest rewards from `INCENTIVES_CONTROLLER` + */ + function claimRewardsOnBehalf( + address onBehalfOf, + address receiver, + bool forceUpdate + ) external; + + /** + * @notice Claim rewards and send them to a receiver + * @param receiver The address to receive the rewards + * @param forceUpdate Flag to retrieve latest rewards from `INCENTIVES_CONTROLLER` + */ + function claimRewards(address receiver, bool forceUpdate) external; + + /** + * @notice Claim rewards + * @param forceUpdate Flag to retrieve latest rewards from `INCENTIVES_CONTROLLER` + */ + function claimRewardsToSelf(bool forceUpdate) external; + + /** + * @notice Get the total claimable rewards of the contract. + * @return The current balance + pending rewards from the `_incentivesController` + */ + function getTotalClaimableRewards() external view returns (uint256); + + /** + * @notice Get the total claimable rewards for a user in WAD + * @param user The address of the user + * @return The claimable amount of rewards in WAD + */ + function getClaimableRewards(address user) external view returns (uint256); + + /** + * @notice The unclaimed rewards for a user in WAD + * @param user The address of the user + * @return The unclaimed amount of rewards in WAD + */ + function getUnclaimedRewards(address user) external view returns (uint256); + + function getAccRewardsPerToken() external view returns (uint256); + + function getLifetimeRewardsClaimed() external view returns (uint256); + + function getLifetimeRewards() external view returns (uint256); + + function getLastRewardBlock() external view returns (uint256); + + // solhint-disable-next-line func-name-mixedcase + function LENDING_POOL() external returns (address); + + // solhint-disable-next-line func-name-mixedcase + function INCENTIVES_CONTROLLER() external returns (address); + + // solhint-disable-next-line func-name-mixedcase + function ATOKEN() external returns (IERC20); + + // solhint-disable-next-line func-name-mixedcase + function ASSET() external returns (IERC20); + + // solhint-disable-next-line func-name-mixedcase + function REWARD_TOKEN() external returns (IERC20); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ITetuSmartVault.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ITetuSmartVault.sol new file mode 100644 index 0000000..a12a20f --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ITetuSmartVault.sol @@ -0,0 +1,37 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface ITetuSmartVault is IERC20 { + function deposit(uint256 amount) external; + + function depositFor(uint256 amount, address holder) external; + + function underlyingBalanceInVault() external view returns (uint256); + + function withdraw(uint256 numberOfShares) external; + + function underlyingBalanceWithInvestmentForHolder(address holder) external view returns (uint256); + + function underlying() external view returns (address); + + function underlyingUnit() external view returns (uint256); + + function getPricePerFullShare() external view returns (uint256); + + function strategy() external view returns (address); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ITetuStrategy.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ITetuStrategy.sol new file mode 100644 index 0000000..e331dd2 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/ITetuStrategy.sol @@ -0,0 +1,19 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface ITetuStrategy { + function investedUnderlyingBalance() external view returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IUnbuttonToken.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IUnbuttonToken.sol new file mode 100644 index 0000000..7ee7e6a --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IUnbuttonToken.sol @@ -0,0 +1,25 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +import "./IButtonWrapper.sol"; + +// Balancer only supports ERC20 tokens, so we use this intermediate interface +// to enforce ERC20-ness of UnbuttonTokens. +interface IUnbuttonToken is IButtonWrapper, IERC20 { + // solhint-disable-previous-line no-empty-blocks +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IYearnTokenVault.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IYearnTokenVault.sol new file mode 100644 index 0000000..2f457cc --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IYearnTokenVault.sol @@ -0,0 +1,49 @@ +// 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 . + +pragma solidity ^0.7.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface IYearnTokenVault is IERC20 { + /** + * @dev returns the address of the vault's underlying asset (mainToken) + */ + function token() external view returns (address); + + /** + * @dev returns the price for a single Vault share (ie yvDAI). The pricePerShare is represented + * in the same decimals as the underlying asset (ie: 6 decimals for USDC) + */ + function pricePerShare() external view returns (uint256); + + /** + * @notice Deposits `_amount` `token`, issuing shares to `recipient`. + * If the Vault is in Emergency Shutdown, deposits will not be accepted and this call will fail. + * @param _amount The quantity of tokens to deposit, defaults to all. + * @param recipient The address to issue the shares in this Vault to. Defaults to the caller's address. + * @return The issued Vault shares. + */ + function deposit(uint256 _amount, address recipient) external returns (uint256); + + /** + * @notice Withdraws the calling account's tokens from this Vault, + * redeeming amount `_shares` for an appropriate amount of tokens. + * See note on `setWithdrawalQueue` for further details of withdrawal ordering and behavior. + * @param maxShares How many shares to try and redeem for tokens, defaults to all. + * @param recipient The address to issue the shares in this Vault to. Defaults to the caller's address. + * @return redeemed: The quantity of tokens redeemed for `_shares`. + */ + function withdraw(uint256 maxShares, address recipient) external returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IstETH.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IstETH.sol new file mode 100644 index 0000000..308e3be --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IstETH.sol @@ -0,0 +1,24 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +// solhint-disable-next-line max-line-length +// Based on https://github.com/lidofinance/lido-dao/blob/816bf1d0995ba5cfdfc264de4acda34a7fe93eba/contracts/0.4.24/Lido.sol + +interface IstETH is IERC20 { + function submit(address referral) external payable returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IwstETH.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IwstETH.sol new file mode 100644 index 0000000..f87bf49 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/standalone-utils/IwstETH.sol @@ -0,0 +1,92 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +import "./IstETH.sol"; + +// solhint-disable-next-line max-line-length +// Based on https://github.com/lidofinance/lido-dao/blob/2b46615a11dee77d4d22066f942f6c6afab9b87a/contracts/0.6.12/WstETH.sol + +/** + * @title StETH token wrapper with static balances. + * @dev It's an ERC20 token that represents the account's share of the total + * supply of stETH tokens. WstETH token's balance only changes on transfers, + * unlike StETH that is also changed when oracles report staking rewards and + * penalties. It's a "power user" token for DeFi protocols which don't + * support rebasable tokens. + * + * The contract is also a trustless wrapper that accepts stETH tokens and mints + * wstETH in return. Then the user unwraps, the contract burns user's wstETH + * and sends user locked stETH in return. + * + * The contract provides the staking shortcut: user can send ETH with regular + * transfer and get wstETH in return. The contract will send ETH to Lido submit + * method, staking it and wrapping the received stETH. + * + */ +interface IwstETH is IERC20 { + function stETH() external returns (IstETH); + + /** + * @notice Exchanges stETH to wstETH + * @param _stETHAmount amount of stETH to wrap in exchange for wstETH + * @dev Requirements: + * - `_stETHAmount` must be non-zero + * - msg.sender must approve at least `_stETHAmount` stETH to this + * contract. + * - msg.sender must have at least `_stETHAmount` of stETH. + * User should first approve _stETHAmount to the WstETH contract + * @return Amount of wstETH user receives after wrap + */ + function wrap(uint256 _stETHAmount) external returns (uint256); + + /** + * @notice Exchanges wstETH to stETH + * @param _wstETHAmount amount of wstETH to uwrap in exchange for stETH + * @dev Requirements: + * - `_wstETHAmount` must be non-zero + * - msg.sender must have at least `_wstETHAmount` wstETH. + * @return Amount of stETH user receives after unwrap + */ + function unwrap(uint256 _wstETHAmount) external returns (uint256); + + /** + * @notice Get amount of wstETH for a given amount of stETH + * @param _stETHAmount amount of stETH + * @return Amount of wstETH for a given stETH amount + */ + function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256); + + /** + * @notice Get amount of stETH for a given amount of wstETH + * @param _wstETHAmount amount of wstETH + * @return Amount of stETH for a given wstETH amount + */ + function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256); + + /** + * @notice Get amount of wstETH for a one stETH + * @return Amount of stETH for 1 wstETH + */ + function stEthPerToken() external view returns (uint256); + + /** + * @notice Get amount of stETH for a one wstETH + * @return Amount of wstETH for a 1 stETH + */ + function tokensPerStEth() external view returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IAsset.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IAsset.sol new file mode 100644 index 0000000..a425a6d --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IAsset.sol @@ -0,0 +1,26 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @dev This is an empty interface used to represent either ERC20-conforming token contracts or ETH (using the zero + * address sentinel value). We're just relying on the fact that `interface` can be used to declare new address-like + * types. + * + * This concept is unrelated to a Pool's Asset Managers. + */ +interface IAsset { + // solhint-disable-previous-line no-empty-blocks +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IAuthorizer.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IAuthorizer.sol new file mode 100644 index 0000000..d7995fb --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IAuthorizer.sol @@ -0,0 +1,26 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +interface IAuthorizer { + /** + * @dev Returns true if `account` can perform the action described by `actionId` in the contract `where`. + */ + function canPerform( + bytes32 actionId, + address account, + address where + ) external view returns (bool); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IBasePool.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IBasePool.sol new file mode 100644 index 0000000..4411e51 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IBasePool.sol @@ -0,0 +1,126 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "./IVault.sol"; +import "./IPoolSwapStructs.sol"; + +/** + * @dev Interface for adding and removing liquidity that all Pool contracts should implement. Note that this is not + * the complete Pool contract interface, as it is missing the swap hooks. Pool contracts should also inherit from + * either IGeneralPool or IMinimalSwapInfoPool + */ +interface IBasePool is IPoolSwapStructs { + /** + * @dev Called by the Vault when a user calls `IVault.joinPool` to add liquidity to this Pool. Returns how many of + * each registered token the user should provide, as well as the amount of protocol fees the Pool owes to the Vault. + * The Vault will then take tokens from `sender` and add them to the Pool's balances, as well as collect + * the reported amount in protocol fees, which the pool should calculate based on `protocolSwapFeePercentage`. + * + * Protocol fees are reported and charged on join events so that the Pool is free of debt whenever new users join. + * + * `sender` is the account performing the join (from which tokens will be withdrawn), and `recipient` is the account + * designated to receive any benefits (typically pool shares). `balances` contains the total balances + * for each token the Pool registered in the Vault, in the same order that `IVault.getPoolTokens` would return. + * + * `lastChangeBlock` is the last block in which *any* of the Pool's registered tokens last changed its total + * balance. + * + * `userData` contains any pool-specific instructions needed to perform the calculations, such as the type of + * join (e.g., proportional given an amount of pool shares, single-asset, multi-asset, etc.) + * + * Contracts implementing this function should check that the caller is indeed the Vault before performing any + * state-changing operations, such as minting pool shares. + */ + function onJoinPool( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + bytes memory userData + ) external returns (uint256[] memory amountsIn, uint256[] memory dueProtocolFeeAmounts); + + /** + * @dev Called by the Vault when a user calls `IVault.exitPool` to remove liquidity from this Pool. Returns how many + * tokens the Vault should deduct from the Pool's balances, as well as the amount of protocol fees the Pool owes + * to the Vault. The Vault will then take tokens from the Pool's balances and send them to `recipient`, + * as well as collect the reported amount in protocol fees, which the Pool should calculate based on + * `protocolSwapFeePercentage`. + * + * Protocol fees are charged on exit events to guarantee that users exiting the Pool have paid their share. + * + * `sender` is the account performing the exit (typically the pool shareholder), and `recipient` is the account + * to which the Vault will send the proceeds. `balances` contains the total token balances for each token + * the Pool registered in the Vault, in the same order that `IVault.getPoolTokens` would return. + * + * `lastChangeBlock` is the last block in which *any* of the Pool's registered tokens last changed its total + * balance. + * + * `userData` contains any pool-specific instructions needed to perform the calculations, such as the type of + * exit (e.g., proportional given an amount of pool shares, single-asset, multi-asset, etc.) + * + * Contracts implementing this function should check that the caller is indeed the Vault before performing any + * state-changing operations, such as burning pool shares. + */ + function onExitPool( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + bytes memory userData + ) external returns (uint256[] memory amountsOut, uint256[] memory dueProtocolFeeAmounts); + + /** + * @dev Returns this Pool's ID, used when interacting with the Vault (to e.g. join the Pool or swap with it). + */ + function getPoolId() external view returns (bytes32); + + /** + * @dev Returns the current swap fee percentage as a 18 decimal fixed point number, so e.g. 1e17 corresponds to a + * 10% swap fee. + */ + function getSwapFeePercentage() external view returns (uint256); + + /** + * @dev Returns the scaling factors of each of the Pool's tokens. This is an implementation detail that is typically + * not relevant for outside parties, but which might be useful for some types of Pools. + */ + function getScalingFactors() external view returns (uint256[] memory); + + function queryJoin( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + bytes memory userData + ) external returns (uint256 bptOut, uint256[] memory amountsIn); + + function queryExit( + bytes32 poolId, + address sender, + address recipient, + uint256[] memory balances, + uint256 lastChangeBlock, + uint256 protocolSwapFeePercentage, + bytes memory userData + ) external returns (uint256 bptIn, uint256[] memory amountsOut); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IBasicAuthorizer.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IBasicAuthorizer.sol new file mode 100644 index 0000000..f84bbfb --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IBasicAuthorizer.sol @@ -0,0 +1,26 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +import "./IAuthorizer.sol"; + +interface IBasicAuthorizer is IAuthorizer { + // solhint-disable-next-line func-name-mixedcase + function DEFAULT_ADMIN_ROLE() external returns (bytes32); + + function getRoleAdmin(bytes32 role) external view returns (bytes32); + + function getRoleMember(bytes32 role, uint256 index) external view returns (address); + + function getRoleMemberCount(bytes32 role) external view returns (uint256); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IFlashLoanRecipient.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IFlashLoanRecipient.sol new file mode 100644 index 0000000..10ad894 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IFlashLoanRecipient.sol @@ -0,0 +1,37 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; + +// Inspired by Aave Protocol's IFlashLoanReceiver. + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +interface IFlashLoanRecipient { + /** + * @dev When `flashLoan` is called on the Vault, it invokes the `receiveFlashLoan` hook on the recipient. + * + * At the time of the call, the Vault will have transferred `amounts` for `tokens` to the recipient. Before this + * call returns, the recipient must have transferred `amounts` plus `feeAmounts` for each token back to the + * Vault, or else the entire flash loan will revert. + * + * `userData` is the same value passed in the `IVault.flashLoan` call. + */ + function receiveFlashLoan( + IERC20[] memory tokens, + uint256[] memory amounts, + uint256[] memory feeAmounts, + bytes memory userData + ) external; +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IGeneralPool.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IGeneralPool.sol new file mode 100644 index 0000000..e5f2b6b --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IGeneralPool.sol @@ -0,0 +1,38 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "./IBasePool.sol"; + +/** + * @dev IPools with the General specialization setting should implement this interface. + * + * This is called by the Vault when a user calls `IVault.swap` or `IVault.batchSwap` to swap with this Pool. + * Returns the number of tokens the Pool will grant to the user in a 'given in' swap, or that the user will + * grant to the pool in a 'given out' swap. + * + * This can often be implemented by a `view` function, since many pricing algorithms don't need to track state + * changes in swaps. However, contracts implementing this in non-view functions should check that the caller is + * indeed the Vault. + */ +interface IGeneralPool is IBasePool { + function onSwap( + SwapRequest memory swapRequest, + uint256[] memory balances, + uint256 indexIn, + uint256 indexOut + ) external returns (uint256 amount); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IMinimalSwapInfoPool.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IMinimalSwapInfoPool.sol new file mode 100644 index 0000000..8359396 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IMinimalSwapInfoPool.sol @@ -0,0 +1,37 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "./IBasePool.sol"; + +/** + * @dev Pool contracts with the MinimalSwapInfo or TwoToken specialization settings should implement this interface. + * + * This is called by the Vault when a user calls `IVault.swap` or `IVault.batchSwap` to swap with this Pool. + * Returns the number of tokens the Pool will grant to the user in a 'given in' swap, or that the user will grant + * to the pool in a 'given out' swap. + * + * This can often be implemented by a `view` function, since many pricing algorithms don't need to track state + * changes in swaps. However, contracts implementing this in non-view functions should check that the caller is + * indeed the Vault. + */ +interface IMinimalSwapInfoPool is IBasePool { + function onSwap( + SwapRequest memory swapRequest, + uint256 currentBalanceTokenIn, + uint256 currentBalanceTokenOut + ) external returns (uint256 amount); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IPoolSwapStructs.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IPoolSwapStructs.sol new file mode 100644 index 0000000..a23a04d --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IPoolSwapStructs.sol @@ -0,0 +1,59 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +import "./IVault.sol"; + +interface IPoolSwapStructs { + // This is not really an interface - it just defines common structs used by other interfaces: IGeneralPool and + // IMinimalSwapInfoPool. + // + // This data structure represents a request for a token swap, where `kind` indicates the swap type ('given in' or + // 'given out') which indicates whether or not the amount sent by the pool is known. + // + // The pool receives `tokenIn` and sends `tokenOut`. `amount` is the number of `tokenIn` tokens the pool will take + // in, or the number of `tokenOut` tokens the Pool will send out, depending on the given swap `kind`. + // + // All other fields are not strictly necessary for most swaps, but are provided to support advanced scenarios in + // some Pools. + // + // `poolId` is the ID of the Pool involved in the swap - this is useful for Pool contracts that implement more than + // one Pool. + // + // The meaning of `lastChangeBlock` depends on the Pool specialization: + // - Two Token or Minimal Swap Info: the last block in which either `tokenIn` or `tokenOut` changed its total + // balance. + // - General: the last block in which *any* of the Pool's registered tokens changed its total balance. + // + // `from` is the origin address for the funds the Pool receives, and `to` is the destination address + // where the Pool sends the outgoing tokens. + // + // `userData` is extra data provided by the caller - typically a signature from a trusted party. + struct SwapRequest { + IVault.SwapKind kind; + IERC20 tokenIn; + IERC20 tokenOut; + uint256 amount; + // Misc data + bytes32 poolId; + uint256 lastChangeBlock; + address from; + address to; + bytes userData; + } +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IProtocolFeesCollector.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IProtocolFeesCollector.sol new file mode 100644 index 0000000..7fb4482 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IProtocolFeesCollector.sol @@ -0,0 +1,46 @@ +// 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 . + +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "../solidity-utils/openzeppelin/IERC20.sol"; + +import "./IVault.sol"; +import "./IAuthorizer.sol"; + +interface IProtocolFeesCollector { + event SwapFeePercentageChanged(uint256 newSwapFeePercentage); + event FlashLoanFeePercentageChanged(uint256 newFlashLoanFeePercentage); + + function withdrawCollectedFees( + IERC20[] calldata tokens, + uint256[] calldata amounts, + address recipient + ) external; + + function setSwapFeePercentage(uint256 newSwapFeePercentage) external; + + function setFlashLoanFeePercentage(uint256 newFlashLoanFeePercentage) external; + + function getSwapFeePercentage() external view returns (uint256); + + function getFlashLoanFeePercentage() external view returns (uint256); + + function getCollectedFeeAmounts(IERC20[] memory tokens) external view returns (uint256[] memory feeAmounts); + + function getAuthorizer() external view returns (IAuthorizer); + + function vault() external view returns (IVault); +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IVault.sol b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IVault.sol new file mode 100644 index 0000000..c55f9d2 --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/contracts/vault/IVault.sol @@ -0,0 +1,772 @@ +// 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 . + +pragma experimental ABIEncoderV2; + +import "../solidity-utils/openzeppelin/IERC20.sol"; +import "../solidity-utils/helpers/IAuthentication.sol"; +import "../solidity-utils/helpers/ISignaturesValidator.sol"; +import "../solidity-utils/helpers/ITemporarilyPausable.sol"; +import "../solidity-utils/misc/IWETH.sol"; + +import "./IAsset.sol"; +import "./IAuthorizer.sol"; +import "./IFlashLoanRecipient.sol"; +import "./IProtocolFeesCollector.sol"; + +pragma solidity >=0.7.0 <0.9.0; + +/** + * @dev Full external interface for the Vault core contract - no external or public methods exist in the contract that + * don't override one of these declarations. + */ +interface IVault is ISignaturesValidator, ITemporarilyPausable, IAuthentication { + // Generalities about the Vault: + // + // - Whenever documentation refers to 'tokens', it strictly refers to ERC20-compliant token contracts. Tokens are + // transferred out of the Vault by calling the `IERC20.transfer` function, and transferred in by calling + // `IERC20.transferFrom`. In these cases, the sender must have previously allowed the Vault to use their tokens by + // calling `IERC20.approve`. The only deviation from the ERC20 standard that is supported is functions not returning + // a boolean value: in these scenarios, a non-reverting call is assumed to be successful. + // + // - All non-view functions in the Vault are non-reentrant: calling them while another one is mid-execution (e.g. + // while execution control is transferred to a token contract during a swap) will result in a revert. View + // functions can be called in a re-reentrant way, but doing so might cause them to return inconsistent results. + // Contracts calling view functions in the Vault must make sure the Vault has not already been entered. + // + // - View functions revert if referring to either unregistered Pools, or unregistered tokens for registered Pools. + + // Authorizer + // + // Some system actions are permissioned, like setting and collecting protocol fees. This permissioning system exists + // outside of the Vault in the Authorizer contract: the Vault simply calls the Authorizer to check if the caller + // can perform a given action. + + /** + * @dev Returns the Vault's Authorizer. + */ + function getAuthorizer() external view returns (IAuthorizer); + + /** + * @dev Sets a new Authorizer for the Vault. The caller must be allowed by the current Authorizer to do this. + * + * Emits an `AuthorizerChanged` event. + */ + function setAuthorizer(IAuthorizer newAuthorizer) external; + + /** + * @dev Emitted when a new authorizer is set by `setAuthorizer`. + */ + event AuthorizerChanged(IAuthorizer indexed newAuthorizer); + + // Relayers + // + // Additionally, it is possible for an account to perform certain actions on behalf of another one, using their + // Vault ERC20 allowance and Internal Balance. These accounts are said to be 'relayers' for these Vault functions, + // and are expected to be smart contracts with sound authentication mechanisms. For an account to be able to wield + // this power, two things must occur: + // - The Authorizer must grant the account the permission to be a relayer for the relevant Vault function. This + // means that Balancer governance must approve each individual contract to act as a relayer for the intended + // functions. + // - Each user must approve the relayer to act on their behalf. + // This double protection means users cannot be tricked into approving malicious relayers (because they will not + // have been allowed by the Authorizer via governance), nor can malicious relayers approved by a compromised + // Authorizer or governance drain user funds, since they would also need to be approved by each individual user. + + /** + * @dev Returns true if `user` has approved `relayer` to act as a relayer for them. + */ + function hasApprovedRelayer(address user, address relayer) external view returns (bool); + + /** + * @dev Allows `relayer` to act as a relayer for `sender` if `approved` is true, and disallows it otherwise. + * + * Emits a `RelayerApprovalChanged` event. + */ + function setRelayerApproval( + address sender, + address relayer, + bool approved + ) external; + + /** + * @dev Emitted every time a relayer is approved or disapproved by `setRelayerApproval`. + */ + event RelayerApprovalChanged(address indexed relayer, address indexed sender, bool approved); + + // Internal Balance + // + // Users can deposit tokens into the Vault, where they are allocated to their Internal Balance, and later + // transferred or withdrawn. It can also be used as a source of tokens when joining Pools, as a destination + // when exiting them, and as either when performing swaps. This usage of Internal Balance results in greatly reduced + // gas costs when compared to relying on plain ERC20 transfers, leading to large savings for frequent users. + // + // Internal Balance management features batching, which means a single contract call can be used to perform multiple + // operations of different kinds, with different senders and recipients, at once. + + /** + * @dev Returns `user`'s Internal Balance for a set of tokens. + */ + function getInternalBalance(address user, IERC20[] memory tokens) external view returns (uint256[] memory); + + /** + * @dev Performs a set of user balance operations, which involve Internal Balance (deposit, withdraw or transfer) + * and plain ERC20 transfers using the Vault's allowance. This last feature is particularly useful for relayers, as + * it lets integrators reuse a user's Vault allowance. + * + * For each operation, if the caller is not `sender`, it must be an authorized relayer for them. + */ + function manageUserBalance(UserBalanceOp[] memory ops) external payable; + + /** + * @dev Data for `manageUserBalance` operations, which include the possibility for ETH to be sent and received + without manual WETH wrapping or unwrapping. + */ + struct UserBalanceOp { + UserBalanceOpKind kind; + IAsset asset; + uint256 amount; + address sender; + address payable recipient; + } + + // There are four possible operations in `manageUserBalance`: + // + // - DEPOSIT_INTERNAL + // Increases the Internal Balance of the `recipient` account by transferring tokens from the corresponding + // `sender`. The sender must have allowed the Vault to use their tokens via `IERC20.approve()`. + // + // ETH can be used by passing the ETH sentinel value as the asset and forwarding ETH in the call: it will be wrapped + // and deposited as WETH. Any ETH amount remaining will be sent back to the caller (not the sender, which is + // relevant for relayers). + // + // Emits an `InternalBalanceChanged` event. + // + // + // - WITHDRAW_INTERNAL + // Decreases the Internal Balance of the `sender` account by transferring tokens to the `recipient`. + // + // ETH can be used by passing the ETH sentinel value as the asset. This will deduct WETH instead, unwrap it and send + // it to the recipient as ETH. + // + // Emits an `InternalBalanceChanged` event. + // + // + // - TRANSFER_INTERNAL + // Transfers tokens from the Internal Balance of the `sender` account to the Internal Balance of `recipient`. + // + // Reverts if the ETH sentinel value is passed. + // + // Emits an `InternalBalanceChanged` event. + // + // + // - TRANSFER_EXTERNAL + // Transfers tokens from `sender` to `recipient`, using the Vault's ERC20 allowance. This is typically used by + // relayers, as it lets them reuse a user's Vault allowance. + // + // Reverts if the ETH sentinel value is passed. + // + // Emits an `ExternalBalanceTransfer` event. + + enum UserBalanceOpKind { DEPOSIT_INTERNAL, WITHDRAW_INTERNAL, TRANSFER_INTERNAL, TRANSFER_EXTERNAL } + + /** + * @dev Emitted when a user's Internal Balance changes, either from calls to `manageUserBalance`, or through + * interacting with Pools using Internal Balance. + * + * Because Internal Balance works exclusively with ERC20 tokens, ETH deposits and withdrawals will use the WETH + * address. + */ + event InternalBalanceChanged(address indexed user, IERC20 indexed token, int256 delta); + + /** + * @dev Emitted when a user's Vault ERC20 allowance is used by the Vault to transfer tokens to an external account. + */ + event ExternalBalanceTransfer(IERC20 indexed token, address indexed sender, address recipient, uint256 amount); + + // Pools + // + // There are three specialization settings for Pools, which allow for cheaper swaps at the cost of reduced + // functionality: + // + // - General: no specialization, suited for all Pools. IGeneralPool is used for swap request callbacks, passing the + // balance of all tokens in the Pool. These Pools have the largest swap costs (because of the extra storage reads), + // which increase with the number of registered tokens. + // + // - Minimal Swap Info: IMinimalSwapInfoPool is used instead of IGeneralPool, which saves gas by only passing the + // balance of the two tokens involved in the swap. This is suitable for some pricing algorithms, like the weighted + // constant product one popularized by Balancer V1. Swap costs are smaller compared to general Pools, and are + // independent of the number of registered tokens. + // + // - Two Token: only allows two tokens to be registered. This achieves the lowest possible swap gas cost. Like + // minimal swap info Pools, these are called via IMinimalSwapInfoPool. + + enum PoolSpecialization { GENERAL, MINIMAL_SWAP_INFO, TWO_TOKEN } + + /** + * @dev Registers the caller account as a Pool with a given specialization setting. Returns the Pool's ID, which + * is used in all Pool-related functions. Pools cannot be deregistered, nor can the Pool's specialization be + * changed. + * + * The caller is expected to be a smart contract that implements either `IGeneralPool` or `IMinimalSwapInfoPool`, + * depending on the chosen specialization setting. This contract is known as the Pool's contract. + * + * Note that the same contract may register itself as multiple Pools with unique Pool IDs, or in other words, + * multiple Pools may share the same contract. + * + * Emits a `PoolRegistered` event. + */ + function registerPool(PoolSpecialization specialization) external returns (bytes32); + + /** + * @dev Emitted when a Pool is registered by calling `registerPool`. + */ + event PoolRegistered(bytes32 indexed poolId, address indexed poolAddress, PoolSpecialization specialization); + + /** + * @dev Returns a Pool's contract address and specialization setting. + */ + function getPool(bytes32 poolId) external view returns (address, PoolSpecialization); + + /** + * @dev Registers `tokens` for the `poolId` Pool. Must be called by the Pool's contract. + * + * Pools can only interact with tokens they have registered. Users join a Pool by transferring registered tokens, + * exit by receiving registered tokens, and can only swap registered tokens. + * + * Each token can only be registered once. For Pools with the Two Token specialization, `tokens` must have a length + * of two, that is, both tokens must be registered in the same `registerTokens` call, and they must be sorted in + * ascending order. + * + * The `tokens` and `assetManagers` arrays must have the same length, and each entry in these indicates the Asset + * Manager for the corresponding token. Asset Managers can manage a Pool's tokens via `managePoolBalance`, + * depositing and withdrawing them directly, and can even set their balance to arbitrary amounts. They are therefore + * expected to be highly secured smart contracts with sound design principles, and the decision to register an + * Asset Manager should not be made lightly. + * + * Pools can choose not to assign an Asset Manager to a given token by passing in the zero address. Once an Asset + * Manager is set, it cannot be changed except by deregistering the associated token and registering again with a + * different Asset Manager. + * + * Emits a `TokensRegistered` event. + */ + function registerTokens( + bytes32 poolId, + IERC20[] memory tokens, + address[] memory assetManagers + ) external; + + /** + * @dev Emitted when a Pool registers tokens by calling `registerTokens`. + */ + event TokensRegistered(bytes32 indexed poolId, IERC20[] tokens, address[] assetManagers); + + /** + * @dev Deregisters `tokens` for the `poolId` Pool. Must be called by the Pool's contract. + * + * Only registered tokens (via `registerTokens`) can be deregistered. Additionally, they must have zero total + * balance. For Pools with the Two Token specialization, `tokens` must have a length of two, that is, both tokens + * must be deregistered in the same `deregisterTokens` call. + * + * A deregistered token can be re-registered later on, possibly with a different Asset Manager. + * + * Emits a `TokensDeregistered` event. + */ + function deregisterTokens(bytes32 poolId, IERC20[] memory tokens) external; + + /** + * @dev Emitted when a Pool deregisters tokens by calling `deregisterTokens`. + */ + event TokensDeregistered(bytes32 indexed poolId, IERC20[] tokens); + + /** + * @dev Returns detailed information for a Pool's registered token. + * + * `cash` is the number of tokens the Vault currently holds for the Pool. `managed` is the number of tokens + * withdrawn and held outside the Vault by the Pool's token Asset Manager. The Pool's total balance for `token` + * equals the sum of `cash` and `managed`. + * + * Internally, `cash` and `managed` are stored using 112 bits. No action can ever cause a Pool's token `cash`, + * `managed` or `total` balance to be greater than 2^112 - 1. + * + * `lastChangeBlock` is the number of the block in which `token`'s total balance was last modified (via either a + * join, exit, swap, or Asset Manager update). This value is useful to avoid so-called 'sandwich attacks', for + * example when developing price oracles. A change of zero (e.g. caused by a swap with amount zero) is considered a + * change for this purpose, and will update `lastChangeBlock`. + * + * `assetManager` is the Pool's token Asset Manager. + */ + function getPoolTokenInfo(bytes32 poolId, IERC20 token) + external + view + returns ( + uint256 cash, + uint256 managed, + uint256 lastChangeBlock, + address assetManager + ); + + /** + * @dev Returns a Pool's registered tokens, the total balance for each, and the latest block when *any* of + * the tokens' `balances` changed. + * + * The order of the `tokens` array is the same order that will be used in `joinPool`, `exitPool`, as well as in all + * Pool hooks (where applicable). Calls to `registerTokens` and `deregisterTokens` may change this order. + * + * If a Pool only registers tokens once, and these are sorted in ascending order, they will be stored in the same + * order as passed to `registerTokens`. + * + * Total balances include both tokens held by the Vault and those withdrawn by the Pool's Asset Managers. These are + * the amounts used by joins, exits and swaps. For a detailed breakdown of token balances, use `getPoolTokenInfo` + * instead. + */ + function getPoolTokens(bytes32 poolId) + external + view + returns ( + IERC20[] memory tokens, + uint256[] memory balances, + uint256 lastChangeBlock + ); + + /** + * @dev Called by users to join a Pool, which transfers tokens from `sender` into the Pool's balance. This will + * trigger custom Pool behavior, which will typically grant something in return to `recipient` - often tokenized + * Pool shares. + * + * If the caller is not `sender`, it must be an authorized relayer for them. + * + * The `assets` and `maxAmountsIn` arrays must have the same length, and each entry indicates the maximum amount + * to send for each asset. The amounts to send are decided by the Pool and not the Vault: it just enforces + * these maximums. + * + * If joining a Pool that holds WETH, it is possible to send ETH directly: the Vault will do the wrapping. To enable + * this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead of the + * WETH address. Note that it is not possible to combine ETH and WETH in the same join. Any excess ETH will be sent + * back to the caller (not the sender, which is important for relayers). + * + * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when + * interacting with Pools that register and deregister tokens frequently. If sending ETH however, the array must be + * sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the final + * `assets` array might not be sorted. Pools with no registered tokens cannot be joined. + * + * If `fromInternalBalance` is true, the caller's Internal Balance will be preferred: ERC20 transfers will only + * be made for the difference between the requested amount and Internal Balance (if any). Note that ETH cannot be + * withdrawn from Internal Balance: attempting to do so will trigger a revert. + * + * This causes the Vault to call the `IBasePool.onJoinPool` hook on the Pool's contract, where Pools implement + * their own custom logic. This typically requires additional information from the user (such as the expected number + * of Pool shares). This can be encoded in the `userData` argument, which is ignored by the Vault and passed + * directly to the Pool's contract, as is `recipient`. + * + * Emits a `PoolBalanceChanged` event. + */ + function joinPool( + bytes32 poolId, + address sender, + address recipient, + JoinPoolRequest memory request + ) external payable; + + struct JoinPoolRequest { + IAsset[] assets; + uint256[] maxAmountsIn; + bytes userData; + bool fromInternalBalance; + } + + /** + * @dev Called by users to exit a Pool, which transfers tokens from the Pool's balance to `recipient`. This will + * trigger custom Pool behavior, which will typically ask for something in return from `sender` - often tokenized + * Pool shares. The amount of tokens that can be withdrawn is limited by the Pool's `cash` balance (see + * `getPoolTokenInfo`). + * + * If the caller is not `sender`, it must be an authorized relayer for them. + * + * The `tokens` and `minAmountsOut` arrays must have the same length, and each entry in these indicates the minimum + * token amount to receive for each token contract. The amounts to send are decided by the Pool and not the Vault: + * it just enforces these minimums. + * + * If exiting a Pool that holds WETH, it is possible to receive ETH directly: the Vault will do the unwrapping. To + * enable this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead + * of the WETH address. Note that it is not possible to combine ETH and WETH in the same exit. + * + * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when + * interacting with Pools that register and deregister tokens frequently. If receiving ETH however, the array must + * be sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the + * final `assets` array might not be sorted. Pools with no registered tokens cannot be exited. + * + * If `toInternalBalance` is true, the tokens will be deposited to `recipient`'s Internal Balance. Otherwise, + * an ERC20 transfer will be performed. Note that ETH cannot be deposited to Internal Balance: attempting to + * do so will trigger a revert. + * + * `minAmountsOut` is the minimum amount of tokens the user expects to get out of the Pool, for each token in the + * `tokens` array. This array must match the Pool's registered tokens. + * + * This causes the Vault to call the `IBasePool.onExitPool` hook on the Pool's contract, where Pools implement + * their own custom logic. This typically requires additional information from the user (such as the expected number + * of Pool shares to return). This can be encoded in the `userData` argument, which is ignored by the Vault and + * passed directly to the Pool's contract. + * + * Emits a `PoolBalanceChanged` event. + */ + function exitPool( + bytes32 poolId, + address sender, + address payable recipient, + ExitPoolRequest memory request + ) external; + + struct ExitPoolRequest { + IAsset[] assets; + uint256[] minAmountsOut; + bytes userData; + bool toInternalBalance; + } + + /** + * @dev Emitted when a user joins or exits a Pool by calling `joinPool` or `exitPool`, respectively. + */ + event PoolBalanceChanged( + bytes32 indexed poolId, + address indexed liquidityProvider, + IERC20[] tokens, + int256[] deltas, + uint256[] protocolFeeAmounts + ); + + enum PoolBalanceChangeKind { JOIN, EXIT } + + // Swaps + // + // Users can swap tokens with Pools by calling the `swap` and `batchSwap` functions. To do this, + // they need not trust Pool contracts in any way: all security checks are made by the Vault. They must however be + // aware of the Pools' pricing algorithms in order to estimate the prices Pools will quote. + // + // The `swap` function executes a single swap, while `batchSwap` can perform multiple swaps in sequence. + // In each individual swap, tokens of one kind are sent from the sender to the Pool (this is the 'token in'), + // and tokens of another kind are sent from the Pool to the recipient in exchange (this is the 'token out'). + // More complex swaps, such as one token in to multiple tokens out can be achieved by batching together + // individual swaps. + // + // There are two swap kinds: + // - 'given in' swaps, where the amount of tokens in (sent to the Pool) is known, and the Pool determines (via the + // `onSwap` hook) the amount of tokens out (to send to the recipient). + // - 'given out' swaps, where the amount of tokens out (received from the Pool) is known, and the Pool determines + // (via the `onSwap` hook) the amount of tokens in (to receive from the sender). + // + // Additionally, it is possible to chain swaps using a placeholder input amount, which the Vault replaces with + // the calculated output of the previous swap. If the previous swap was 'given in', this will be the calculated + // tokenOut amount. If the previous swap was 'given out', it will use the calculated tokenIn amount. These extended + // swaps are known as 'multihop' swaps, since they 'hop' through a number of intermediate tokens before arriving at + // the final intended token. + // + // In all cases, tokens are only transferred in and out of the Vault (or withdrawn from and deposited into Internal + // Balance) after all individual swaps have been completed, and the net token balance change computed. This makes + // certain swap patterns, such as multihops, or swaps that interact with the same token pair in multiple Pools, cost + // much less gas than they would otherwise. + // + // It also means that under certain conditions it is possible to perform arbitrage by swapping with multiple + // Pools in a way that results in net token movement out of the Vault (profit), with no tokens being sent in (only + // updating the Pool's internal accounting). + // + // To protect users from front-running or the market changing rapidly, they supply a list of 'limits' for each token + // involved in the swap, where either the maximum number of tokens to send (by passing a positive value) or the + // minimum amount of tokens to receive (by passing a negative value) is specified. + // + // Additionally, a 'deadline' timestamp can also be provided, forcing the swap to fail if it occurs after + // this point in time (e.g. if the transaction failed to be included in a block promptly). + // + // If interacting with Pools that hold WETH, it is possible to both send and receive ETH directly: the Vault will do + // the wrapping and unwrapping. To enable this mechanism, the IAsset sentinel value (the zero address) must be + // passed in the `assets` array instead of the WETH address. Note that it is possible to combine ETH and WETH in the + // same swap. Any excess ETH will be sent back to the caller (not the sender, which is relevant for relayers). + // + // Finally, Internal Balance can be used when either sending or receiving tokens. + + enum SwapKind { GIVEN_IN, GIVEN_OUT } + + /** + * @dev Performs a swap with a single Pool. + * + * If the swap is 'given in' (the number of tokens to send to the Pool is known), it returns the amount of tokens + * taken from the Pool, which must be greater than or equal to `limit`. + * + * If the swap is 'given out' (the number of tokens to take from the Pool is known), it returns the amount of tokens + * sent to the Pool, which must be less than or equal to `limit`. + * + * Internal Balance usage and the recipient are determined by the `funds` struct. + * + * Emits a `Swap` event. + */ + function swap( + SingleSwap memory singleSwap, + FundManagement memory funds, + uint256 limit, + uint256 deadline + ) external payable returns (uint256); + + /** + * @dev Data for a single swap executed by `swap`. `amount` is either `amountIn` or `amountOut` depending on + * the `kind` value. + * + * `assetIn` and `assetOut` are either token addresses, or the IAsset sentinel value for ETH (the zero address). + * Note that Pools never interact with ETH directly: it will be wrapped to or unwrapped from WETH by the Vault. + * + * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be + * used to extend swap behavior. + */ + struct SingleSwap { + bytes32 poolId; + SwapKind kind; + IAsset assetIn; + IAsset assetOut; + uint256 amount; + bytes userData; + } + + /** + * @dev Performs a series of swaps with one or multiple Pools. In each individual swap, the caller determines either + * the amount of tokens sent to or received from the Pool, depending on the `kind` value. + * + * Returns an array with the net Vault asset balance deltas. Positive amounts represent tokens (or ETH) sent to the + * Vault, and negative amounts represent tokens (or ETH) sent by the Vault. Each delta corresponds to the asset at + * the same index in the `assets` array. + * + * Swaps are executed sequentially, in the order specified by the `swaps` array. Each array element describes a + * Pool, the token to be sent to this Pool, the token to receive from it, and an amount that is either `amountIn` or + * `amountOut` depending on the swap kind. + * + * Multihop swaps can be executed by passing an `amount` value of zero for a swap. This will cause the amount in/out + * of the previous swap to be used as the amount in for the current one. In a 'given in' swap, 'tokenIn' must equal + * the previous swap's `tokenOut`. For a 'given out' swap, `tokenOut` must equal the previous swap's `tokenIn`. + * + * The `assets` array contains the addresses of all assets involved in the swaps. These are either token addresses, + * or the IAsset sentinel value for ETH (the zero address). Each entry in the `swaps` array specifies tokens in and + * out by referencing an index in `assets`. Note that Pools never interact with ETH directly: it will be wrapped to + * or unwrapped from WETH by the Vault. + * + * Internal Balance usage, sender, and recipient are determined by the `funds` struct. The `limits` array specifies + * the minimum or maximum amount of each token the vault is allowed to transfer. + * + * `batchSwap` can be used to make a single swap, like `swap` does, but doing so requires more gas than the + * equivalent `swap` call. + * + * Emits `Swap` events. + */ + function batchSwap( + SwapKind kind, + BatchSwapStep[] memory swaps, + IAsset[] memory assets, + FundManagement memory funds, + int256[] memory limits, + uint256 deadline + ) external payable returns (int256[] memory); + + /** + * @dev Data for each individual swap executed by `batchSwap`. The asset in and out fields are indexes into the + * `assets` array passed to that function, and ETH assets are converted to WETH. + * + * If `amount` is zero, the multihop mechanism is used to determine the actual amount based on the amount in/out + * from the previous swap, depending on the swap kind. + * + * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be + * used to extend swap behavior. + */ + struct BatchSwapStep { + bytes32 poolId; + uint256 assetInIndex; + uint256 assetOutIndex; + uint256 amount; + bytes userData; + } + + /** + * @dev Emitted for each individual swap performed by `swap` or `batchSwap`. + */ + event Swap( + bytes32 indexed poolId, + IERC20 indexed tokenIn, + IERC20 indexed tokenOut, + uint256 amountIn, + uint256 amountOut + ); + + /** + * @dev All tokens in a swap are either sent from the `sender` account to the Vault, or from the Vault to the + * `recipient` account. + * + * If the caller is not `sender`, it must be an authorized relayer for them. + * + * If `fromInternalBalance` is true, the `sender`'s Internal Balance will be preferred, performing an ERC20 + * transfer for the difference between the requested amount and the User's Internal Balance (if any). The `sender` + * must have allowed the Vault to use their tokens via `IERC20.approve()`. This matches the behavior of + * `joinPool`. + * + * If `toInternalBalance` is true, tokens will be deposited to `recipient`'s internal balance instead of + * transferred. This matches the behavior of `exitPool`. + * + * Note that ETH cannot be deposited to or withdrawn from Internal Balance: attempting to do so will trigger a + * revert. + */ + struct FundManagement { + address sender; + bool fromInternalBalance; + address payable recipient; + bool toInternalBalance; + } + + /** + * @dev Simulates a call to `batchSwap`, returning an array of Vault asset deltas. Calls to `swap` cannot be + * simulated directly, but an equivalent `batchSwap` call can and will yield the exact same result. + * + * Each element in the array corresponds to the asset at the same index, and indicates the number of tokens (or ETH) + * the Vault would take from the sender (if positive) or send to the recipient (if negative). The arguments it + * receives are the same that an equivalent `batchSwap` call would receive. + * + * Unlike `batchSwap`, this function performs no checks on the sender or recipient field in the `funds` struct. + * This makes it suitable to be called by off-chain applications via eth_call without needing to hold tokens, + * approve them for the Vault, or even know a user's address. + * + * Note that this function is not 'view' (due to implementation details): the client code must explicitly execute + * eth_call instead of eth_sendTransaction. + */ + function queryBatchSwap( + SwapKind kind, + BatchSwapStep[] memory swaps, + IAsset[] memory assets, + FundManagement memory funds + ) external returns (int256[] memory assetDeltas); + + // Flash Loans + + /** + * @dev Performs a 'flash loan', sending tokens to `recipient`, executing the `receiveFlashLoan` hook on it, + * and then reverting unless the tokens plus a proportional protocol fee have been returned. + * + * The `tokens` and `amounts` arrays must have the same length, and each entry in these indicates the loan amount + * for each token contract. `tokens` must be sorted in ascending order. + * + * The 'userData' field is ignored by the Vault, and forwarded as-is to `recipient` as part of the + * `receiveFlashLoan` call. + * + * Emits `FlashLoan` events. + */ + function flashLoan( + IFlashLoanRecipient recipient, + IERC20[] memory tokens, + uint256[] memory amounts, + bytes memory userData + ) external; + + /** + * @dev Emitted for each individual flash loan performed by `flashLoan`. + */ + event FlashLoan(IFlashLoanRecipient indexed recipient, IERC20 indexed token, uint256 amount, uint256 feeAmount); + + // Asset Management + // + // Each token registered for a Pool can be assigned an Asset Manager, which is able to freely withdraw the Pool's + // tokens from the Vault, deposit them, or assign arbitrary values to its `managed` balance (see + // `getPoolTokenInfo`). This makes them extremely powerful and dangerous. Even if an Asset Manager only directly + // controls one of the tokens in a Pool, a malicious manager could set that token's balance to manipulate the + // prices of the other tokens, and then drain the Pool with swaps. The risk of using Asset Managers is therefore + // not constrained to the tokens they are managing, but extends to the entire Pool's holdings. + // + // However, a properly designed Asset Manager smart contract can be safely used for the Pool's benefit, + // for example by lending unused tokens out for interest, or using them to participate in voting protocols. + // + // This concept is unrelated to the IAsset interface. + + /** + * @dev Performs a set of Pool balance operations, which may be either withdrawals, deposits or updates. + * + * Pool Balance management features batching, which means a single contract call can be used to perform multiple + * operations of different kinds, with different Pools and tokens, at once. + * + * For each operation, the caller must be registered as the Asset Manager for `token` in `poolId`. + */ + function managePoolBalance(PoolBalanceOp[] memory ops) external; + + struct PoolBalanceOp { + PoolBalanceOpKind kind; + bytes32 poolId; + IERC20 token; + uint256 amount; + } + + /** + * Withdrawals decrease the Pool's cash, but increase its managed balance, leaving the total balance unchanged. + * + * Deposits increase the Pool's cash, but decrease its managed balance, leaving the total balance unchanged. + * + * Updates don't affect the Pool's cash balance, but because the managed balance changes, it does alter the total. + * The external amount can be either increased or decreased by this call (i.e., reporting a gain or a loss). + */ + enum PoolBalanceOpKind { WITHDRAW, DEPOSIT, UPDATE } + + /** + * @dev Emitted when a Pool's token Asset Manager alters its balance via `managePoolBalance`. + */ + event PoolBalanceManaged( + bytes32 indexed poolId, + address indexed assetManager, + IERC20 indexed token, + int256 cashDelta, + int256 managedDelta + ); + + // Protocol Fees + // + // Some operations cause the Vault to collect tokens in the form of protocol fees, which can then be withdrawn by + // permissioned accounts. + // + // There are two kinds of protocol fees: + // + // - flash loan fees: charged on all flash loans, as a percentage of the amounts lent. + // + // - swap fees: a percentage of the fees charged by Pools when performing swaps. For a number of reasons, including + // swap gas costs and interface simplicity, protocol swap fees are not charged on each individual swap. Rather, + // Pools are expected to keep track of how much they have charged in swap fees, and pay any outstanding debts to the + // Vault when they are joined or exited. This prevents users from joining a Pool with unpaid debt, as well as + // exiting a Pool in debt without first paying their share. + + /** + * @dev Returns the current protocol fee module. + */ + function getProtocolFeesCollector() external view returns (IProtocolFeesCollector); + + /** + * @dev Safety mechanism to pause most Vault operations in the event of an emergency - typically detection of an + * error in some part of the system. + * + * The Vault can only be paused during an initial time period, after which pausing is forever disabled. + * + * While the contract is paused, the following features are disabled: + * - depositing and transferring internal balance + * - transferring external balance (using the Vault's allowance) + * - swaps + * - joining Pools + * - Asset Manager interactions + * + * Internal Balance can still be withdrawn, and Pools exited. + */ + function setPaused(bool paused) external; + + /** + * @dev Returns the Vault's WETH instance. + */ + function WETH() external view returns (IWETH); + // solhint-disable-previous-line func-name-mixedcase +} diff --git a/foundry/lib/balancer-labs/v2-interfaces/package.json b/foundry/lib/balancer-labs/v2-interfaces/package.json new file mode 100644 index 0000000..1608cae --- /dev/null +++ b/foundry/lib/balancer-labs/v2-interfaces/package.json @@ -0,0 +1,58 @@ +{ + "name": "@balancer-labs/v2-interfaces", + "version": "0.4.0", + "description": "V2 Interfaces", + "license": "GPL-3.0-only", + "homepage": "https://github.com/balancer-labs/balancer-v2-monorepo/tree/master/pkg/interfaces#readme", + "repository": { + "type": "git", + "url": "https://github.com/balancer-labs/balancer-v2-monorepo.git", + "directory": "pkg/interfaces" + }, + "bugs": { + "url": "https://github.com/balancer-labs/balancer-v2-monorepo/issues" + }, + "files": [ + "contracts/**/*" + ], + "scripts": { + "build": "yarn compile", + "compile": "hardhat compile && rm -rf artifacts/build-info", + "compile:watch": "nodemon --ext sol --exec yarn compile", + "lint": "yarn lint:solidity && yarn lint:typescript", + "lint:solidity": "solhint 'contracts/**/*.sol'", + "lint:typescript": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ../../.eslintignore --max-warnings 0" + }, + "devDependencies": { + "@nomiclabs/hardhat-ethers": "^2.2.1", + "@nomiclabs/hardhat-waffle": "^2.0.3", + "@types/chai": "^4.3.3", + "@types/lodash": "^4.14.186", + "@types/mocha": "^10.0.0", + "@types/node": "^14.14.31", + "@typescript-eslint/eslint-plugin": "^5.41.0", + "@typescript-eslint/parser": "^5.41.0", + "chai": "^4.3.6", + "decimal.js": "^10.4.2", + "eslint": "^8.26.0", + "eslint-plugin-mocha-no-only": "^1.1.1", + "eslint-plugin-prettier": "^4.2.1", + "ethereum-waffle": "^3.4.4", + "ethers": "^5.7.2", + "hardhat": "^2.12.5", + "hardhat-ignore-warnings": "^0.2.4", + "lodash.frompairs": "^4.0.1", + "lodash.pick": "^4.4.0", + "lodash.range": "^3.2.0", + "lodash.times": "^4.3.2", + "lodash.zip": "^4.2.0", + "mocha": "^10.1.0", + "nodemon": "^2.0.20", + "prettier": "^2.7.1", + "prettier-plugin-solidity": "v1.0.0-alpha.59", + "solhint": "^3.2.0", + "solhint-plugin-prettier": "^0.0.4", + "ts-node": "^10.9.1", + "typescript": "^4.0.2" + } +} \ No newline at end of file diff --git a/foundry/remappings.txt b/foundry/remappings.txt index f4b9a08..6d33fc1 100644 --- a/foundry/remappings.txt +++ b/foundry/remappings.txt @@ -2,4 +2,5 @@ @interfaces/=interfaces/ @permit2/=lib/permit2/ @src/=src/ -@uniswap-v2/=lib/v2-core/ \ No newline at end of file +@uniswap-v2/=lib/v2-core/ +@balancer-labs/v2-interfaces/=lib/balancer-labs/v2-interfaces/ \ No newline at end of file diff --git a/foundry/src/executors/BalancerV2Executor.sol b/foundry/src/executors/BalancerV2Executor.sol new file mode 100644 index 0000000..10b2826 --- /dev/null +++ b/foundry/src/executors/BalancerV2Executor.sol @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.28; + +import "@interfaces/IExecutor.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@balancer-labs/v2-interfaces/contracts/vault/IAsset.sol"; +import "@balancer-labs/v2-interfaces/contracts/vault/IVault.sol"; + + +error BalancerV2Executor__InvalidDataLength(); + +contract BalancerV2Executor is IExecutor { + using SafeERC20 for IERC20; + + address private constant VAULT = 0xBA12222222228d8Ba445958a75a0704d566BF2C8; + + function swap(uint256 givenAmount, bytes calldata data) + external + returns (uint256 calculatedAmount) + { + + ( + IERC20 tokenIn, + IERC20 tokenOut, + bytes32 poolId, + address receiver, + bool exactOut, + bool needsApproval + ) = _decodeData(data); + + + if (needsApproval) { + tokenIn.safeApprove(VAULT, type(uint256).max); + } + + + IVault.SingleSwap memory singleSwap = IVault.SingleSwap({ + poolId: poolId, + kind: exactOut ? IVault.SwapKind.GIVEN_OUT : IVault.SwapKind.GIVEN_IN, + assetIn: IAsset(address(tokenIn)), + assetOut: IAsset(address(tokenOut)), + amount: givenAmount, + userData: "" + }); + + + IVault.FundManagement memory funds = IVault.FundManagement({ + sender: address(this), + fromInternalBalance: false, + recipient: payable(receiver), + toInternalBalance: false + }); + + + uint256 limit = exactOut ? type(uint256).max : 0; + + + calculatedAmount = IVault(VAULT).swap( + singleSwap, + funds, + limit, + block.timestamp + ); + } + + function _decodeData(bytes calldata data) + internal + pure + returns ( + IERC20 tokenIn, + IERC20 tokenOut, + bytes32 poolId, + address receiver, + bool exactOut, + bool needsApproval + ) + { + // Verify data length (20 + 20 + 32 + 20 + 1 + 1 = 94 bytes) + if (data.length != 94) { + revert BalancerV2Executor__InvalidDataLength(); + } + + + tokenIn = IERC20(address(bytes20(data[0:20]))); + tokenOut = IERC20(address(bytes20(data[20:40]))); + poolId = bytes32(data[40:72]); + receiver = address(bytes20(data[72:92])); + exactOut = uint8(data[92]) > 0; + needsApproval = uint8(data[93]) > 0; + } +} \ No newline at end of file