├── .commitlintrc.json ├── .eslintrc.json ├── .github └── workflows │ ├── lint_pr.yml │ ├── pr.yml │ └── release.yml ├── .gitignore ├── .husky ├── .gitignore ├── commit-msg └── pre-commit ├── .nvmrc ├── .prettierignore ├── .releaserc.json ├── .vscode ├── extensions.json └── settings.json ├── ContributionAgreement ├── LICENSE ├── README.md ├── bindings ├── AdapterData.sol ├── CreditConfigLive.sol ├── PriceFeedDataLive.sol ├── SupportedContracts.sol ├── Tokens.sol ├── TokensDataLive.sol ├── generate.ts └── generate_decimals.ts ├── config ├── adapters.ts ├── creditManagers.ts └── liveTests.ts ├── contracts ├── adapters │ ├── LICENSE │ ├── aave │ │ ├── AaveV2_LendingPoolAdapter.sol │ │ ├── AaveV2_WrappedATokenAdapter.sol │ │ ├── WrappedAToken.sol │ │ └── WrappedATokenGateway.sol │ ├── balancer │ │ └── BalancerV2VaultAdapter.sol │ ├── compound │ │ ├── CEtherGateway.sol │ │ ├── CompoundV2_CErc20Adapter.sol │ │ ├── CompoundV2_CEtherAdapter.sol │ │ └── CompoundV2_CTokenAdapter.sol │ ├── convex │ │ ├── ConvexV1_BaseRewardPool.sol │ │ ├── ConvexV1_Booster.sol │ │ ├── ConvexV1_ClaimZap.sol │ │ └── ConvexV1_StakedPositionToken.sol │ ├── curve │ │ ├── CurveV1_2.sol │ │ ├── CurveV1_3.sol │ │ ├── CurveV1_4.sol │ │ ├── CurveV1_Base.sol │ │ ├── CurveV1_DepositZap.sol │ │ ├── CurveV1_stETH.sol │ │ └── CurveV1_stETHGateway.sol │ ├── euler │ │ └── EulerV1_ETokenAdapter.sol │ ├── lido │ │ ├── LidoV1.sol │ │ ├── LidoV1_WETHGateway.sol │ │ ├── WstETHGateway.sol │ │ └── WstETHV1.sol │ ├── uniswap │ │ ├── UniswapConnectorChecker.sol │ │ ├── UniswapV2.sol │ │ └── UniswapV3.sol │ └── yearn │ │ └── YearnV2.sol ├── factories │ └── CreditManagerFactory.sol ├── integrations │ ├── TokenType.sol │ ├── aave │ │ ├── DataTypes.sol │ │ ├── IAToken.sol │ │ └── ILendingPool.sol │ ├── balancer │ │ ├── FixedPoint.sol │ │ ├── IAsset.sol │ │ ├── IBalancerStablePool.sol │ │ ├── IBalancerV2Vault.sol │ │ ├── IBalancerWeightedPool.sol │ │ └── LogExpMath.sol │ ├── compound │ │ ├── ICErc20.sol │ │ ├── ICEther.sol │ │ └── ICToken.sol │ ├── convex │ │ ├── IBaseRewardPool.sol │ │ ├── IBooster.sol │ │ ├── IClaimZap.sol │ │ ├── IConvexToken.sol │ │ ├── IRewards.sol │ │ └── Interfaces.sol │ ├── curve │ │ ├── ICRVToken.sol │ │ ├── ICurvePool.sol │ │ ├── ICurvePoolStETH.sol │ │ ├── ICurvePool_2.sol │ │ ├── ICurvePool_3.sol │ │ ├── ICurvePool_4.sol │ │ └── ICurveRegistry.sol │ ├── euler │ │ └── IEToken.sol │ ├── lido │ │ ├── ILidoOracle.sol │ │ ├── IstETH.sol │ │ ├── IwstETH.sol │ │ └── IwstETHGateway.sol │ ├── uniswap │ │ ├── BytesLib.sol │ │ ├── IQuoter.sol │ │ ├── IUniswapV2Router01.sol │ │ ├── IUniswapV2Router02.sol │ │ ├── IUniswapV3.sol │ │ ├── IUniswapV3SwapCallback.sol │ │ ├── LICENSE │ │ └── Path.sol │ └── yearn │ │ └── IYVault.sol ├── interfaces │ ├── LICENSE │ ├── aave │ │ ├── IAaveV2_LendingPoolAdapter.sol │ │ ├── IAaveV2_WrappedATokenAdapter.sol │ │ ├── IWrappedAToken.sol │ │ └── IWrappedATokenGateway.sol │ ├── balancer │ │ └── IBalancerV2VaultAdapter.sol │ ├── compound │ │ └── ICompoundV2_CTokenAdapter.sol │ ├── convex │ │ ├── IConvexV1BaseRewardPoolAdapter.sol │ │ └── IConvexV1BoosterAdapter.sol │ ├── curve │ │ ├── ICurveV1Adapter.sol │ │ ├── ICurveV1_2AssetsAdapter.sol │ │ ├── ICurveV1_3AssetsAdapter.sol │ │ └── ICurveV1_4AssetsAdapter.sol │ ├── euler │ │ └── IEulerV1_ETokenAdapter.sol │ ├── lido │ │ ├── ILidoV1Adapter.sol │ │ └── IwstETHV1Adapter.sol │ ├── uniswap │ │ ├── IUniswapConnectorChecker.sol │ │ ├── IUniswapV2Adapter.sol │ │ └── IUniswapV3Adapter.sol │ └── yearn │ │ └── IYearnV2Adapter.sol ├── multicall │ ├── aave │ │ ├── AaveV2_LendingPoolCalls.sol │ │ └── AaveV2_WrappedATokenCalls.sol │ ├── balancer │ │ └── BalancerV2_Calls.sol │ ├── compound │ │ └── CompoundV2_Calls.sol │ ├── convex │ │ ├── ConvexV1_BaseRewardPoolCalls.sol │ │ └── ConvexV1_BoosterCalls.sol │ ├── curve │ │ └── CurveV1_Calls.sol │ ├── euler │ │ └── EulerV1_Calls.sol │ ├── lido │ │ ├── LidoV1_Calls.sol │ │ └── WstETHV1_Calls.sol │ ├── uniswap │ │ ├── UniswapV2_Calls.sol │ │ └── UniswapV3_Calls.sol │ └── yearn │ │ └── YearnV2_Calls.sol ├── oracles │ ├── aave │ │ └── AavePriceFeed.sol │ ├── balancer │ │ ├── BPTStablePriceFeed.sol │ │ ├── BPTWeightedPriceFeed.sol │ │ └── BPTWeightedPriceFeedSetup.sol │ ├── compound │ │ └── CompoundPriceFeed.sol │ ├── curve │ │ ├── AbstractCurveLPPriceFeed.sol │ │ ├── CurveCryptoLPPriceFeed.sol │ │ ├── CurveLP2PriceFeed.sol │ │ ├── CurveLP3PriceFeed.sol │ │ └── CurveLP4PriceFeed.sol │ ├── euler │ │ └── EulerPriceFeed.sol │ ├── lido │ │ └── WstETHPriceFeed.sol │ └── yearn │ │ └── YearnPriceFeed.sol └── test │ ├── adapters │ ├── AdapterTestHelper.sol │ ├── balancer │ │ └── BalancerV2VaultAdapter.t.sol │ ├── convex │ │ ├── ConvexAdapterHelper.sol │ │ ├── ConvexV1_BaseRewardPool.t.sol │ │ ├── ConvexV1_Booster.t.sol │ │ └── ConvexV1_ClaimZap.t.sol │ ├── curve │ │ ├── CurveV1AdapterBaseMetapoolTest.t.sol │ │ ├── CurveV1AdapterBaseTest.t.sol │ │ ├── CurveV1AdapterCryptoTest.t.sol │ │ ├── CurveV1AdapterHelper.sol │ │ ├── CurveV1Adapter_2AssetsTest.t.sol │ │ ├── CurveV1Adapter_3AssetsTest.t.sol │ │ ├── CurveV1Adapter_4AssetsTest.t.sol │ │ └── CurveV1StETHTest.t.sol │ ├── lido │ │ ├── LidoV1Adapter.t.sol │ │ ├── WstETHV1Adapter.t.sol │ │ └── WstETHV1Gateway.t.sol │ ├── mainnet │ │ ├── Live_3CRVEquivalenceTest.sol │ │ ├── Live_ConvexEquivalenceTest.t.sol │ │ ├── Live_FraxUsdcEquivalenceTest.sol │ │ ├── Live_Gusd3CRVEquivalenceTest.sol │ │ ├── Live_LidoEquivalenceTest.sol │ │ ├── Live_MetapoolEquivalenceTest.sol │ │ ├── Live_SUSDEquivalenceTest.sol │ │ ├── Live_YearnEquivalenceTest.sol │ │ ├── Live_stETHEquivalenceTest.sol │ │ └── WstETHV1Adapter.t.sol │ ├── uniswap │ │ ├── UniswapV2Adapter.t.sol │ │ └── UniswapV3Adapter.t.sol │ └── yearn │ │ └── YearnV2Adapter.t.sol │ ├── config │ ├── AdapterData.sol │ ├── CreditConfig.sol │ ├── CreditConfigLive.sol │ ├── PriceFeedDataLive.sol │ ├── SupportedContracts.sol │ ├── Tokens.sol │ ├── TokensData.sol │ └── TokensDataLive.sol │ ├── credit │ └── CreditFacade.t.sol │ ├── helpers │ ├── BalanceComparator.sol │ ├── BalanceHelper.sol │ └── CreditFacadeTestHelper.sol │ ├── lib │ ├── LICENSE │ ├── Path.sol │ └── constants.sol │ ├── mocks │ ├── credit │ │ ├── CreditManagerLiveMock.sol │ │ └── CreditManagerMockFactory.sol │ ├── integrations │ │ ├── BPTMock.sol │ │ ├── BPTStableMock.sol │ │ ├── BalancerVaultMock.sol │ │ ├── ConvexBaseRewardPoolMock.sol │ │ ├── ConvexBoosterMock.sol │ │ ├── ConvexClaimZapMock.sol │ │ ├── ConvexExtraRewardPoolMock.sol │ │ ├── ConvexTokenRewardContractMock.sol │ │ ├── CurveV1MetapoolMock.sol │ │ ├── CurveV1Mock.sol │ │ ├── CurveV1Mock_2Assets.sol │ │ ├── CurveV1Mock_3Assets.sol │ │ ├── CurveV1Mock_4Assets.sol │ │ ├── CurveV1StETHMock.sol │ │ ├── LidoMock.sol │ │ ├── UniswapV2Mock.sol │ │ ├── UniswapV3Mock.sol │ │ ├── WstETHV1Mock.sol │ │ └── YearnV2Mock.sol │ └── token │ │ ├── StETHMock.sol │ │ ├── WETHMock.sol │ │ └── cERC20Mock.sol │ ├── oracles │ ├── BPTStablePriceFeed.t.sol │ ├── BPTWeightedPriceFeed.t.sol │ ├── CurveCryptoLPPriceFeed.t.sol │ ├── CurveLPPriceFeed.t.sol │ ├── WstETHPriceFeed.t.sol │ └── YearnPriceFeed.t.sol │ └── suites │ ├── AdapterDeployer.sol │ ├── LiveEnvHelper.sol │ ├── LiveEnvTestSuite.sol │ ├── LivePriceFeedDeployer.sol │ ├── TokensTestSuite.sol │ └── WstETHPoolSetup.sol ├── core ├── creditFilter.ts └── pool.ts ├── foundry.toml ├── hardhat.config.ts ├── header.png ├── package.json ├── scripts ├── abigen.sh ├── fork-goerli.sh ├── fork.sh └── trimport.sh ├── tsconfig.json └── yarn.lock /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["@gearbox-protocol/eslint-config"] 4 | } 5 | -------------------------------------------------------------------------------- /.github/workflows/lint_pr.yml: -------------------------------------------------------------------------------- 1 | name: "Lint PR" 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - reopened 8 | - edited 9 | - synchronize 10 | 11 | jobs: 12 | main: 13 | name: Validate PR title 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: amannn/action-semantic-pull-request@v4 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: Check PR 2 | 3 | on: 4 | pull_request: 5 | types: [opened, reopened, synchronize] 6 | 7 | env: 8 | HUSKY: 0 9 | CI: true 10 | 11 | jobs: 12 | checks: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | 18 | - name: Setup node.js 19 | uses: actions/setup-node@v3 20 | with: 21 | cache: "yarn" 22 | node-version-file: ".nvmrc" 23 | 24 | - name: Configure access to private npm packages 25 | run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc 26 | 27 | - name: Install dependencies 28 | run: | 29 | yarn install --frozen-lockfile 30 | 31 | - name: Install Foundry 32 | uses: foundry-rs/foundry-toolchain@v1 33 | with: 34 | version: nightly 35 | 36 | - name: Run forge unit tests 37 | run: forge test 38 | 39 | - name: Run forge integration tests 40 | run: forge t --match-test _live_ --fork-url ${{ secrets.ETH_GOERLI_PROVIDER }} 41 | 42 | - name: Perform checks 43 | run: | 44 | yarn typecheck:ci 45 | yarn lint:ci 46 | yarn prettier:ci 47 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - "main" 7 | - "next" 8 | 9 | env: 10 | HUSKY: 0 11 | CI: true 12 | 13 | jobs: 14 | release: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - uses: actions/setup-node@v3 21 | with: 22 | cache: "yarn" 23 | node-version-file: ".nvmrc" 24 | 25 | - name: Configure access to private npm packages 26 | run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc 27 | 28 | # prepare script runs before publish, and it needs husky 29 | - name: Install dependencies 30 | run: | 31 | yarn install --frozen-lockfile 32 | 33 | - name: Semantic Release 34 | uses: cycjimmy/semantic-release-action@v3 35 | env: 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 37 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /forge-out 3 | .DS_Store 4 | cache -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | artifacts 3 | cache 4 | types 5 | forge-out 6 | -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "branches": [ 3 | { 4 | "name": "main" 5 | }, 6 | { 7 | "name": "next", 8 | "channel": "next", 9 | "prerelease": "next" 10 | } 11 | ], 12 | "plugins": [ 13 | "@semantic-release/commit-analyzer", 14 | "@semantic-release/release-notes-generator", 15 | "@semantic-release/npm", 16 | "@semantic-release/github" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "esbenp.prettier-vscode", 4 | "nomicfoundation.hardhat-solidity", 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[json]": { 3 | "editor.defaultFormatter": "esbenp.prettier-vscode" 4 | }, 5 | "[solidity]": { 6 | "editor.defaultFormatter": "JuanBlanco.solidity" 7 | }, 8 | 9 | "editor.defaultFormatter": "esbenp.prettier-vscode", 10 | "editor.formatOnSave": true, 11 | "editor.tabSize": 4, 12 | "eslint.validate": ["javascript", "typescript"], 13 | "files.eol": "\n", 14 | "solidity.formatter": "forge", 15 | "solidity.packageDefaultDependenciesContractsDirectory": "contracts", 16 | "solidity.packageDefaultDependenciesDirectory": "node_modules", 17 | "solidity.remappings": [ 18 | "ds-test/=lib/ds-test/src/", 19 | "hardhat/=node_modules/hardhat/", 20 | "forge-std/=node_modules/forge-std/", 21 | "@chainlink/=node_modules/@chainlink/", 22 | "@ensdomains/=node_modules/@ensdomains/", 23 | "@openzeppelin/=node_modules/@openzeppelin/", 24 | "@gearbox-protocol=node_modules/@gearbox-protocol/" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /bindings/AdapterData.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import { Tokens } from "./Tokens.sol"; 7 | import { Contracts } from "./SupportedContracts.sol"; 8 | import { AdapterType } from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 9 | 10 | struct SimpleAdapter { 11 | Contracts targetContract; 12 | AdapterType adapterType; 13 | } 14 | 15 | struct CurveAdapter { 16 | Contracts targetContract; 17 | AdapterType adapterType; 18 | Tokens lpToken; 19 | Contracts basePool; 20 | } 21 | 22 | struct CurveStETHAdapter { 23 | Contracts curveETHGateway; 24 | AdapterType adapterType; 25 | Tokens lpToken; 26 | } 27 | 28 | struct CurveWrapper { 29 | Contracts targetContract; 30 | AdapterType adapterType; 31 | Tokens lpToken; 32 | uint256 nCoins; 33 | } 34 | 35 | struct ConvexBasePoolAdapter { 36 | Contracts targetContract; 37 | AdapterType adapterType; 38 | Tokens stakedToken; 39 | } 40 | 41 | contract AdapterData { 42 | SimpleAdapter[] simpleAdapters; 43 | CurveAdapter[] curveAdapters; 44 | CurveStETHAdapter curveStEthAdapter; 45 | CurveWrapper[] curveWrappers; 46 | ConvexBasePoolAdapter[] convexBasePoolAdapters; 47 | 48 | constructor() { 49 | // $ADAPTERS_LIST 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /bindings/CreditConfigLive.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import { Tokens } from "./Tokens.sol"; 7 | import { Contracts } from "./SupportedContracts.sol"; 8 | 9 | /// @dev A struct containing parameters for a recognized collateral token in the system 10 | struct CollateralTokenHuman { 11 | /// @dev Address of the collateral token 12 | Tokens token; 13 | /// @dev Address of the liquidation threshold 14 | uint16 liquidationThreshold; 15 | } 16 | 17 | /// @dev A struct representing the initial Credit Manager configuration parameters 18 | struct CreditManagerHumanOpts { 19 | /// @dev The minimal debt principal amount 20 | uint128 minBorrowedAmount; 21 | /// @dev The maximal debt principal amount 22 | uint128 maxBorrowedAmount; 23 | /// @dev The initial list of collateral tokens to allow 24 | CollateralTokenHuman[] collateralTokens; 25 | /// @dev Address of DegenNFT, address(0) if whitelisted mode is not used 26 | address degenNFT; 27 | /// @dev Address of BlacklistHelper, address(0) if the underlying is not blacklistable 28 | address blacklistHelper; 29 | /// @dev Whether the Credit Manager is connected to an expirable pool (and the CreditFacade is expirable) 30 | bool expirable; 31 | /// @dev Whether to skip normal initialization - used for new Credit Configurators that are deployed for existing CMs 32 | bool skipInit; 33 | /// @dev Contracts which should become adapters 34 | Contracts[] contracts; 35 | } 36 | 37 | contract CreditConfigLive { 38 | mapping(Tokens => CreditManagerHumanOpts) creditManagerHumanOpts; 39 | 40 | constructor() { 41 | CreditManagerHumanOpts storage cm; 42 | 43 | // $CREDIT_MANAGER_CONFIG 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /bindings/PriceFeedDataLive.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import { Tokens } from "./Tokens.sol"; 7 | import { Contracts } from "./SupportedContracts.sol"; 8 | 9 | struct ChainlinkPriceFeedData { 10 | Tokens token; 11 | address priceFeed; 12 | } 13 | 14 | struct CurvePriceFeedData { 15 | Tokens lpToken; 16 | Tokens[] assets; 17 | Contracts pool; 18 | } 19 | 20 | struct CurveLikePriceFeedData { 21 | Tokens lpToken; 22 | Tokens curveToken; 23 | } 24 | 25 | struct SingeTokenPriceFeedData { 26 | Tokens token; 27 | } 28 | 29 | contract PriceFeedDataLive { 30 | ChainlinkPriceFeedData[] chainlinkPriceFeeds; 31 | SingeTokenPriceFeedData[] zeroPriceFeeds; 32 | CurvePriceFeedData[] curvePriceFeeds; 33 | CurveLikePriceFeedData[] likeCurvePriceFeeds; 34 | SingeTokenPriceFeedData[] yearnPriceFeeds; 35 | SingeTokenPriceFeedData wstethPriceFeed; 36 | 37 | constructor(uint8 networkId) { 38 | if (networkId == 1) { 39 | // $CHAINLINK_PRICE_FEEDS 40 | // $CURVE_LIKE_PRICE_FEEDS 41 | } else if (networkId == 2) { 42 | // $GOERLI_CHAINLINK_PRICE_FEEDS 43 | // $GOERLI_CURVE_LIKE_PRICE_FEEDS 44 | } 45 | 46 | // $ZERO_PRICE_FEEDS 47 | // $CURVE_PRICE_FEEDS 48 | // $YEARN_PRICE_FEEDS 49 | // $WSTETH_PRICE_FEED 50 | } 51 | 52 | function assets(Tokens t1, Tokens t2) 53 | internal 54 | pure 55 | returns (Tokens[] memory result) 56 | { 57 | result = new Tokens[](2); 58 | result[0] = t1; 59 | result[1] = t2; 60 | } 61 | 62 | function assets( 63 | Tokens t1, 64 | Tokens t2, 65 | Tokens t3 66 | ) internal pure returns (Tokens[] memory result) { 67 | result = new Tokens[](3); 68 | result[0] = t1; 69 | result[1] = t2; 70 | result[2] = t3; 71 | } 72 | 73 | function assets( 74 | Tokens t1, 75 | Tokens t2, 76 | Tokens t3, 77 | Tokens t4 78 | ) internal pure returns (Tokens[] memory result) { 79 | result = new Tokens[](4); 80 | result[0] = t1; 81 | result[1] = t2; 82 | result[2] = t3; 83 | result[3] = t4; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /bindings/SupportedContracts.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | import { CheatCodes, HEVM_ADDRESS } from "@gearbox-protocol/core-v2/contracts/test/lib/cheatCodes.sol"; 6 | 7 | interface ISupportedContracts { 8 | function addressOf(Contracts c) external view returns (address); 9 | 10 | function nameOf(Contracts c) external view returns (string memory); 11 | 12 | function contractIndex(address) external view returns (Contracts); 13 | 14 | function contractCount() external view returns (uint256); 15 | } 16 | 17 | enum Contracts { 18 | NO_CONTRACT 19 | // $CONTRACTS_ENUM$ 20 | } 21 | 22 | struct ContractData { 23 | Contracts id; 24 | address addr; 25 | string name; 26 | } 27 | 28 | contract SupportedContracts is ISupportedContracts { 29 | CheatCodes evm = CheatCodes(HEVM_ADDRESS); 30 | 31 | mapping(Contracts => address) public override addressOf; 32 | mapping(Contracts => string) public override nameOf; 33 | mapping(address => Contracts) public override contractIndex; 34 | 35 | uint256 public override contractCount; 36 | 37 | constructor(uint8 networkId) { 38 | ContractData[] memory cd; 39 | if (networkId == 1) { 40 | // $CONTRACTS_ADDRESSES$ 41 | } else if (networkId == 2) { 42 | // $GOERLI_CONTRACTS_ADDRESSES$ 43 | } 44 | uint256 len = cd.length; 45 | contractCount = len; 46 | unchecked { 47 | for (uint256 i; i < len; ++i) { 48 | addressOf[cd[i].id] = cd[i].addr; 49 | nameOf[cd[i].id] = cd[i].name; 50 | contractIndex[cd[i].addr] = cd[i].id; 51 | 52 | evm.label(cd[i].addr, cd[i].name); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /bindings/Tokens.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | /// @dev c-Tokens and LUNA are added for unit test purposes 7 | enum Tokens { 8 | NO_TOKEN, 9 | cDAI, 10 | cUSDC, 11 | cUSDT, 12 | cLINK, 13 | LUNA 14 | // $TOKENS$ 15 | } 16 | -------------------------------------------------------------------------------- /bindings/TokensDataLive.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import { Tokens } from "./Tokens.sol"; 7 | import { TokenData } from "../suites/TokensTestSuite.sol"; 8 | import { TokenType } from "../../integrations/TokenType.sol"; 9 | 10 | contract TokensDataLive { 11 | TokenData[] tokenData; 12 | 13 | constructor(uint8 networkId) { 14 | TokenData[] memory td; 15 | 16 | if (networkId == 1) { 17 | // $TOKEN_ADDRESSES$ 18 | } else if (networkId == 2) { 19 | // $GOERLI_TOKEN_ADDRESSES$ 20 | } 21 | 22 | for (uint256 i = 0; i < td.length; ++i) { 23 | tokenData.push(td[i]); 24 | } 25 | } 26 | 27 | function getTokenData() external view returns (TokenData[] memory) { 28 | return tokenData; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /bindings/generate_decimals.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IERC20Metadata__factory, 3 | SupportedToken, 4 | supportedTokens, 5 | tokenDataByNetwork, 6 | } from "@gearbox-protocol/sdk"; 7 | import * as fs from "fs"; 8 | import { ethers } from "hardhat"; 9 | 10 | async function generateTokens() { 11 | const accounts = await ethers.getSigners(); 12 | const deployer = accounts[0]; 13 | 14 | const tokenList: Array = []; 15 | for (let token of Object.keys(supportedTokens)) { 16 | const address = tokenDataByNetwork.Mainnet[token as SupportedToken]; 17 | const decimals = await IERC20Metadata__factory.connect( 18 | address, 19 | deployer, 20 | ).decimals(); 21 | tokenList.push(`"${token}": ${decimals.toString()}`); 22 | } 23 | 24 | const file = `import { SupportedToken } from "./token"; 25 | 26 | export const decimals: Record = { 27 | ${tokenList.join(",\n")} 28 | } `; 29 | 30 | fs.writeFileSync("./decimals.ts", file); 31 | } 32 | 33 | generateTokens() 34 | .then(() => { 35 | process.exit(0); 36 | }) 37 | .catch(error => { 38 | console.error(error); 39 | process.exit(1); 40 | }); 41 | -------------------------------------------------------------------------------- /config/adapters.ts: -------------------------------------------------------------------------------- 1 | import { SupportedContract } from "@gearbox-protocol/sdk"; 2 | 3 | export const adapters: Array = [ 4 | /// SWAPPERS 5 | "UNISWAP_V3_ROUTER", 6 | "UNISWAP_V2_ROUTER", 7 | "SUSHISWAP_ROUTER", 8 | "LIDO_STETH_GATEWAY", 9 | 10 | // CURVE 11 | "CURVE_3CRV_POOL", 12 | "CURVE_FRAX_USDC_POOL", 13 | "CURVE_STETH_GATEWAY", 14 | "CURVE_FRAX_POOL", 15 | "CURVE_SUSD_POOL", 16 | "CURVE_LUSD_POOL", 17 | "CURVE_GUSD_POOL", 18 | "CURVE_SUSD_DEPOSIT", 19 | 20 | // YEARN 21 | "YEARN_DAI_VAULT", 22 | "YEARN_USDC_VAULT", 23 | "YEARN_WETH_VAULT", 24 | "YEARN_WBTC_VAULT", 25 | "YEARN_CURVE_FRAX_VAULT", 26 | "YEARN_CURVE_STETH_VAULT", 27 | 28 | // CONVEX 29 | "CONVEX_FRAX3CRV_POOL", 30 | "CONVEX_LUSD3CRV_POOL", 31 | "CONVEX_GUSD_POOL", 32 | "CONVEX_SUSD_POOL", 33 | "CONVEX_3CRV_POOL", 34 | "CONVEX_FRAX_USDC_POOL", 35 | "CONVEX_STECRV_POOL", 36 | "CONVEX_BOOSTER", 37 | "CONVEX_CLAIM_ZAP", 38 | 39 | // UNIVERSAL 40 | "UNIVERSAL_ADAPTER", 41 | ]; 42 | -------------------------------------------------------------------------------- /config/liveTests.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022. Gearbox 3 | */ 4 | import { CMConfig } from "../core/pool"; 5 | import { mainnetCreditManagers as mcm } from "./creditManagers"; 6 | 7 | export const mainnetCreditManagers: Array = mcm; 8 | -------------------------------------------------------------------------------- /contracts/adapters/aave/WrappedATokenGateway.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IPool4626} from "@gearbox-protocol/core-v2/contracts/interfaces/IPool4626.sol"; 7 | import {IAddressProvider} from "@gearbox-protocol/core-v2/contracts/interfaces/IAddressProvider.sol"; 8 | import {IContractsRegister} from "@gearbox-protocol/core-v2/contracts/interfaces/IContractsRegister.sol"; 9 | import {ZeroAddressException} from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; 10 | 11 | import {IAToken} from "../../integrations/aave/IAToken.sol"; 12 | import {IWrappedAToken} from "../../interfaces/aave/IWrappedAToken.sol"; 13 | import {IWrappedATokenGateway} from "../../interfaces/aave/IWrappedATokenGateway.sol"; 14 | 15 | /// @title waToken Gateway 16 | /// @notice Allows LPs to add/remove aTokens to/from waToken liquidity pool 17 | contract WrappedATokenGateway is IWrappedATokenGateway { 18 | /// @notice waToken pool 19 | IPool4626 public immutable override pool; 20 | 21 | /// @notice waToken address 22 | IWrappedAToken public immutable override waToken; 23 | 24 | /// @notice aToken address 25 | IAToken public immutable override aToken; 26 | 27 | /// @notice Constructor 28 | /// @param _pool waToken pool address 29 | constructor(address _pool) { 30 | if (_pool == address(0)) revert ZeroAddressException(); 31 | 32 | IContractsRegister cr = 33 | IContractsRegister(IAddressProvider(IPool4626(_pool).addressProvider()).getContractsRegister()); 34 | if (!cr.isPool(_pool)) revert NotRegisteredPoolException(); 35 | 36 | pool = IPool4626(_pool); 37 | waToken = IWrappedAToken(pool.underlyingToken()); 38 | aToken = waToken.aToken(); 39 | 40 | waToken.approve(address(pool), type(uint256).max); // non-spendable 41 | aToken.approve(address(waToken), type(uint256).max); // spendable 42 | } 43 | 44 | /// @notice Deposit aTokens into waToken liquidity pool 45 | /// @dev Gateway must be approved to spend aTokens from `msg.sender` before the call 46 | /// @param assets Amount of aTokens to deposit to the pool 47 | /// @param receiver Account that should receive dTokens 48 | /// @param referralCode Referral code, for potential rewards 49 | /// @return shares Amount of dTokens minted to `receiver` 50 | function depositReferral(uint256 assets, address receiver, uint16 referralCode) 51 | external 52 | override 53 | returns (uint256 shares) 54 | { 55 | aToken.transferFrom(msg.sender, address(this), assets); 56 | 57 | _ensureWrapperAllowance(assets); 58 | uint256 waTokenAmount = waToken.deposit(assets); 59 | 60 | shares = pool.depositReferral(waTokenAmount, receiver, referralCode); 61 | } 62 | 63 | /// @notice Redeem aTokens from waToken liquidity pool 64 | /// @dev Gateway must be approved to spend dTokens from `owner` before the call 65 | /// @param shares Amount of dTokens to burn 66 | /// @param receiver Account that should receive aTokens 67 | /// @param owner Account to burn dTokens from 68 | /// @return assets Amount of aTokens sent to `receiver` 69 | function redeem(uint256 shares, address receiver, address owner) external override returns (uint256 assets) { 70 | uint256 waTokenAmount = pool.redeem(shares, address(this), owner); 71 | 72 | assets = waToken.withdraw(waTokenAmount); 73 | aToken.transfer(receiver, assets); 74 | } 75 | 76 | /// @dev Sets waToken's allowance for gateway's aTokens to `type(uint256).max` if it falls below `amount` 77 | function _ensureWrapperAllowance(uint256 amount) internal { 78 | if (aToken.allowance(address(this), address(waToken)) < amount) { 79 | aToken.approve(address(waToken), type(uint256).max); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /contracts/adapters/convex/ConvexV1_StakedPositionToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 7 | import {PhantomERC20} from "@gearbox-protocol/core-v2/contracts/tokens/PhantomERC20.sol"; 8 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 9 | 10 | /// @title ConvexStakedPositionToken 11 | /// @dev Represents the balance of the staking token position in Convex pools 12 | contract ConvexStakedPositionToken is PhantomERC20 { 13 | address public immutable pool; 14 | 15 | /// @dev Constructor 16 | /// @param _pool The Convex pool where the balance is tracked 17 | /// @param _lptoken The Convex LP token that is staked in the pool 18 | constructor(address _pool, address _lptoken) 19 | PhantomERC20( 20 | _lptoken, 21 | string(abi.encodePacked("Convex Staked Position ", IERC20Metadata(_lptoken).name())), 22 | string(abi.encodePacked("stk", IERC20Metadata(_lptoken).symbol())), 23 | IERC20Metadata(_lptoken).decimals() 24 | ) 25 | { 26 | pool = _pool; 27 | } 28 | 29 | /// @dev Returns the amount of Convex LP tokens staked in the pool 30 | /// @param account The account for which the calculation is performed 31 | function balanceOf(address account) public view returns (uint256) { 32 | return IERC20(pool).balanceOf(account); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/adapters/curve/CurveV1_2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter, AdapterType} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | import {N_COINS} from "../../integrations/curve/ICurvePool_2.sol"; 9 | import {ICurveV1_2AssetsAdapter} from "../../interfaces/curve/ICurveV1_2AssetsAdapter.sol"; 10 | import {CurveV1AdapterBase} from "./CurveV1_Base.sol"; 11 | 12 | /// @title Curve V1 2 assets adapter 13 | /// @notice Implements logic allowing to interact with Curve pools with 2 assets 14 | contract CurveV1Adapter2Assets is CurveV1AdapterBase, ICurveV1_2AssetsAdapter { 15 | function _gearboxAdapterType() external pure virtual override(CurveV1AdapterBase, IAdapter) returns (AdapterType) { 16 | return AdapterType.CURVE_V1_2ASSETS; 17 | } 18 | 19 | /// @notice Constructor 20 | /// @param _creditManager Credit manager address 21 | /// @param _curvePool Target Curve pool address 22 | /// @param _lp_token Pool LP token address 23 | /// @param _metapoolBase Base pool address (for metapools only) or zero address 24 | constructor(address _creditManager, address _curvePool, address _lp_token, address _metapoolBase) 25 | CurveV1AdapterBase(_creditManager, _curvePool, _lp_token, _metapoolBase, N_COINS) 26 | {} 27 | 28 | /// @dev Sends an order to add liquidity to a Curve pool 29 | /// @notice Add liquidity to the pool 30 | /// @param amounts Amounts of tokens to add 31 | /// @dev `min_mint_amount` parameter is ignored because calldata is passed directly to the target contract 32 | function add_liquidity(uint256[N_COINS] calldata amounts, uint256) external creditFacadeOnly { 33 | _add_liquidity(amounts[0] > 1, amounts[1] > 1, false, false); // F: [ACV1_2-4, ACV1S-1] 34 | } 35 | 36 | /// @notice Remove liquidity from the pool 37 | /// @dev '_amount' and 'min_amounts' parameters are ignored because calldata is directly passed to the target contract 38 | function remove_liquidity(uint256, uint256[N_COINS] calldata) external virtual creditFacadeOnly { 39 | _remove_liquidity(); // F: [ACV1_2-5] 40 | } 41 | 42 | /// @notice Withdraw exact amounts of tokens from the pool 43 | /// @param amounts Amounts of tokens to withdraw 44 | /// @dev `max_burn_amount` parameter is ignored because calldata is directly passed to the target contract 45 | function remove_liquidity_imbalance(uint256[N_COINS] calldata amounts, uint256) 46 | external 47 | virtual 48 | override 49 | creditFacadeOnly 50 | { 51 | _remove_liquidity_imbalance(amounts[0] > 1, amounts[1] > 1, false, false); // F: [ACV1_2-6] 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /contracts/adapters/curve/CurveV1_3.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter, AdapterType} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | import {N_COINS} from "../../integrations/curve/ICurvePool_3.sol"; 9 | import {ICurveV1_3AssetsAdapter} from "../../interfaces/curve/ICurveV1_3AssetsAdapter.sol"; 10 | import {CurveV1AdapterBase} from "./CurveV1_Base.sol"; 11 | 12 | /// @title Curve V1 3 assets adapter 13 | /// @notice Implements logic allowing to interact with Curve pools with 3 assets 14 | contract CurveV1Adapter3Assets is CurveV1AdapterBase, ICurveV1_3AssetsAdapter { 15 | AdapterType public constant override(CurveV1AdapterBase, IAdapter) _gearboxAdapterType = 16 | AdapterType.CURVE_V1_3ASSETS; 17 | 18 | /// @notice Constructor 19 | /// @param _creditManager Credit manager address 20 | /// @param _curvePool Target Curve pool address 21 | /// @param _lp_token Pool LP token address 22 | /// @param _metapoolBase Base pool address (for metapools only) or zero address 23 | constructor(address _creditManager, address _curvePool, address _lp_token, address _metapoolBase) 24 | CurveV1AdapterBase(_creditManager, _curvePool, _lp_token, _metapoolBase, N_COINS) 25 | {} 26 | 27 | /// @notice Add liquidity to the pool 28 | /// @param amounts Amounts of tokens to add 29 | /// @dev `min_mint_amount` parameter is ignored because calldata is passed directly to the target contract 30 | function add_liquidity(uint256[N_COINS] calldata amounts, uint256) external creditFacadeOnly { 31 | _add_liquidity(amounts[0] > 1, amounts[1] > 1, amounts[2] > 1, false); // F: [ACV1_3-4] 32 | } 33 | 34 | /// @notice Remove liquidity from the pool 35 | /// @dev '_amount' and 'min_amounts' parameters are ignored because calldata is directly passed to the target contract 36 | function remove_liquidity(uint256, uint256[N_COINS] calldata) external virtual creditFacadeOnly { 37 | _remove_liquidity(); // F: [ACV1_3-5] 38 | } 39 | 40 | /// @notice Withdraw exact amounts of tokens from the pool 41 | /// @param amounts Amounts of tokens to withdraw 42 | /// @dev `max_burn_amount` parameter is ignored because calldata is directly passed to the target contract 43 | function remove_liquidity_imbalance(uint256[N_COINS] calldata amounts, uint256) 44 | external 45 | virtual 46 | override 47 | creditFacadeOnly 48 | { 49 | _remove_liquidity_imbalance(amounts[0] > 1, amounts[1] > 1, amounts[2] > 1, false); // F: [ACV1_3-6] 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/adapters/curve/CurveV1_4.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter, AdapterType} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | import {N_COINS} from "../../integrations/curve/ICurvePool_4.sol"; 9 | import {ICurveV1_4AssetsAdapter} from "../../interfaces/curve/ICurveV1_4AssetsAdapter.sol"; 10 | import {CurveV1AdapterBase} from "./CurveV1_Base.sol"; 11 | 12 | /// @title Curve V1 4 assets adapter interface 13 | /// @notice Implements logic allowing to interact with Curve pools with 4 assets 14 | contract CurveV1Adapter4Assets is CurveV1AdapterBase, ICurveV1_4AssetsAdapter { 15 | AdapterType public constant override(CurveV1AdapterBase, IAdapter) _gearboxAdapterType = 16 | AdapterType.CURVE_V1_4ASSETS; 17 | 18 | /// @notice Constructor 19 | /// @param _creditManager Credit manager address 20 | /// @param _curvePool Target Curve pool address 21 | /// @param _lp_token Pool LP token address 22 | /// @param _metapoolBase Base pool address (for metapools only) or zero address 23 | constructor(address _creditManager, address _curvePool, address _lp_token, address _metapoolBase) 24 | CurveV1AdapterBase(_creditManager, _curvePool, _lp_token, _metapoolBase, N_COINS) 25 | {} 26 | 27 | /// @notice Add liquidity to the pool 28 | /// @param amounts Amounts of tokens to add 29 | /// @dev `min_mint_amount` parameter is ignored because calldata is passed directly to the target contract 30 | function add_liquidity(uint256[N_COINS] calldata amounts, uint256) external creditFacadeOnly { 31 | _add_liquidity(amounts[0] > 1, amounts[1] > 1, amounts[2] > 1, amounts[3] > 1); // F: [ACV1_4-4] 32 | } 33 | 34 | /// @notice Remove liquidity from the pool 35 | /// @dev '_amount' and 'min_amounts' parameters are ignored because calldata is directly passed to the target contract 36 | function remove_liquidity(uint256, uint256[N_COINS] calldata) external virtual creditFacadeOnly { 37 | _remove_liquidity(); // F: [ACV1_4-5] 38 | } 39 | 40 | /// @notice Withdraw exact amounts of tokens from the pool 41 | /// @param amounts Amounts of tokens to withdraw 42 | /// @dev `max_burn_amount` parameter is ignored because calldata is directly passed to the target contract 43 | function remove_liquidity_imbalance(uint256[N_COINS] calldata amounts, uint256) 44 | external 45 | virtual 46 | override 47 | creditFacadeOnly 48 | { 49 | _remove_liquidity_imbalance(amounts[0] > 1, amounts[1] > 1, amounts[2] > 1, amounts[3] > 1); // F: [ACV1_4-6] 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/adapters/curve/CurveV1_DepositZap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 7 | 8 | import {IAdapter, AdapterType} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 9 | import {RAY} from "@gearbox-protocol/core-v2/contracts/libraries/Constants.sol"; 10 | 11 | import {CurveV1AdapterBase} from "./CurveV1_Base.sol"; 12 | 13 | /// @title Curve V1 DepozitZap adapter 14 | /// @notice Implements logic for interacting with a Curve zap wrapper (to remove_liquidity_one_coin from older pools) 15 | contract CurveV1AdapterDeposit is CurveV1AdapterBase { 16 | AdapterType public constant override _gearboxAdapterType = AdapterType.CURVE_V1_WRAPPER; 17 | 18 | /// @notice Sets allowance for the pool LP token to max before the operation and to 1 after 19 | modifier withLPTokenApproval() { 20 | _approveToken(lp_token, type(uint256).max); 21 | _; 22 | _approveToken(lp_token, 1); 23 | } 24 | 25 | /// @notice Constructor 26 | /// @param _creditManager Credit manager address 27 | /// @param _curveDeposit Target Curve DepositZap contract address 28 | /// @param _lp_token Pool LP token address 29 | /// @param _nCoins Number of coins in the pool 30 | constructor(address _creditManager, address _curveDeposit, address _lp_token, uint256 _nCoins) 31 | CurveV1AdapterBase(_creditManager, _curveDeposit, _lp_token, address(0), _nCoins) 32 | {} 33 | 34 | /// @notice Removes liquidity from the pool in a single asset using deposit zap contract 35 | /// @param i Index of the token to withdraw from the pool 36 | /// @dev Unlike other adapters, approves the LP token to the target 37 | function remove_liquidity_one_coin(uint256, int128 i, uint256) 38 | public 39 | virtual 40 | override 41 | creditFacadeOnly 42 | withLPTokenApproval 43 | { 44 | _remove_liquidity_one_coin(i); 45 | } 46 | 47 | /// @notice Removes all liquidity from the pool in a single asset using deposit zap contract 48 | /// @param i Index of the token to withdraw from the pool 49 | /// @param rateMinRAY Minimum exchange rate between LP token and received asset, scaled by 1e27 50 | /// @dev Unlike other adapters, approves the LP token to the target 51 | function remove_all_liquidity_one_coin(int128 i, uint256 rateMinRAY) 52 | public 53 | virtual 54 | override 55 | creditFacadeOnly 56 | withLPTokenApproval 57 | { 58 | _remove_all_liquidity_one_coin(i, rateMinRAY); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /contracts/adapters/uniswap/UniswapConnectorChecker.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.17; 5 | 6 | import {IUniswapConnectorChecker} from "../../interfaces/uniswap/IUniswapConnectorChecker.sol"; 7 | 8 | abstract contract UniswapConnectorChecker is IUniswapConnectorChecker { 9 | address public immutable connectorToken0; 10 | address public immutable connectorToken1; 11 | address public immutable connectorToken2; 12 | address public immutable connectorToken3; 13 | address public immutable connectorToken4; 14 | address public immutable connectorToken5; 15 | address public immutable connectorToken6; 16 | address public immutable connectorToken7; 17 | address public immutable connectorToken8; 18 | address public immutable connectorToken9; 19 | 20 | uint256 public immutable numConnectors; 21 | 22 | constructor(address[] memory _connectorTokensInit) { 23 | address[10] memory _connectorTokens; 24 | uint256 len = _connectorTokensInit.length; 25 | 26 | for (uint256 i = 0; i < 10; ++i) { 27 | _connectorTokens[i] = i >= len ? address(0) : _connectorTokensInit[i]; 28 | } 29 | 30 | connectorToken0 = _connectorTokens[0]; 31 | connectorToken1 = _connectorTokens[1]; 32 | connectorToken2 = _connectorTokens[2]; 33 | connectorToken3 = _connectorTokens[3]; 34 | connectorToken4 = _connectorTokens[4]; 35 | connectorToken5 = _connectorTokens[5]; 36 | connectorToken6 = _connectorTokens[6]; 37 | connectorToken7 = _connectorTokens[7]; 38 | connectorToken8 = _connectorTokens[8]; 39 | connectorToken9 = _connectorTokens[9]; 40 | 41 | numConnectors = len; 42 | } 43 | 44 | /// @notice Returns true if given token is a registered connector token 45 | function isConnector(address token) public view override returns (bool) { 46 | return token == connectorToken0 || token == connectorToken1 || token == connectorToken2 47 | || token == connectorToken3 || token == connectorToken4 || token == connectorToken5 || token == connectorToken6 48 | || token == connectorToken7 || token == connectorToken8 || token == connectorToken9; 49 | } 50 | 51 | /// @notice Returns the array of registered connector tokens 52 | function getConnectors() external view override returns (address[] memory connectors) { 53 | uint256 len = numConnectors; 54 | 55 | connectors = new address[](len); 56 | 57 | for (uint256 i = 0; i < len;) { 58 | if (i == 0) connectors[0] = connectorToken0; 59 | if (i == 1) connectors[1] = connectorToken1; 60 | if (i == 2) connectors[2] = connectorToken2; 61 | if (i == 3) connectors[3] = connectorToken3; 62 | if (i == 4) connectors[4] = connectorToken4; 63 | if (i == 5) connectors[5] = connectorToken5; 64 | if (i == 6) connectors[6] = connectorToken6; 65 | if (i == 7) connectors[7] = connectorToken7; 66 | if (i == 8) connectors[8] = connectorToken8; 67 | if (i == 9) connectors[9] = connectorToken9; 68 | 69 | unchecked { 70 | ++i; 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /contracts/factories/CreditManagerFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {CreditManagerOpts} from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditConfigurator.sol"; 7 | import {CreditManagerFactoryBase} from "@gearbox-protocol/core-v2/contracts/factories/CreditManagerFactoryBase.sol"; 8 | 9 | contract CreditManagerFactory is CreditManagerFactoryBase { 10 | constructor(address _pool, CreditManagerOpts memory opts, uint256 salt) 11 | CreditManagerFactoryBase(_pool, opts, salt) 12 | {} 13 | } 14 | -------------------------------------------------------------------------------- /contracts/integrations/TokenType.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | enum TokenType { 7 | NO_TOKEN, 8 | NORMAL_TOKEN, 9 | CURVE_LP_TOKEN, 10 | YEARN_ON_NORMAL_TOKEN, 11 | YEARN_ON_CURVE_TOKEN, 12 | CONVEX_LP_TOKEN, 13 | CONVEX_STAKED_TOKEN, 14 | DIESEL_LP_TOKEN, 15 | GEAR_TOKEN, 16 | C_TOKEN 17 | } 18 | -------------------------------------------------------------------------------- /contracts/integrations/aave/DataTypes.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity ^0.8.0; 3 | 4 | library DataTypes { 5 | // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. 6 | struct ReserveData { 7 | //stores the reserve configuration 8 | ReserveConfigurationMap configuration; 9 | //the liquidity index. Expressed in ray 10 | uint128 liquidityIndex; 11 | //variable borrow index. Expressed in ray 12 | uint128 variableBorrowIndex; 13 | //the current supply rate. Expressed in ray 14 | uint128 currentLiquidityRate; 15 | //the current variable borrow rate. Expressed in ray 16 | uint128 currentVariableBorrowRate; 17 | //the current stable borrow rate. Expressed in ray 18 | uint128 currentStableBorrowRate; 19 | uint40 lastUpdateTimestamp; 20 | //tokens addresses 21 | address aTokenAddress; 22 | address stableDebtTokenAddress; 23 | address variableDebtTokenAddress; 24 | //address of the interest rate strategy 25 | address interestRateStrategyAddress; 26 | //the id of the reserve. Represents the position in the list of the active reserves 27 | uint8 id; 28 | } 29 | 30 | struct ReserveConfigurationMap { 31 | //bit 0-15: LTV 32 | //bit 16-31: Liq. threshold 33 | //bit 32-47: Liq. bonus 34 | //bit 48-55: Decimals 35 | //bit 56: Reserve is active 36 | //bit 57: reserve is frozen 37 | //bit 58: borrowing is enabled 38 | //bit 59: stable rate borrowing enabled 39 | //bit 60-63: reserved 40 | //bit 64-79: reserve factor 41 | uint256 data; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /contracts/integrations/aave/IAToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity ^0.8.0; 3 | 4 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 5 | 6 | import {ILendingPool} from "./ILendingPool.sol"; 7 | 8 | interface IAToken is IERC20Metadata { 9 | /** 10 | * @dev Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH) 11 | * 12 | */ 13 | function UNDERLYING_ASSET_ADDRESS() external view returns (address); 14 | 15 | /** 16 | * @dev Returns the address of the lending pool where this aToken is used 17 | * 18 | */ 19 | function POOL() external view returns (ILendingPool); 20 | } 21 | -------------------------------------------------------------------------------- /contracts/integrations/aave/ILendingPool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity ^0.8.0; 3 | 4 | import {DataTypes} from "./DataTypes.sol"; 5 | 6 | interface ILendingPool { 7 | /** 8 | * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. 9 | * E.g. User deposits 100 USDC and gets in return 100 aUSDC 10 | * @param asset The address of the underlying asset to deposit 11 | * @param amount The amount to be deposited 12 | * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user 13 | * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens 14 | * is a different wallet 15 | * @param referralCode Code used to register the integrator originating the operation, for potential rewards. 16 | * 0 if the action is executed directly by the user, without any middle-man 17 | * 18 | */ 19 | function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; 20 | 21 | /** 22 | * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned 23 | * - E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC 24 | * @param asset The address of the underlying asset to withdraw 25 | * @param amount The underlying amount to be withdrawn 26 | * - Send the value type(uint256).max in order to withdraw the whole aToken balance 27 | * @param to Address that will receive the underlying, same as msg.sender if the user 28 | * wants to receive it on his own wallet, or a different address if the beneficiary is a 29 | * different wallet 30 | * @return The final amount withdrawn 31 | * 32 | */ 33 | function withdraw(address asset, uint256 amount, address to) external returns (uint256); 34 | 35 | /** 36 | * @dev Returns the state and configuration of the reserve 37 | * @param asset The address of the underlying asset of the reserve 38 | * @return The state of the reserve 39 | * 40 | */ 41 | function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); 42 | } 43 | -------------------------------------------------------------------------------- /contracts/integrations/balancer/IAsset.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | 12 | // You should have received a copy of the GNU General Public License 13 | // along with this program. If not, see . 14 | 15 | pragma solidity >=0.7.0 <0.9.0; 16 | 17 | /** 18 | * @dev This is an empty interface used to represent either ERC20-conforming token contracts or ETH (using the zero 19 | * address sentinel value). We're just relying on the fact that `interface` can be used to declare new address-like 20 | * types. 21 | * 22 | * This concept is unrelated to a Pool's Asset Managers. 23 | */ 24 | interface IAsset { 25 | // solhint-disable-previous-line no-empty-blocks 26 | } 27 | -------------------------------------------------------------------------------- /contracts/integrations/balancer/IBalancerStablePool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | 4 | interface IBalancerStablePool { 5 | function totalSupply() external view returns (uint256); 6 | 7 | function getActualSupply() external view returns (uint256); 8 | 9 | function getPoolId() external view returns (bytes32); 10 | 11 | function getRate() external view returns (uint256); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/integrations/balancer/IBalancerV2Vault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | 4 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | import {IAsset} from "./IAsset.sol"; 6 | 7 | enum SwapKind { 8 | GIVEN_IN, 9 | GIVEN_OUT 10 | } 11 | 12 | enum PoolSpecialization { 13 | GENERAL, 14 | MINIMAL_SWAP_INFO, 15 | TWO_TOKEN 16 | } 17 | 18 | enum JoinKind { 19 | INIT, 20 | EXACT_TOKENS_IN_FOR_BPT_OUT, 21 | TOKEN_IN_FOR_EXACT_BPT_OUT, 22 | ALL_TOKENS_IN_FOR_EXACT_BPT_OUT 23 | } 24 | 25 | enum ExitKind { 26 | EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, 27 | EXACT_BPT_IN_FOR_TOKENS_OUT, 28 | BPT_IN_FOR_EXACT_TOKENS_OUT 29 | } 30 | 31 | struct SingleSwap { 32 | bytes32 poolId; 33 | SwapKind kind; 34 | IAsset assetIn; 35 | IAsset assetOut; 36 | uint256 amount; 37 | bytes userData; 38 | } 39 | 40 | struct BatchSwapStep { 41 | bytes32 poolId; 42 | uint256 assetInIndex; 43 | uint256 assetOutIndex; 44 | uint256 amount; 45 | bytes userData; 46 | } 47 | 48 | struct FundManagement { 49 | address sender; 50 | bool fromInternalBalance; 51 | address payable recipient; 52 | bool toInternalBalance; 53 | } 54 | 55 | struct JoinPoolRequest { 56 | IAsset[] assets; 57 | uint256[] maxAmountsIn; 58 | bytes userData; 59 | bool fromInternalBalance; 60 | } 61 | 62 | struct ExitPoolRequest { 63 | IAsset[] assets; 64 | uint256[] minAmountsOut; 65 | bytes userData; 66 | bool toInternalBalance; 67 | } 68 | 69 | interface IBalancerV2VaultGetters { 70 | function getPool(bytes32 poolId) external view returns (address, PoolSpecialization); 71 | 72 | function getPoolTokenInfo(bytes32 poolId, IERC20 token) 73 | external 74 | view 75 | returns (uint256 cash, uint256 managed, uint256 lastChangeBlock, address assetManager); 76 | 77 | function getPoolTokens(bytes32 poolId) 78 | external 79 | view 80 | returns (IERC20[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock); 81 | } 82 | 83 | interface IBalancerV2Vault is IBalancerV2VaultGetters { 84 | function batchSwap( 85 | SwapKind kind, 86 | BatchSwapStep[] memory swaps, 87 | IAsset[] memory assets, 88 | FundManagement memory funds, 89 | int256[] memory limits, 90 | uint256 deadline 91 | ) external returns (int256[] memory assetDeltas); 92 | 93 | function queryBatchSwap( 94 | SwapKind kind, 95 | BatchSwapStep[] memory swaps, 96 | IAsset[] memory assets, 97 | FundManagement memory funds 98 | ) external returns (int256[] memory assetDeltas); 99 | 100 | function swap(SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline) 101 | external 102 | returns (uint256 amountCalculated); 103 | 104 | function joinPool(bytes32 poolId, address sender, address recipient, JoinPoolRequest memory request) external; 105 | 106 | function exitPool(bytes32 poolId, address sender, address payable recipient, ExitPoolRequest memory request) 107 | external; 108 | } 109 | -------------------------------------------------------------------------------- /contracts/integrations/balancer/IBalancerWeightedPool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | 4 | interface IBalancerWeightedPool { 5 | function getNormalizedWeights() external view returns (uint256[] memory); 6 | 7 | function totalSupply() external view returns (uint256); 8 | 9 | function getActualSupply() external view returns (uint256); 10 | 11 | function getPoolId() external view returns (bytes32); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/integrations/compound/ICErc20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | pragma solidity ^0.8.10; 3 | 4 | import {ICToken} from "./ICToken.sol"; 5 | 6 | interface ICErc20Actions { 7 | /** 8 | * @notice Sender supplies assets into the market and receives cTokens in exchange 9 | * @dev Accrues interest whether or not the operation succeeds, unless reverted 10 | * @param mintAmount The amount of the underlying asset to supply 11 | * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) 12 | */ 13 | function mint(uint256 mintAmount) external returns (uint256); 14 | 15 | /** 16 | * @notice Sender redeems cTokens in exchange for the underlying asset 17 | * @dev Accrues interest whether or not the operation succeeds, unless reverted 18 | * @param redeemTokens The number of cTokens to redeem into underlying 19 | * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) 20 | */ 21 | function redeem(uint256 redeemTokens) external returns (uint256); 22 | 23 | /** 24 | * @notice Sender redeems cTokens in exchange for a specified amount of underlying asset 25 | * @dev Accrues interest whether or not the operation succeeds, unless reverted 26 | * @param redeemAmount The amount of underlying to redeem 27 | * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) 28 | */ 29 | function redeemUnderlying(uint256 redeemAmount) external returns (uint256); 30 | } 31 | 32 | /** 33 | * @title Compound's CErc20 Contract 34 | * @notice CTokens which wrap an EIP-20 underlying 35 | * @author Compound 36 | */ 37 | interface ICErc20 is ICToken, ICErc20Actions { 38 | /** 39 | * @notice Underlying asset for this CToken 40 | */ 41 | function underlying() external view returns (address); 42 | } 43 | -------------------------------------------------------------------------------- /contracts/integrations/compound/ICEther.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | pragma solidity ^0.8.10; 3 | 4 | import {ICToken} from "./ICToken.sol"; 5 | 6 | /** 7 | * @title Compound's CEther Contract 8 | * @notice CToken which wraps Ether 9 | * @author Compound 10 | */ 11 | interface ICEther is ICToken { 12 | /** 13 | * @notice Sender supplies assets into the market and receives cTokens in exchange 14 | * @dev Reverts upon any failure 15 | */ 16 | function mint() external payable; 17 | 18 | /** 19 | * @notice Sender redeems cTokens in exchange for the underlying asset 20 | * @dev Accrues interest whether or not the operation succeeds, unless reverted 21 | * @param redeemTokens The number of cTokens to redeem into underlying 22 | * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) 23 | */ 24 | function redeem(uint256 redeemTokens) external returns (uint256); 25 | 26 | /** 27 | * @notice Sender redeems cTokens in exchange for a specified amount of underlying asset 28 | * @dev Accrues interest whether or not the operation succeeds, unless reverted 29 | * @param redeemAmount The amount of underlying to redeem 30 | * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) 31 | */ 32 | function redeemUnderlying(uint256 redeemAmount) external returns (uint256); 33 | } 34 | -------------------------------------------------------------------------------- /contracts/integrations/compound/ICToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | pragma solidity ^0.8.10; 3 | 4 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 5 | 6 | /** 7 | * @title Compound's CToken Contract 8 | * @notice Abstract base for CTokens 9 | * @author Compound 10 | */ 11 | interface ICToken is IERC20Metadata { 12 | /** 13 | * @notice Accrue interest then return the up-to-date exchange rate 14 | * @return Calculated exchange rate scaled by 1e18 15 | */ 16 | function exchangeRateCurrent() external returns (uint256); 17 | 18 | /** 19 | * @notice Calculates the exchange rate from the underlying to the CToken 20 | * @dev This function does not accrue interest before calculating the exchange rate 21 | * @return Calculated exchange rate scaled by 1e18 22 | */ 23 | function exchangeRateStored() external view returns (uint256); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/integrations/convex/IBaseRewardPool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | 4 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | interface IBaseRewardPool { 7 | // 8 | // STATE CHANGING FUNCTIONS 9 | // 10 | function stake(uint256 _amount) external returns (bool); 11 | 12 | function stakeAll() external returns (bool); 13 | 14 | function stakeFor(address _for, uint256 _amount) external returns (bool); 15 | 16 | function withdraw(uint256 amount, bool claim) external returns (bool); 17 | 18 | function withdrawAll(bool claim) external; 19 | 20 | function withdrawAndUnwrap(uint256 amount, bool claim) external returns (bool); 21 | 22 | function withdrawAllAndUnwrap(bool claim) external; 23 | 24 | function getReward(address _account, bool _claimExtras) external returns (bool); 25 | 26 | function getReward() external returns (bool); 27 | 28 | function donate(uint256 _amount) external returns (bool); 29 | 30 | // 31 | // GETTERS 32 | // 33 | function earned(address account) external view returns (uint256); 34 | 35 | function totalSupply() external view returns (uint256); 36 | 37 | function balanceOf(address account) external view returns (uint256); 38 | 39 | function extraRewardsLength() external view returns (uint256); 40 | 41 | function lastTimeRewardApplicable() external view returns (uint256); 42 | 43 | function rewardPerToken() external view returns (uint256); 44 | 45 | function rewardToken() external view returns (IERC20); 46 | 47 | function stakingToken() external view returns (IERC20); 48 | 49 | function duration() external view returns (uint256); 50 | 51 | function operator() external view returns (address); 52 | 53 | function rewardManager() external view returns (address); 54 | 55 | function pid() external view returns (uint256); 56 | 57 | function periodFinish() external view returns (uint256); 58 | 59 | function rewardRate() external view returns (uint256); 60 | 61 | function lastUpdateTime() external view returns (uint256); 62 | 63 | function rewardPerTokenStored() external view returns (uint256); 64 | 65 | function queuedRewards() external view returns (uint256); 66 | 67 | function currentRewards() external view returns (uint256); 68 | 69 | function historicalRewards() external view returns (uint256); 70 | 71 | function newRewardRatio() external view returns (uint256); 72 | 73 | function userRewardPerTokenPaid(address account) external view returns (uint256); 74 | 75 | function rewards(address account) external view returns (uint256); 76 | 77 | function extraRewards(uint256 i) external view returns (address); 78 | } 79 | -------------------------------------------------------------------------------- /contracts/integrations/convex/IBooster.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | 4 | interface IBooster { 5 | struct PoolInfo { 6 | address lptoken; 7 | address token; 8 | address gauge; 9 | address crvRewards; 10 | address stash; 11 | bool shutdown; 12 | } 13 | 14 | function deposit(uint256 _pid, uint256 _amount, bool _stake) external returns (bool); 15 | 16 | function depositAll(uint256 _pid, bool _stake) external returns (bool); 17 | 18 | function withdraw(uint256 _pid, uint256 _amount) external returns (bool); 19 | 20 | function withdrawAll(uint256 _pid) external returns (bool); 21 | 22 | // function earmarkRewards(uint256 _pid) external returns (bool); 23 | 24 | // function earmarkFees() external returns (bool); 25 | 26 | // 27 | // GETTERS 28 | // 29 | function poolInfo(uint256 i) external view returns (PoolInfo memory); 30 | 31 | function poolLength() external view returns (uint256); 32 | 33 | function staker() external view returns (address); 34 | 35 | function minter() external view returns (address); 36 | 37 | function crv() external view returns (address); 38 | 39 | function registry() external view returns (address); 40 | 41 | function stakerRewards() external view returns (address); 42 | 43 | function lockRewards() external view returns (address); 44 | 45 | function lockFees() external view returns (address); 46 | } 47 | -------------------------------------------------------------------------------- /contracts/integrations/convex/IClaimZap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | pragma abicoder v1; 4 | 5 | interface IClaimZap { 6 | function claimRewards( 7 | address[] calldata rewardContracts, 8 | address[] calldata extraRewardContracts, 9 | address[] calldata tokenRewardContracts, 10 | address[] calldata tokenRewardTokens, 11 | uint256 depositCrvMaxAmount, 12 | uint256 minAmountOut, 13 | uint256 depositCvxMaxAmount, 14 | uint256 spendCvxAmount, 15 | uint256 options 16 | ) external; 17 | 18 | function crv() external view returns (address); 19 | 20 | function cvx() external view returns (address); 21 | } 22 | -------------------------------------------------------------------------------- /contracts/integrations/convex/IConvexToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | 4 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | interface IConvexToken is IERC20 { 7 | function operator() external view returns (address); 8 | 9 | function vecrvProxy() external view returns (address); 10 | 11 | function maxSupply() external view returns (uint256); 12 | 13 | function totalCliffs() external view returns (uint256); 14 | 15 | function reductionPerCliff() external view returns (uint256); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/integrations/convex/IRewards.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | 4 | interface IRewards { 5 | function stake(address, uint256) external; 6 | 7 | function stakeFor(address, uint256) external; 8 | 9 | function withdraw(address, uint256) external; 10 | 11 | function exit(address) external; 12 | 13 | function getReward(address) external; 14 | 15 | function queueNewRewards(uint256) external; 16 | 17 | function notifyRewardAmount(uint256) external; 18 | 19 | function addExtraReward(address) external; 20 | 21 | function stakingToken() external view returns (address); 22 | 23 | function rewardToken() external view returns (address); 24 | 25 | function earned(address account) external view returns (uint256); 26 | } 27 | 28 | interface IBasicRewards { 29 | function getReward(address _account, bool _claimExtras) external; 30 | 31 | function getReward(address _account) external; 32 | 33 | function getReward(address _account, address _token) external; 34 | 35 | function stakeFor(address, uint256) external; 36 | } 37 | -------------------------------------------------------------------------------- /contracts/integrations/curve/ICRVToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | interface ICRVToken is IERC20 { 7 | function set_minter(address minter) external; 8 | 9 | function mint(address to, uint256 value) external returns (bool); 10 | 11 | function burnFrom(address to, uint256 value) external returns (bool); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/integrations/curve/ICurvePool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | interface ICurvePool { 5 | function coins(uint256 i) external view returns (address); 6 | 7 | function underlying_coins(uint256 i) external view returns (address); 8 | 9 | function balances(uint256 i) external view returns (uint256); 10 | 11 | function coins(int128) external view returns (address); 12 | 13 | function underlying_coins(int128) external view returns (address); 14 | 15 | function balances(int128) external view returns (uint256); 16 | 17 | function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external; 18 | 19 | function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external; 20 | 21 | function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external; 22 | 23 | function exchange_underlying(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external; 24 | 25 | function get_dy_underlying(int128 i, int128 j, uint256 dx) external view returns (uint256); 26 | 27 | function get_dy_underlying(uint256 i, uint256 j, uint256 dx) external view returns (uint256); 28 | 29 | function get_dy(int128 i, int128 j, uint256 dx) external view returns (uint256); 30 | 31 | function get_dy(uint256 i, uint256 j, uint256 dx) external view returns (uint256); 32 | 33 | function get_virtual_price() external view returns (uint256); 34 | 35 | function token() external view returns (address); 36 | 37 | function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 min_amount) external; 38 | 39 | function remove_liquidity_one_coin(uint256 _token_amount, uint256 i, uint256 min_amount) external; 40 | 41 | function A() external view returns (uint256); 42 | 43 | function A_precise() external view returns (uint256); 44 | 45 | function calc_withdraw_one_coin(uint256 _burn_amount, int128 i) external view returns (uint256); 46 | 47 | function calc_withdraw_one_coin(uint256 _burn_amount, uint256 i) external view returns (uint256); 48 | 49 | function admin_balances(uint256 i) external view returns (uint256); 50 | 51 | function admin() external view returns (address); 52 | 53 | function fee() external view returns (uint256); 54 | 55 | function admin_fee() external view returns (uint256); 56 | 57 | function block_timestamp_last() external view returns (uint256); 58 | 59 | function initial_A() external view returns (uint256); 60 | 61 | function future_A() external view returns (uint256); 62 | 63 | function initial_A_time() external view returns (uint256); 64 | 65 | function future_A_time() external view returns (uint256); 66 | 67 | function mid_fee() external view returns (uint256); 68 | 69 | // Some pools implement ERC20 70 | 71 | function name() external view returns (string memory); 72 | 73 | function symbol() external view returns (string memory); 74 | 75 | function decimals() external view returns (uint256); 76 | 77 | function balanceOf(address) external view returns (uint256); 78 | 79 | function allowance(address, address) external view returns (uint256); 80 | 81 | function totalSupply() external view returns (uint256); 82 | } 83 | -------------------------------------------------------------------------------- /contracts/integrations/curve/ICurvePoolStETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | uint256 constant N_COINS = 2; 5 | 6 | interface ICurvePoolStETH { 7 | function coins(uint256) external view returns (address); 8 | 9 | function balances(uint256) external view returns (uint256); 10 | 11 | function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external payable; 12 | 13 | function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external; 14 | 15 | function add_liquidity(uint256[N_COINS] memory amounts, uint256 min_mint_amount) external payable; 16 | 17 | function remove_liquidity(uint256 _amount, uint256[N_COINS] memory min_amounts) external; 18 | 19 | function get_dy_underlying(int128 i, int128 j, uint256 dx) external view returns (uint256); 20 | 21 | function get_dy(int128 i, int128 j, uint256 dx) external view returns (uint256); 22 | 23 | function get_virtual_price() external view returns (uint256); 24 | 25 | function lp_token() external view returns (address); 26 | 27 | function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 min_amount) external; 28 | 29 | function remove_liquidity_imbalance(uint256[N_COINS] memory amounts, uint256 max_burn_amount) external; 30 | 31 | function calc_token_amount(uint256[N_COINS] calldata _amounts, bool _is_deposit) external view returns (uint256); 32 | 33 | function A() external view returns (uint256); 34 | 35 | function A_precise() external view returns (uint256); 36 | 37 | function calc_withdraw_one_coin(uint256 _burn_amount, int128 i) external view returns (uint256); 38 | 39 | function admin_balances(uint256 i) external view returns (uint256); 40 | 41 | function admin() external view returns (address); 42 | 43 | function fee() external view returns (uint256); 44 | 45 | function admin_fee() external view returns (uint256); 46 | 47 | function block_timestamp_last() external view returns (uint256); 48 | 49 | function initial_A() external view returns (uint256); 50 | 51 | function future_A() external view returns (uint256); 52 | 53 | function initial_A_time() external view returns (uint256); 54 | 55 | function future_A_time() external view returns (uint256); 56 | } 57 | -------------------------------------------------------------------------------- /contracts/integrations/curve/ICurvePool_2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | import {ICurvePool} from "./ICurvePool.sol"; 5 | 6 | uint256 constant N_COINS = 2; 7 | 8 | /// @title ICurvePool2Assets 9 | /// @dev Extends original pool contract with liquidity functions 10 | interface ICurvePool2Assets is ICurvePool { 11 | function add_liquidity(uint256[N_COINS] memory amounts, uint256 min_mint_amount) external; 12 | 13 | function remove_liquidity(uint256 _amount, uint256[N_COINS] memory min_amounts) external; 14 | 15 | function remove_liquidity_imbalance(uint256[N_COINS] calldata amounts, uint256 max_burn_amount) external; 16 | 17 | function calc_token_amount(uint256[N_COINS] calldata _amounts, bool _is_deposit) external view returns (uint256); 18 | 19 | function get_twap_balances( 20 | uint256[N_COINS] calldata _first_balances, 21 | uint256[N_COINS] calldata _last_balances, 22 | uint256 _time_elapsed 23 | ) external view returns (uint256[N_COINS] memory); 24 | 25 | function get_balances() external view returns (uint256[N_COINS] memory); 26 | 27 | function get_previous_balances() external view returns (uint256[N_COINS] memory); 28 | 29 | function get_price_cumulative_last() external view returns (uint256[N_COINS] memory); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/integrations/curve/ICurvePool_3.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | import {ICurvePool} from "./ICurvePool.sol"; 5 | 6 | uint256 constant N_COINS = 3; 7 | 8 | /// @title ICurvePool3Assets 9 | /// @dev Extends original pool contract with liquidity functions 10 | interface ICurvePool3Assets is ICurvePool { 11 | function add_liquidity(uint256[N_COINS] memory amounts, uint256 min_mint_amount) external; 12 | 13 | function remove_liquidity(uint256 _amount, uint256[N_COINS] memory min_amounts) external; 14 | 15 | function remove_liquidity_imbalance(uint256[N_COINS] memory amounts, uint256 max_burn_amount) external; 16 | 17 | function calc_token_amount(uint256[N_COINS] calldata _amounts, bool _is_deposit) external view returns (uint256); 18 | 19 | function get_twap_balances( 20 | uint256[N_COINS] calldata _first_balances, 21 | uint256[N_COINS] calldata _last_balances, 22 | uint256 _time_elapsed 23 | ) external view returns (uint256[N_COINS] memory); 24 | 25 | function get_balances() external view returns (uint256[N_COINS] memory); 26 | 27 | function get_previous_balances() external view returns (uint256[N_COINS] memory); 28 | 29 | function get_price_cumulative_last() external view returns (uint256[N_COINS] memory); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/integrations/curve/ICurvePool_4.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | import {ICurvePool} from "./ICurvePool.sol"; 5 | 6 | uint256 constant N_COINS = 4; 7 | 8 | /// @title ICurvePool4Assets 9 | /// @dev Extends original pool contract with liquidity functions 10 | interface ICurvePool4Assets is ICurvePool { 11 | function add_liquidity(uint256[N_COINS] memory amounts, uint256 min_mint_amount) external; 12 | 13 | function remove_liquidity(uint256 _amount, uint256[N_COINS] memory min_amounts) external; 14 | 15 | function remove_liquidity_imbalance(uint256[N_COINS] memory amounts, uint256 max_burn_amount) external; 16 | 17 | function calc_token_amount(uint256[N_COINS] calldata _amounts, bool _is_deposit) external view returns (uint256); 18 | 19 | function get_twap_balances( 20 | uint256[N_COINS] calldata _first_balances, 21 | uint256[N_COINS] calldata _last_balances, 22 | uint256 _time_elapsed 23 | ) external view returns (uint256[N_COINS] memory); 24 | 25 | function get_balances() external view returns (uint256[N_COINS] memory); 26 | 27 | function get_previous_balances() external view returns (uint256[N_COINS] memory); 28 | 29 | function get_price_cumulative_last() external view returns (uint256[N_COINS] memory); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/integrations/curve/ICurveRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | interface ICurveRegistry { 5 | function get_pool_from_lp_token(address token) external view returns (address); 6 | 7 | function get_n_coins(address pool) external view returns (uint256); 8 | 9 | function get_lp_token(address pool) external view returns (address); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/integrations/euler/IEToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity ^0.8.0; 3 | 4 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 5 | 6 | /// @notice Tokenised representation of assets 7 | interface IEToken is IERC20Metadata { 8 | /// @notice Address of underlying asset 9 | function underlyingAsset() external view returns (address); 10 | 11 | /// @notice Balance of a particular account, in underlying units (increases as interest is earned) 12 | function balanceOfUnderlying(address account) external view returns (uint256); 13 | 14 | /// @notice Convert an eToken balance to an underlying amount, taking into account current exchange rate 15 | /// @param balance eToken balance, in internal book-keeping units (18 decimals) 16 | /// @return Amount in underlying units, (same decimals as underlying token) 17 | function convertBalanceToUnderlying(uint256 balance) external view returns (uint256); 18 | 19 | /// @notice Transfer underlying tokens from sender to the Euler pool, and increase account's eTokens 20 | /// @param subAccountId 0 for primary, 1-255 for a sub-account 21 | /// @param amount In underlying units (use max uint256 for full underlying token balance) 22 | function deposit(uint256 subAccountId, uint256 amount) external; 23 | 24 | /// @notice Transfer underlying tokens from Euler pool to sender, and decrease account's eTokens 25 | /// @param subAccountId 0 for primary, 1-255 for a sub-account 26 | /// @param amount In underlying units (use max uint256 for full pool balance) 27 | function withdraw(uint256 subAccountId, uint256 amount) external; 28 | } 29 | -------------------------------------------------------------------------------- /contracts/integrations/lido/ILidoOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Lido 2 | 3 | // SPDX-License-Identifier: GPL-3.0 4 | pragma solidity ^0.8.10; 5 | 6 | interface ILidoOracle { 7 | function getLastCompletedReportDelta() 8 | external 9 | view 10 | returns (uint256 postTotalPooledEther, uint256 preTotalPooledEther, uint256 timeElapsed); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/integrations/lido/IstETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Lido 2 | 3 | // SPDX-License-Identifier: GPL-3.0 4 | pragma solidity ^0.8.10; 5 | 6 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 7 | 8 | interface IstETHGetters is IERC20Metadata { 9 | function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256); 10 | 11 | function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); 12 | 13 | function getTotalPooledEther() external view returns (uint256); 14 | 15 | function getTotalShares() external view returns (uint256); 16 | 17 | function getFee() external view returns (uint16); 18 | 19 | function sharesOf(address _account) external view returns (uint256); 20 | } 21 | 22 | interface IstETH is IstETHGetters { 23 | function submit(address _referral) external payable returns (uint256); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/integrations/lido/IwstETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2021 Lido 2 | 3 | // SPDX-License-Identifier: GPL-3.0 4 | pragma solidity ^0.8.10; 5 | 6 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 7 | 8 | interface IwstETHGetters is IERC20Metadata { 9 | function stETH() external view returns (address); 10 | 11 | /** 12 | * @notice Get amount of wstETH for a given amount of stETH 13 | * @param _stETHAmount amount of stETH 14 | * @return Amount of wstETH for a given stETH amount 15 | */ 16 | function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256); 17 | 18 | /** 19 | * @notice Get amount of stETH for a given amount of wstETH 20 | * @param _wstETHAmount amount of wstETH 21 | * @return Amount of stETH for a given wstETH amount 22 | */ 23 | function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256); 24 | 25 | /** 26 | * @notice Get amount of stETH for a one wstETH 27 | * @return Amount of stETH for 1 wstETH 28 | */ 29 | function stEthPerToken() external view returns (uint256); 30 | 31 | /** 32 | * @notice Get amount of wstETH for a one stETH 33 | * @return Amount of wstETH for a 1 stETH 34 | */ 35 | function tokensPerStEth() external view returns (uint256); 36 | } 37 | 38 | interface IwstETH is IwstETHGetters { 39 | /** 40 | * @notice Exchanges stETH to wstETH 41 | * @param _stETHAmount amount of stETH to wrap in exchange for wstETH 42 | * @dev Requirements: 43 | * - `_stETHAmount` must be non-zero 44 | * - msg.sender must approve at least `_stETHAmount` stETH to this 45 | * contract. 46 | * - msg.sender must have at least `_stETHAmount` of stETH. 47 | * User should first approve _stETHAmount to the WstETH contract 48 | * @return Amount of wstETH user receives after wrap 49 | */ 50 | function wrap(uint256 _stETHAmount) external returns (uint256); 51 | 52 | /** 53 | * @notice Exchanges wstETH to stETH 54 | * @param _wstETHAmount amount of wstETH to uwrap in exchange for stETH 55 | * @dev Requirements: 56 | * - `_wstETHAmount` must be non-zero 57 | * - msg.sender must have at least `_wstETHAmount` wstETH. 58 | * @return Amount of stETH user receives after unwrap 59 | */ 60 | function unwrap(uint256 _wstETHAmount) external returns (uint256); 61 | } 62 | -------------------------------------------------------------------------------- /contracts/integrations/lido/IwstETHGateway.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | interface IwstETHGateWay { 5 | error NonRegisterPoolException(); 6 | 7 | /** 8 | * @dev Adds stETH liquidity to wstETH pool 9 | * - transfers the underlying to the pool 10 | * - mints Diesel (LP) tokens to onBehalfOf 11 | * @param amount Amount of tokens to be deposited 12 | * @param onBehalfOf The address that will receive the dToken 13 | * @param referralCode Code used to register the integrator originating the operation, for potential rewards. 14 | * 0 if the action is executed directly by the user, without a facilitator. 15 | */ 16 | function addLiquidity(uint256 amount, address onBehalfOf, uint256 referralCode) external; 17 | 18 | /// @dev Removes liquidity from pool 19 | /// - burns LP's Diesel (LP) tokens 20 | /// - returns the equivalent amount of underlying to 'to' 21 | /// @param amount Amount of Diesel tokens to burn 22 | /// @param to Address to transfer the underlying to 23 | function removeLiquidity(uint256 amount, address to) external returns (uint256 amountGet); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/integrations/uniswap/IQuoter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | /// @title Quoter Interface 6 | /// @notice Supports quoting the calculated amounts from exact input or exact output swaps 7 | /// @dev These functions are not marked view because they rely on calling non-view functions and reverting 8 | /// to compute the result. They are also not gas efficient and should not be called on-chain. 9 | interface IQuoter { 10 | /// @notice Returns the amount out received for a given exact input swap without executing the swap 11 | /// @param path The path of the swap, i.e. each token pair and the pool fee 12 | /// @param amountIn The amount of the first token to swap 13 | /// @return amountOut The amount of the last token that would be received 14 | function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut); 15 | 16 | /// @notice Returns the amount out received for a given exact input but for a swap of a single pool 17 | /// @param tokenIn The token being swapped in 18 | /// @param tokenOut The token being swapped out 19 | /// @param fee The fee of the token pool to consider for the pair 20 | /// @param amountIn The desired input amount 21 | /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap 22 | /// @return amountOut The amount of `tokenOut` that would be received 23 | function quoteExactInputSingle( 24 | address tokenIn, 25 | address tokenOut, 26 | uint24 fee, 27 | uint256 amountIn, 28 | uint160 sqrtPriceLimitX96 29 | ) external returns (uint256 amountOut); 30 | 31 | /// @notice Returns the amount in required for a given exact output swap without executing the swap 32 | /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order 33 | /// @param amountOut The amount of the last token to receive 34 | /// @return amountIn The amount of first token required to be paid 35 | function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn); 36 | 37 | /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool 38 | /// @param tokenIn The token being swapped in 39 | /// @param tokenOut The token being swapped out 40 | /// @param fee The fee of the token pool to consider for the pair 41 | /// @param amountOut The desired output amount 42 | /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap 43 | /// @return amountIn The amount required as the input for the swap in order to receive `amountOut` 44 | function quoteExactOutputSingle( 45 | address tokenIn, 46 | address tokenOut, 47 | uint24 fee, 48 | uint256 amountOut, 49 | uint160 sqrtPriceLimitX96 50 | ) external returns (uint256 amountIn); 51 | } 52 | -------------------------------------------------------------------------------- /contracts/integrations/uniswap/IUniswapV3.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | interface ISwapRouter { 6 | struct ExactInputSingleParams { 7 | address tokenIn; 8 | address tokenOut; 9 | uint24 fee; 10 | address recipient; 11 | uint256 deadline; 12 | uint256 amountIn; 13 | uint256 amountOutMinimum; 14 | uint160 sqrtPriceLimitX96; 15 | } 16 | 17 | function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); 18 | 19 | struct ExactInputParams { 20 | bytes path; 21 | address recipient; 22 | uint256 deadline; 23 | uint256 amountIn; 24 | uint256 amountOutMinimum; 25 | } 26 | 27 | function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); 28 | 29 | struct ExactOutputSingleParams { 30 | address tokenIn; 31 | address tokenOut; 32 | uint24 fee; 33 | address recipient; 34 | uint256 deadline; 35 | uint256 amountOut; 36 | uint256 amountInMaximum; 37 | uint160 sqrtPriceLimitX96; 38 | } 39 | 40 | function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); 41 | 42 | struct ExactOutputParams { 43 | bytes path; 44 | address recipient; 45 | uint256 deadline; 46 | uint256 amountOut; 47 | uint256 amountInMaximum; 48 | } 49 | 50 | function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); 51 | } 52 | -------------------------------------------------------------------------------- /contracts/integrations/uniswap/IUniswapV3SwapCallback.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Callback for IUniswapV3PoolActions#swap 5 | /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface 6 | interface IUniswapV3SwapCallback { 7 | /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. 8 | /// @dev In the implementation you must pay the pool tokens owed for the swap. 9 | /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. 10 | /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. 11 | /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by 12 | /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. 13 | /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by 14 | /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. 15 | /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call 16 | function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external; 17 | } 18 | -------------------------------------------------------------------------------- /contracts/integrations/uniswap/Path.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.6.0; 3 | 4 | import "../../integrations/uniswap/BytesLib.sol"; 5 | 6 | /// @title Functions for manipulating path data for multihop swaps 7 | library Path { 8 | using BytesLib for bytes; 9 | 10 | /// @dev The length of the bytes encoded address 11 | uint256 private constant ADDR_SIZE = 20; 12 | /// @dev The length of the bytes encoded fee 13 | uint256 private constant FEE_SIZE = 3; 14 | 15 | /// @dev The offset of a single token address and pool fee 16 | uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE; 17 | /// @dev The offset of an encoded pool key 18 | uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE; 19 | /// @dev The minimum length of an encoding that contains 2 or more pools 20 | uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET; 21 | 22 | /// @notice Returns true iff the path contains two or more pools 23 | /// @param path The encoded swap path 24 | /// @return True if path contains two or more pools, otherwise false 25 | function hasMultiplePools(bytes memory path) internal pure returns (bool) { 26 | return path.length >= MULTIPLE_POOLS_MIN_LENGTH; 27 | } 28 | 29 | /// @notice Returns the number of pools in the path 30 | /// @param path The encoded swap path 31 | /// @return The number of pools in the path 32 | function numPools(bytes memory path) internal pure returns (uint256) { 33 | // Ignore the first token address. From then on every fee and token offset indicates a pool. 34 | return ((path.length - ADDR_SIZE) / NEXT_OFFSET); 35 | } 36 | 37 | /// @notice Decodes the first pool in path 38 | /// @param path The bytes encoded swap path 39 | /// @return tokenA The first token of the given pool 40 | /// @return tokenB The second token of the given pool 41 | /// @return fee The fee level of the pool 42 | function decodeFirstPool(bytes memory path) internal pure returns (address tokenA, address tokenB, uint24 fee) { 43 | tokenA = path.toAddress(0); 44 | fee = path.toUint24(ADDR_SIZE); 45 | tokenB = path.toAddress(NEXT_OFFSET); 46 | } 47 | 48 | /// @notice Gets the segment corresponding to the first pool in the path 49 | /// @param path The bytes encoded swap path 50 | /// @return The segment containing all data necessary to target the first pool in the path 51 | function getFirstPool(bytes memory path) internal pure returns (bytes memory) { 52 | return path.slice(0, POP_OFFSET); 53 | } 54 | 55 | /// @notice Skips a token + fee element from the buffer and returns the remainder 56 | /// @param path The swap path 57 | /// @return The remaining token + fee elements in the path 58 | function skipToken(bytes memory path) internal pure returns (bytes memory) { 59 | return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/integrations/yearn/IYVault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | interface IYVault is IERC20 { 7 | function token() external view returns (address); 8 | 9 | function deposit() external returns (uint256); 10 | 11 | function deposit(uint256 _amount) external returns (uint256); 12 | 13 | function deposit(uint256 _amount, address recipient) external returns (uint256); 14 | 15 | function withdraw() external returns (uint256); 16 | 17 | function withdraw(uint256 maxShares) external returns (uint256); 18 | 19 | function withdraw(uint256 maxShares, address recipient) external returns (uint256); 20 | 21 | function withdraw(uint256 maxShares, address recipient, uint256 maxLoss) external returns (uint256); 22 | 23 | function pricePerShare() external view returns (uint256); 24 | 25 | function name() external view returns (string memory); 26 | 27 | function symbol() external view returns (string memory); 28 | 29 | function decimals() external view returns (uint8); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/interfaces/LICENSE: -------------------------------------------------------------------------------- 1 | (c) Gearbox Holdings, 2022 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. 8 | -------------------------------------------------------------------------------- /contracts/interfaces/aave/IAaveV2_LendingPoolAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | /// @title Aave V2 LendingPool adapter interface 9 | /// @notice Implements logic allowing CAs to interact with Aave's lending pool 10 | interface IAaveV2_LendingPoolAdapter is IAdapter { 11 | /// @notice Deposit underlying tokens into Aave in exchange for aTokens 12 | /// @param asset Address of underlying token to deposit 13 | /// @param amount Amount of underlying tokens to deposit 14 | /// @dev Last two parameters are ignored as `onBehalfOf` can only be credit account, 15 | /// and `referralCode` is set to zero 16 | function deposit(address asset, uint256 amount, address, uint16) external; 17 | 18 | /// @notice Deposit all underlying tokens into Aave in exchange for aTokens, disables underlying 19 | /// @param asset Address of underlying token to deposit 20 | function depositAll(address asset) external; 21 | 22 | /// @notice Withdraw underlying tokens from Aave and burn aTokens 23 | /// @param asset Address of underlying token to deposit 24 | /// @param amount Amount of underlying tokens to withdraw 25 | /// If `type(uint256).max`, will withdraw the full amount 26 | /// @dev Last parameter is ignored because underlying recepient can only be credit account 27 | function withdraw(address asset, uint256 amount, address) external; 28 | 29 | /// @notice Withdraw all underlying tokens from Aave and burn aTokens, disables aToken 30 | /// @param asset Address of underlying token to withdraw 31 | function withdrawAll(address asset) external; 32 | } 33 | -------------------------------------------------------------------------------- /contracts/interfaces/aave/IAaveV2_WrappedATokenAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | /// @title Aave V2 Wrapped aToken adapter interface 9 | /// @notice Implements logic allowing CAs to convert between waTokens, aTokens and underlying tokens 10 | interface IAaveV2_WrappedATokenAdapter is IAdapter { 11 | /// @notice Underlying aToken 12 | function aToken() external view returns (address); 13 | 14 | /// @notice Underlying token 15 | function underlying() external view returns (address); 16 | 17 | /// @notice Collateral token mask of waToken in the credit manager 18 | function waTokenMask() external view returns (uint256); 19 | 20 | /// @notice Collateral token mask of aToken in the credit manager 21 | function aTokenMask() external view returns (uint256); 22 | 23 | /// @notice Collateral token mask of underlying token in the credit manager 24 | function tokenMask() external view returns (uint256); 25 | 26 | /// @notice Deposit given amount of aTokens 27 | /// @param assets Amount of aTokens to deposit in exchange for waTokens 28 | function deposit(uint256 assets) external; 29 | 30 | /// @notice Deposit all balance of aTokens 31 | function depositAll() external; 32 | 33 | /// @notice Deposit given amount underlying tokens 34 | /// @param assets Amount of underlying tokens to deposit in exchange for waTokens 35 | function depositUnderlying(uint256 assets) external; 36 | 37 | /// @notice Deposit all balance of underlying tokens 38 | function depositAllUnderlying() external; 39 | 40 | /// @notice Withdraw given amount of waTokens for aTokens 41 | /// @param shares Amount of waTokens to burn in exchange for aTokens 42 | function withdraw(uint256 shares) external; 43 | 44 | /// @notice Withdraw all balance of waTokens for aTokens 45 | function withdrawAll() external; 46 | 47 | /// @notice Withdraw given amount of waTokens for underlying tokens 48 | /// @param shares Amount of waTokens to burn in exchange for underlying tokens 49 | function withdrawUnderlying(uint256 shares) external; 50 | 51 | /// @notice Withdraw all balance of waTokens for underlying tokens 52 | function withdrawAllUnderlying() external; 53 | } 54 | -------------------------------------------------------------------------------- /contracts/interfaces/aave/IWrappedAToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 7 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 8 | 9 | import {IAToken} from "../../integrations/aave/IAToken.sol"; 10 | import {ILendingPool} from "../../integrations/aave/ILendingPool.sol"; 11 | 12 | /// @title Wrapped aToken interface 13 | interface IWrappedAToken is IERC20Metadata { 14 | /// @notice Emitted on deposit 15 | /// @param account Account that performed deposit 16 | /// @param assets Amount of deposited aTokens 17 | /// @param shares Amount of waTokens minted to account 18 | event Deposit(address account, uint256 assets, uint256 shares); 19 | 20 | /// @notice Emitted on withdrawal 21 | /// @param account Account that performed withdrawal 22 | /// @param assets Amount of withdrawn aTokens 23 | /// @param shares Amount of waTokens burnt from account 24 | event Withdraw(address account, uint256 assets, uint256 shares); 25 | 26 | /// @notice Underlying aToken 27 | function aToken() external view returns (IAToken); 28 | 29 | /// @notice Underlying token 30 | function underlying() external view returns (IERC20); 31 | 32 | /// @notice Aave lending pool 33 | function lendingPool() external view returns (ILendingPool); 34 | 35 | /// @notice Returns amount of aTokens belonging to given account (increases as interest is accrued) 36 | function balanceOfUnderlying(address account) external view returns (uint256); 37 | 38 | /// @notice Returns amount of aTokens per waToken, scaled by 1e18 39 | function exchangeRate() external view returns (uint256); 40 | 41 | /// @notice Deposit given amount of aTokens (aToken must be approved before the call) 42 | /// @param assets Amount of aTokens to deposit in exchange for waTokens 43 | /// @return shares Amount of waTokens minted to the caller 44 | function deposit(uint256 assets) external returns (uint256 shares); 45 | 46 | /// @notice Deposit given amount underlying tokens (underlying must be approved before the call) 47 | /// @param assets Amount of underlying tokens to deposit in exchange for waTokens 48 | /// @return shares Amount of waTokens minted to the caller 49 | function depositUnderlying(uint256 assets) external returns (uint256 shares); 50 | 51 | /// @notice Withdraw given amount of waTokens for aTokens 52 | /// @param shares Amount of waTokens to burn in exchange for aTokens 53 | /// @return assets Amount of aTokens sent to the caller 54 | function withdraw(uint256 shares) external returns (uint256 assets); 55 | 56 | /// @notice Withdraw given amount of waTokens for underlying tokens 57 | /// @param shares Amount of waTokens to burn in exchange for underlying tokens 58 | /// @return assets Amount of underlying tokens sent to the caller 59 | function withdrawUnderlying(uint256 shares) external returns (uint256 assets); 60 | } 61 | -------------------------------------------------------------------------------- /contracts/interfaces/aave/IWrappedATokenGateway.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IPool4626} from "@gearbox-protocol/core-v2/contracts/interfaces/IPool4626.sol"; 7 | import {IAToken} from "../../integrations/aave/IAToken.sol"; 8 | import {IWrappedAToken} from "./IWrappedAToken.sol"; 9 | 10 | /// @title waToken Gateway interface 11 | /// @notice Allows LPs to add/remove aTokens to/from waToken liquidity pool 12 | interface IWrappedATokenGateway { 13 | /// @notice Thrown when trying to create gateway to the contract that is not a registered pool 14 | error NotRegisteredPoolException(); 15 | 16 | /// @notice waToken pool 17 | function pool() external view returns (IPool4626); 18 | 19 | /// @notice waToken address 20 | function waToken() external view returns (IWrappedAToken); 21 | 22 | /// @notice aToken address 23 | function aToken() external view returns (IAToken); 24 | 25 | /// @notice Deposit aTokens into waToken liquidity pool 26 | /// @dev Gateway must be approved to spend aTokens from `msg.sender` before the call 27 | /// @param assets Amount of aTokens to deposit to the pool 28 | /// @param receiver Account that should receive dTokens 29 | /// @param referralCode Referral code, for potential rewards 30 | /// @return shares Amount of dTokens minted to `receiver` 31 | function depositReferral(uint256 assets, address receiver, uint16 referralCode) external returns (uint256 shares); 32 | 33 | /// @notice Redeem aTokens from waToken liquidity pool 34 | /// @dev Gateway must be approved to spend dTokens from `owner` before the call 35 | /// @param shares Amount of dTokens to burn 36 | /// @param receiver Account that should receive aTokens 37 | /// @param owner Account to burn dTokens from 38 | /// @return assets Amount of aTokens sent to `receiver` 39 | function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/interfaces/compound/ICompoundV2_CTokenAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | /// @notice When cToken operation produces an error 9 | error CTokenError(uint256 errorCode); 10 | 11 | /// @title Compound V2 cToken adapter interface 12 | /// @notice Implements logic allowing CAs to interact with Compound's cTokens 13 | interface ICompoundV2_CTokenAdapter is IAdapter { 14 | /// @notice cToken that this adapter is connected to 15 | function cToken() external view returns (address); 16 | 17 | /// @notice cToken's underlying token 18 | function underlying() external view returns (address); 19 | 20 | /// @notice Collateral token mask of underlying token in the credit manager 21 | function tokenMask() external view returns (uint256); 22 | 23 | /// @notice Collateral token mask of cToken in the credit manager 24 | function cTokenMask() external view returns (uint256); 25 | 26 | /// @notice Deposit given amount of underlying tokens into Compound in exchange for cTokens 27 | /// @param amount Amount of underlying tokens to deposit 28 | function mint(uint256 amount) external; 29 | 30 | /// @notice Deposit all underlying tokens into Compound in exchange for cTokens, disables underlying 31 | function mintAll() external; 32 | 33 | /// @notice Burn given amount of cTokens to withdraw underlying from Compound 34 | /// @param amount Amount of cTokens to burn 35 | function redeem(uint256 amount) external; 36 | 37 | /// @notice Withdraw all underlying tokens from Compound and burn cTokens, disables cToken 38 | function redeemAll() external; 39 | 40 | /// @notice Burn cTokens to withdraw given amount of underlying from Compound 41 | /// @param amount Amount of underlying to withdraw 42 | function redeemUnderlying(uint256 amount) external; 43 | } 44 | -------------------------------------------------------------------------------- /contracts/interfaces/convex/IConvexV1BaseRewardPoolAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | /// @title Convex V1 BaseRewardPool adapter interface 9 | /// @notice Implements logic for interacting with Convex reward pool 10 | interface IConvexV1BaseRewardPoolAdapter is IAdapter { 11 | /// @notice Address of a Curve LP token deposited into the Convex pool 12 | function curveLPtoken() external view returns (address); 13 | 14 | /// @notice Address of a Convex LP token staked in the reward pool 15 | function stakingToken() external view returns (address); 16 | 17 | /// @notice Address of a phantom token representing account's stake in the reward pool 18 | function stakedPhantomToken() external view returns (address); 19 | 20 | /// @notice Collateral token mask of a Curve LP token in the credit manager 21 | function curveLPTokenMask() external view returns (uint256); 22 | 23 | /// @notice Collateral token mask of a Convex LP token in the credit manager 24 | function stakingTokenMask() external view returns (uint256); 25 | 26 | /// @notice Collateral token mask of a reward pool stake token 27 | function stakedTokenMask() external view returns (uint256); 28 | 29 | /// @notice Bitmask of all reward tokens of the pool (CRV, CVX, extra reward tokens, if any) in the credit manager 30 | function rewardTokensMask() external view returns (uint256); 31 | 32 | /// @notice Stakes Convex LP token in the reward pool 33 | /// @dev `amount` parameter is ignored since calldata is passed directly to the target contract 34 | function stake(uint256) external; 35 | 36 | /// @notice Stakes the entire balance of Convex LP token in the reward pool, disables LP token 37 | function stakeAll() external; 38 | 39 | /// @notice Claims rewards on the current position, enables reward tokens 40 | function getReward() external; 41 | 42 | /// @notice Withdraws Convex LP token from the reward pool 43 | /// @param claim Whether to claim staking rewards 44 | /// @dev `amount` parameter is ignored since calldata is passed directly to the target contract 45 | function withdraw(uint256, bool claim) external; 46 | 47 | /// @notice Withdraws the entire balance of Convex LP token from the reward pool, disables staked token 48 | /// @param claim Whether to claim staking rewards 49 | function withdrawAll(bool claim) external; 50 | 51 | /// @notice Withdraws Convex LP token from the reward pool and unwraps it into Curve LP token 52 | /// @param claim Whether to claim staking rewards 53 | /// @dev `amount` parameter is ignored since calldata is passed directly to the target contract 54 | function withdrawAndUnwrap(uint256, bool claim) external; 55 | 56 | /// @notice Withdraws the entire balance of Convex LP token from the reward pool and unwraps it into Curve LP token, 57 | /// disables staked token 58 | /// @param claim Whether to claim staking rewards 59 | function withdrawAllAndUnwrap(bool claim) external; 60 | } 61 | -------------------------------------------------------------------------------- /contracts/interfaces/convex/IConvexV1BoosterAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | /// @title Convex V1 Booster adapter interface 9 | /// @notice Implements logic allowing CAs to interact with Convex Booster 10 | interface IConvexV1BoosterAdapter is IAdapter { 11 | /// @notice Maps pool ID to phantom token representing staked position 12 | function pidToPhantomToken(uint256) external view returns (address); 13 | 14 | /// @notice Deposits Curve LP tokens into Booster 15 | /// @param _pid ID of the pool to deposit to 16 | /// @param _stake Whether to stake Convex LP tokens in the rewards pool 17 | /// @dev `_amount` parameter is ignored since calldata is passed directly to the target contract 18 | function deposit(uint256 _pid, uint256, bool _stake) external; 19 | 20 | /// @notice Deposits the entire balance of Curve LP tokens into Booster, disables Curve LP token 21 | /// @param _pid ID of the pool to deposit to 22 | /// @param _stake Whether to stake Convex LP tokens in the rewards pool 23 | function depositAll(uint256 _pid, bool _stake) external; 24 | 25 | /// @notice Withdraws Curve LP tokens from Booster 26 | /// @param _pid ID of the pool to withdraw from 27 | /// @dev `_amount` parameter is ignored since calldata is passed directly to the target contract 28 | function withdraw(uint256 _pid, uint256) external; 29 | 30 | /// @notice Withdraws all Curve LP tokens from Booster, disables Convex LP token 31 | /// @param _pid ID of the pool to withdraw from 32 | /// @dev `_amount` parameter is ignored since calldata is passed directly to the target contract 33 | function withdrawAll(uint256 _pid) external; 34 | 35 | /// @notice Updates the mapping of pool IDs to phantom staked token addresses 36 | function updateStakedPhantomTokensMap() external; 37 | } 38 | -------------------------------------------------------------------------------- /contracts/interfaces/curve/ICurveV1_2AssetsAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {N_COINS} from "../../integrations/curve/ICurvePool_2.sol"; 7 | import {ICurveV1Adapter} from "./ICurveV1Adapter.sol"; 8 | 9 | /// @title Curve V1 2 assets adapter interface 10 | /// @notice Implements logic allowing to interact with Curve pools with 2 assets 11 | interface ICurveV1_2AssetsAdapter is ICurveV1Adapter { 12 | /// @notice Add liquidity to the pool 13 | /// @param amounts Amounts of tokens to add 14 | /// @dev `min_mint_amount` parameter is ignored because calldata is passed directly to the target contract 15 | function add_liquidity(uint256[N_COINS] calldata amounts, uint256) external; 16 | 17 | /// @notice Remove liquidity from the pool 18 | /// @dev '_amount' and 'min_amounts' parameters are ignored because calldata is directly passed to the target contract 19 | function remove_liquidity(uint256, uint256[N_COINS] calldata) external; 20 | 21 | /// @notice Withdraw exact amounts of tokens from the pool 22 | /// @param amounts Amounts of tokens to withdraw 23 | /// @dev `max_burn_amount` parameter is ignored because calldata is directly passed to the target contract 24 | function remove_liquidity_imbalance(uint256[N_COINS] calldata amounts, uint256) external; 25 | } 26 | -------------------------------------------------------------------------------- /contracts/interfaces/curve/ICurveV1_3AssetsAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {N_COINS} from "../../integrations/curve/ICurvePool_3.sol"; 7 | import {ICurveV1Adapter} from "./ICurveV1Adapter.sol"; 8 | 9 | /// @title Curve V1 3 assets adapter interface 10 | /// @notice Implements logic allowing to interact with Curve pools with 3 assets 11 | interface ICurveV1_3AssetsAdapter is ICurveV1Adapter { 12 | /// @notice Add liquidity to the pool 13 | /// @param amounts Amounts of tokens to add 14 | /// @dev `min_mint_amount` parameter is ignored because calldata is passed directly to the target contract 15 | function add_liquidity(uint256[N_COINS] calldata amounts, uint256) external; 16 | 17 | /// @notice Remove liquidity from the pool 18 | /// @dev '_amount' and 'min_amounts' parameters are ignored because calldata is directly passed to the target contract 19 | function remove_liquidity(uint256, uint256[N_COINS] calldata) external; 20 | 21 | /// @notice Withdraw exact amounts of tokens from the pool 22 | /// @param amounts Amounts of tokens to withdraw 23 | /// @dev `max_burn_amount` parameter is ignored because calldata is directly passed to the target contract 24 | function remove_liquidity_imbalance(uint256[N_COINS] calldata amounts, uint256) external; 25 | } 26 | -------------------------------------------------------------------------------- /contracts/interfaces/curve/ICurveV1_4AssetsAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {N_COINS} from "../../integrations/curve/ICurvePool_4.sol"; 7 | import {ICurveV1Adapter} from "./ICurveV1Adapter.sol"; 8 | 9 | /// @title Curve V1 4 assets adapter interface 10 | /// @notice Implements logic allowing to interact with Curve pools with 4 assets 11 | interface ICurveV1_4AssetsAdapter is ICurveV1Adapter { 12 | /// @notice Add liquidity to the pool 13 | /// @param amounts Amounts of tokens to add 14 | /// @dev `min_mint_amount` parameter is ignored because calldata is passed directly to the target contract 15 | function add_liquidity(uint256[N_COINS] calldata amounts, uint256) external; 16 | 17 | /// @notice Remove liquidity from the pool 18 | /// @dev '_amount' and 'min_amounts' parameters are ignored because calldata is directly passed to the target contract 19 | function remove_liquidity(uint256, uint256[N_COINS] calldata) external; 20 | 21 | /// @notice Withdraw exact amounts of tokens from the pool 22 | /// @param amounts Amounts of tokens to withdraw 23 | /// @dev `max_burn_amount` parameter is ignored because calldata is directly passed to the target contract 24 | function remove_liquidity_imbalance(uint256[N_COINS] calldata amounts, uint256) external; 25 | } 26 | -------------------------------------------------------------------------------- /contracts/interfaces/euler/IEulerV1_ETokenAdapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | /// @title Euler V1 eToken adapter interface 9 | /// @notice Implements logic allowing CAs to interact with Euler's eTokens 10 | interface IEulerV1_ETokenAdapter is IAdapter { 11 | /// @notice Address of the eToken's underlying token 12 | function underlying() external view returns (address); 13 | 14 | /// @notice Collateral token mask of underlying token in the credit manager 15 | function tokenMask() external view returns (uint256); 16 | 17 | /// @notice Collateral token mask of eToken in the credit manager 18 | function eTokenMask() external view returns (uint256); 19 | 20 | /// @notice Deposit underlying tokens into Euler in exchange for eTokens 21 | /// @param amount Amount of underlying tokens to deposit, set to `type(uint256).max` 22 | /// to deposit full amount (in this case, underlying will be disabled) 23 | /// @dev First param (`subAccountId`) is ignored since CAs can't use Euler's sub-accounts 24 | function deposit(uint256, uint256 amount) external; 25 | 26 | /// @notice Deposit all underlying tokens into Euler in exchange for eTokens, disables underlying 27 | function depositAll() external; 28 | 29 | /// @notice Withdraw underlying tokens from Euler and burn eTokens 30 | /// @param amount Amount of underlying tokens to withdraw, set to `type(uint256).max` 31 | /// to withdraw full amount (in this case, EToken will be disabled) 32 | /// @dev First param (`subAccountId`) is ignored since CAs can't use Euler's sub-accounts 33 | function withdraw(uint256, uint256 amount) external; 34 | 35 | /// @notice Withdraw all underlying tokens from Euler and burn eTokens, disables EToken 36 | function withdrawAll() external; 37 | } 38 | -------------------------------------------------------------------------------- /contracts/interfaces/lido/ILidoV1Adapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | interface ILidoV1AdapterEvents { 9 | /// @notice Emitted when configurator sets new deposit limit 10 | event NewLimit(uint256 _limit); 11 | } 12 | 13 | interface ILidoV1AdapterExceptions { 14 | /// @notice Thrown when trying to stake more than the current limit 15 | error LimitIsOverException(); 16 | } 17 | 18 | /// @title Lido V1 adapter interface 19 | /// @notice Implements logic for interacting with the Lido contract through the gateway 20 | interface ILidoV1Adapter is IAdapter, ILidoV1AdapterEvents, ILidoV1AdapterExceptions { 21 | /// @notice Address of WETH 22 | function weth() external view returns (address); 23 | 24 | /// @notice Address of the Lido contract 25 | function stETH() external view returns (address); 26 | 27 | /// @notice Collateral token mask of WETH in the credit manager 28 | function wethTokenMask() external view returns (uint256); 29 | 30 | /// @notice Collateral token mask of stETH in the credit manager 31 | function stETHTokenMask() external view returns (uint256); 32 | 33 | /// @notice Address of Gearbox treasury 34 | function treasury() external view returns (address); 35 | 36 | /// @notice The amount of WETH that can be deposited through this adapter 37 | function limit() external view returns (uint256); 38 | 39 | /// @notice Stakes given amount of WETH in Lido via Gateway 40 | /// @param amount Amount of WETH to deposit 41 | /// @dev The referral address is set to Gearbox treasury 42 | function submit(uint256 amount) external; 43 | 44 | /// @notice Stakes the entire balance of WETH in Lido via Gateway, disables WETH 45 | /// @dev The referral address is set to Gearbox treasury 46 | function submitAll() external; 47 | 48 | /// @notice Set a new deposit limit 49 | /// @param _limit New value for the limit 50 | function setLimit(uint256 _limit) external; 51 | } 52 | -------------------------------------------------------------------------------- /contracts/interfaces/lido/IwstETHV1Adapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | /// @title wstETH adapter interface 9 | /// @notice Implements logic for wrapping / unwrapping stETH 10 | interface IwstETHV1Adapter is IAdapter { 11 | /// @notice Address of the Lido contract 12 | function stETH() external view returns (address); 13 | 14 | /// @notice Collateral token mask of stETH in the credit manager 15 | function stETHTokenMask() external view returns (uint256); 16 | 17 | /// @notice Collateral token mask of wstETH in the credit manager 18 | function wstETHTokenMask() external view returns (uint256); 19 | 20 | /// @notice Wraps given amount of stETH into wstETH 21 | /// @param amount Amount of stETH to wrap 22 | function wrap(uint256 amount) external; 23 | 24 | /// @notice Wraps the entire balance of stETH into wstETH, disables stETH 25 | function wrapAll() external; 26 | 27 | /// @notice Unwraps given amount of wstETH into stETH 28 | /// @param amount Amount of wstETH to unwrap 29 | function unwrap(uint256 amount) external; 30 | 31 | /// @notice Unwraps the entire balance of wstETH to stETH, disables wstETH 32 | function unwrapAll() external; 33 | } 34 | -------------------------------------------------------------------------------- /contracts/interfaces/uniswap/IUniswapConnectorChecker.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.17; 5 | 6 | interface IUniswapConnectorChecker { 7 | /// @notice Returns true if given token is a registered connector token 8 | function isConnector(address token) external view returns (bool); 9 | 10 | /// @notice Returns the array of registered connector tokens 11 | function getConnectors() external view returns (address[] memory connectors); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/interfaces/uniswap/IUniswapV2Adapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | import {IUniswapConnectorChecker} from "./IUniswapConnectorChecker.sol"; 8 | 9 | interface IUniswapV2AdapterExceptions { 10 | /// @notice Thrown when sanity checks on a swap path fail 11 | error InvalidPathException(); 12 | } 13 | 14 | /// @title Uniswap V2 Router adapter interface 15 | /// @notice Implements logic allowing CAs to perform swaps via Uniswap V2 and its forks 16 | interface IUniswapV2Adapter is IAdapter, IUniswapConnectorChecker, IUniswapV2AdapterExceptions { 17 | /// @notice Swap input token for given amount of output token 18 | /// @param amountOut Amount of output token to receive 19 | /// @param amountInMax Maximum amount of input token to spend 20 | /// @param path Array of token addresses representing swap path, which must have at most 3 hops 21 | /// through registered connector tokens 22 | /// @param deadline Maximum timestamp until which the transaction is valid 23 | /// @dev Parameter `to` is ignored since swap recipient can only be the credit account 24 | function swapTokensForExactTokens( 25 | uint256 amountOut, 26 | uint256 amountInMax, 27 | address[] calldata path, 28 | address, 29 | uint256 deadline 30 | ) external; 31 | 32 | /// @notice Swap given amount of input token to output token 33 | /// @param amountIn Amount of input token to spend 34 | /// @param amountOutMin Minumum amount of output token to receive 35 | /// @param path Array of token addresses representing swap path, which must have at most 3 hops 36 | /// through registered connector tokens 37 | /// @param deadline Maximum timestamp until which the transaction is valid 38 | /// @dev Parameter `to` is ignored since swap recipient can only be the credit account 39 | function swapExactTokensForTokens( 40 | uint256 amountIn, 41 | uint256 amountOutMin, 42 | address[] calldata path, 43 | address, 44 | uint256 deadline 45 | ) external; 46 | 47 | /// @notice Swap the entire balance of input token to output token, disables input token 48 | /// @param rateMinRAY Minimum exchange rate between input and output tokens, scaled by 1e27 49 | /// @param path Array of token addresses representing swap path, which must have at most 3 hops 50 | /// through registered connector tokens 51 | /// @param deadline Maximum timestamp until which the transaction is valid 52 | function swapAllTokensForTokens(uint256 rateMinRAY, address[] calldata path, uint256 deadline) external; 53 | } 54 | -------------------------------------------------------------------------------- /contracts/interfaces/yearn/IYearnV2Adapter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 7 | 8 | /// @title Yearn V2 Vault adapter interface 9 | /// @notice Implements logic allowing CAs to deposit into Yearn vaults 10 | interface IYearnV2Adapter is IAdapter { 11 | /// @notice Vault's underlying token address 12 | function token() external view returns (address); 13 | 14 | /// @notice Collateral token mask of underlying token in the credit manager 15 | function tokenMask() external view returns (uint256); 16 | 17 | /// @notice Collateral token mask of eToken in the credit manager 18 | function yTokenMask() external view returns (uint256); 19 | 20 | /// @notice Deposit the entire balance of underlying tokens into the vault, disables underlying 21 | function deposit() external; 22 | 23 | /// @notice Deposit given amount of underlying tokens into the vault 24 | /// @param amount Amount of underlying tokens to deposit 25 | function deposit(uint256 amount) external; 26 | 27 | /// @notice Deposit given amount of underlying tokens into the vault 28 | /// @param amount Amount of underlying tokens to deposit 29 | /// @dev Second param (`recipient`) is ignored because it can only be the credit account 30 | function deposit(uint256 amount, address) external; 31 | 32 | /// @notice Withdraw the entire balance of underlying from the vault, disables yToken 33 | function withdraw() external; 34 | 35 | /// @notice Burn given amount of yTokens to withdraw corresponding amount of underlying from the vault 36 | /// @param maxShares Amout of yTokens to burn 37 | function withdraw(uint256 maxShares) external; 38 | 39 | /// @notice Burn given amount of yTokens to withdraw corresponding amount of underlying from the vault 40 | /// @param maxShares Amout of yTokens to burn 41 | /// @dev Second param (`recipient`) is ignored because it can only be the credit account 42 | function withdraw(uint256 maxShares, address) external; 43 | 44 | /// @notice Burn given amount of yTokens to withdraw corresponding amount of underlying from the vault 45 | /// @param maxShares Amout of yTokens to burn 46 | /// @param maxLoss Maximal slippage on withdrawal in basis points 47 | /// @dev Second param (`recipient`) is ignored because it can only be the credit account 48 | function withdraw(uint256 maxShares, address, uint256 maxLoss) external; 49 | } 50 | -------------------------------------------------------------------------------- /contracts/multicall/aave/AaveV2_LendingPoolCalls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | 8 | import {IAaveV2_LendingPoolAdapter} from "../../interfaces/aave/IAaveV2_LendingPoolAdapter.sol"; 9 | 10 | interface AaveV2_LendingPoolMulticaller {} 11 | 12 | library AaveV2_LendingPoolCalls { 13 | function deposit(AaveV2_LendingPoolMulticaller c, address asset, uint256 amount, address, uint16) 14 | internal 15 | pure 16 | returns (MultiCall memory) 17 | { 18 | return MultiCall({ 19 | target: address(c), 20 | callData: abi.encodeCall(IAaveV2_LendingPoolAdapter.deposit, (asset, amount, address(0), 0)) 21 | }); 22 | } 23 | 24 | function depositAll(AaveV2_LendingPoolMulticaller c, address asset) internal pure returns (MultiCall memory) { 25 | return MultiCall({target: address(c), callData: abi.encodeCall(IAaveV2_LendingPoolAdapter.depositAll, (asset))}); 26 | } 27 | 28 | function withdraw(AaveV2_LendingPoolMulticaller c, address asset, uint256 amount, address) 29 | internal 30 | pure 31 | returns (MultiCall memory) 32 | { 33 | return MultiCall({ 34 | target: address(c), 35 | callData: abi.encodeCall(IAaveV2_LendingPoolAdapter.withdraw, (asset, amount, address(0))) 36 | }); 37 | } 38 | 39 | function withdrawAll(AaveV2_LendingPoolMulticaller c, address asset) internal pure returns (MultiCall memory) { 40 | return 41 | MultiCall({target: address(c), callData: abi.encodeCall(IAaveV2_LendingPoolAdapter.withdrawAll, (asset))}); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /contracts/multicall/aave/AaveV2_WrappedATokenCalls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | 8 | import {IAaveV2_WrappedATokenAdapter} from "../../interfaces/aave/IAaveV2_WrappedATokenAdapter.sol"; 9 | 10 | interface AaveV2_WrappedATokenMulticaller {} 11 | 12 | library AaveV2_WrappedATokenCalls { 13 | function deposit(AaveV2_WrappedATokenMulticaller c, uint256 assets) internal pure returns (MultiCall memory) { 14 | return MultiCall({target: address(c), callData: abi.encodeCall(IAaveV2_WrappedATokenAdapter.deposit, (assets))}); 15 | } 16 | 17 | function depositAll(AaveV2_WrappedATokenMulticaller c) internal pure returns (MultiCall memory) { 18 | return MultiCall({target: address(c), callData: abi.encodeCall(IAaveV2_WrappedATokenAdapter.depositAll, ())}); 19 | } 20 | 21 | function depositUnderlying(AaveV2_WrappedATokenMulticaller c, uint256 assets) 22 | internal 23 | pure 24 | returns (MultiCall memory) 25 | { 26 | return MultiCall({ 27 | target: address(c), 28 | callData: abi.encodeCall(IAaveV2_WrappedATokenAdapter.depositUnderlying, (assets)) 29 | }); 30 | } 31 | 32 | function depositAllUnderlying(AaveV2_WrappedATokenMulticaller c) internal pure returns (MultiCall memory) { 33 | return MultiCall({ 34 | target: address(c), 35 | callData: abi.encodeCall(IAaveV2_WrappedATokenAdapter.depositAllUnderlying, ()) 36 | }); 37 | } 38 | 39 | function withdraw(AaveV2_WrappedATokenMulticaller c, uint256 shares) internal pure returns (MultiCall memory) { 40 | return 41 | MultiCall({target: address(c), callData: abi.encodeCall(IAaveV2_WrappedATokenAdapter.withdraw, (shares))}); 42 | } 43 | 44 | function withdrawAll(AaveV2_WrappedATokenMulticaller c) internal pure returns (MultiCall memory) { 45 | return MultiCall({target: address(c), callData: abi.encodeCall(IAaveV2_WrappedATokenAdapter.withdrawAll, ())}); 46 | } 47 | 48 | function withdrawUnderlying(AaveV2_WrappedATokenMulticaller c, uint256 shares) 49 | internal 50 | pure 51 | returns (MultiCall memory) 52 | { 53 | return MultiCall({ 54 | target: address(c), 55 | callData: abi.encodeCall(IAaveV2_WrappedATokenAdapter.withdrawUnderlying, (shares)) 56 | }); 57 | } 58 | 59 | function withdrawAllUnderlying(AaveV2_WrappedATokenMulticaller c) internal pure returns (MultiCall memory) { 60 | return MultiCall({ 61 | target: address(c), 62 | callData: abi.encodeCall(IAaveV2_WrappedATokenAdapter.withdrawAllUnderlying, ()) 63 | }); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /contracts/multicall/compound/CompoundV2_Calls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | 8 | import {ICompoundV2_CTokenAdapter} from "../../interfaces/compound/ICompoundV2_CTokenAdapter.sol"; 9 | 10 | interface CompoundV2_Multicaller {} 11 | 12 | library CompoundV2_Calls { 13 | function mint(CompoundV2_Multicaller c, uint256 mintAmount) internal pure returns (MultiCall memory) { 14 | return MultiCall({target: address(c), callData: abi.encodeCall(ICompoundV2_CTokenAdapter.mint, (mintAmount))}); 15 | } 16 | 17 | function mintAll(CompoundV2_Multicaller c) internal pure returns (MultiCall memory) { 18 | return MultiCall({target: address(c), callData: abi.encodeCall(ICompoundV2_CTokenAdapter.mintAll, ())}); 19 | } 20 | 21 | function redeem(CompoundV2_Multicaller c, uint256 redeemTokens) internal pure returns (MultiCall memory) { 22 | return 23 | MultiCall({target: address(c), callData: abi.encodeCall(ICompoundV2_CTokenAdapter.redeem, (redeemTokens))}); 24 | } 25 | 26 | function redeemAll(CompoundV2_Multicaller c) internal pure returns (MultiCall memory) { 27 | return MultiCall({target: address(c), callData: abi.encodeCall(ICompoundV2_CTokenAdapter.redeemAll, ())}); 28 | } 29 | 30 | function redeemUnderlying(CompoundV2_Multicaller c, uint256 redeemAmount) 31 | internal 32 | pure 33 | returns (MultiCall memory) 34 | { 35 | return MultiCall({ 36 | target: address(c), 37 | callData: abi.encodeCall(ICompoundV2_CTokenAdapter.redeemUnderlying, (redeemAmount)) 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/multicall/convex/ConvexV1_BaseRewardPoolCalls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | 8 | import {IConvexV1BaseRewardPoolAdapter} from "../../interfaces/convex/IConvexV1BaseRewardPoolAdapter.sol"; 9 | 10 | interface ConvexV1_BaseRewardPoolMulticaller {} 11 | 12 | library ConvexV1_BaseRewardPoolCalls { 13 | function stake(ConvexV1_BaseRewardPoolMulticaller c, uint256 amount) internal pure returns (MultiCall memory) { 14 | return MultiCall({target: address(c), callData: abi.encodeCall(IConvexV1BaseRewardPoolAdapter.stake, (amount))}); 15 | } 16 | 17 | function stakeAll(ConvexV1_BaseRewardPoolMulticaller c) internal pure returns (MultiCall memory) { 18 | return MultiCall({target: address(c), callData: abi.encodeCall(IConvexV1BaseRewardPoolAdapter.stakeAll, ())}); 19 | } 20 | 21 | function withdraw(ConvexV1_BaseRewardPoolMulticaller c, uint256 amount, bool claim) 22 | internal 23 | pure 24 | returns (MultiCall memory) 25 | { 26 | return MultiCall({ 27 | target: address(c), 28 | callData: abi.encodeCall(IConvexV1BaseRewardPoolAdapter.withdraw, (amount, claim)) 29 | }); 30 | } 31 | 32 | function withdrawAll(ConvexV1_BaseRewardPoolMulticaller c, bool claim) internal pure returns (MultiCall memory) { 33 | return MultiCall({ 34 | target: address(c), 35 | callData: abi.encodeCall(IConvexV1BaseRewardPoolAdapter.withdrawAll, (claim)) 36 | }); 37 | } 38 | 39 | function withdrawAndUnwrap(ConvexV1_BaseRewardPoolMulticaller c, uint256 amount, bool claim) 40 | internal 41 | pure 42 | returns (MultiCall memory) 43 | { 44 | return MultiCall({ 45 | target: address(c), 46 | callData: abi.encodeCall(IConvexV1BaseRewardPoolAdapter.withdrawAndUnwrap, (amount, claim)) 47 | }); 48 | } 49 | 50 | function withdrawAllAndUnwrap(ConvexV1_BaseRewardPoolMulticaller c, bool claim) 51 | internal 52 | pure 53 | returns (MultiCall memory) 54 | { 55 | return MultiCall({ 56 | target: address(c), 57 | callData: abi.encodeCall(IConvexV1BaseRewardPoolAdapter.withdrawAllAndUnwrap, (claim)) 58 | }); 59 | } 60 | 61 | function getReward(ConvexV1_BaseRewardPoolMulticaller c) internal pure returns (MultiCall memory) { 62 | return MultiCall({target: address(c), callData: abi.encodeCall(IConvexV1BaseRewardPoolAdapter.getReward, ())}); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /contracts/multicall/convex/ConvexV1_BoosterCalls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | 8 | import {IConvexV1BoosterAdapter} from "../../interfaces/convex/IConvexV1BoosterAdapter.sol"; 9 | 10 | interface ConvexV1_BoosterMulticaller {} 11 | 12 | library ConvexV1_BoosterCalls { 13 | function deposit(ConvexV1_BoosterMulticaller c, uint256 pid, uint256 amount, bool stake) 14 | internal 15 | pure 16 | returns (MultiCall memory) 17 | { 18 | return MultiCall({ 19 | target: address(c), 20 | callData: abi.encodeCall(IConvexV1BoosterAdapter.deposit, (pid, amount, stake)) 21 | }); 22 | } 23 | 24 | function depositAll(ConvexV1_BoosterMulticaller c, uint256 pid, bool stake) 25 | internal 26 | pure 27 | returns (MultiCall memory) 28 | { 29 | return 30 | MultiCall({target: address(c), callData: abi.encodeCall(IConvexV1BoosterAdapter.depositAll, (pid, stake))}); 31 | } 32 | 33 | function withdraw(ConvexV1_BoosterMulticaller c, uint256 pid, uint256 amount) 34 | internal 35 | pure 36 | returns (MultiCall memory) 37 | { 38 | return 39 | MultiCall({target: address(c), callData: abi.encodeCall(IConvexV1BoosterAdapter.withdraw, (pid, amount))}); 40 | } 41 | 42 | function withdrawAll(ConvexV1_BoosterMulticaller c, uint256 pid) internal pure returns (MultiCall memory) { 43 | return MultiCall({target: address(c), callData: abi.encodeCall(IConvexV1BoosterAdapter.withdrawAll, (pid))}); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /contracts/multicall/euler/EulerV1_Calls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | 8 | import {IEulerV1_ETokenAdapter} from "../../interfaces/euler/IEulerV1_ETokenAdapter.sol"; 9 | 10 | interface EulerV1_Multicaller {} 11 | 12 | library EulerV1_Calls { 13 | function deposit(EulerV1_Multicaller c, uint256, uint256 amount) internal pure returns (MultiCall memory) { 14 | return MultiCall({target: address(c), callData: abi.encodeCall(IEulerV1_ETokenAdapter.deposit, (0, amount))}); 15 | } 16 | 17 | function depositAll(EulerV1_Multicaller c) internal pure returns (MultiCall memory) { 18 | return MultiCall({target: address(c), callData: abi.encodeCall(IEulerV1_ETokenAdapter.depositAll, ())}); 19 | } 20 | 21 | function withdraw(EulerV1_Multicaller c, uint256, uint256 amount) internal pure returns (MultiCall memory) { 22 | return MultiCall({target: address(c), callData: abi.encodeCall(IEulerV1_ETokenAdapter.withdraw, (0, amount))}); 23 | } 24 | 25 | function withdrawAll(EulerV1_Multicaller c) internal pure returns (MultiCall memory) { 26 | return MultiCall({target: address(c), callData: abi.encodeCall(IEulerV1_ETokenAdapter.withdrawAll, ())}); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/multicall/lido/LidoV1_Calls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | 8 | import {ILidoV1Adapter} from "../../interfaces/lido/ILidoV1Adapter.sol"; 9 | 10 | interface LidoV1_Multicaller {} 11 | 12 | library LidoV1_Calls { 13 | function submit(LidoV1_Multicaller c, uint256 amount) internal pure returns (MultiCall memory) { 14 | return MultiCall({target: address(c), callData: abi.encodeCall(ILidoV1Adapter.submit, (amount))}); 15 | } 16 | 17 | function submitAll(LidoV1_Multicaller c) internal pure returns (MultiCall memory) { 18 | return MultiCall({target: address(c), callData: abi.encodeCall(ILidoV1Adapter.submitAll, ())}); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/multicall/lido/WstETHV1_Calls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | 8 | import {IwstETHV1Adapter} from "../../interfaces/lido/IwstETHV1Adapter.sol"; 9 | 10 | interface WstETHV1_Multicaller {} 11 | 12 | library WstETHV1_Calls { 13 | function wrap(WstETHV1_Multicaller c, uint256 amount) internal pure returns (MultiCall memory) { 14 | return MultiCall({target: address(c), callData: abi.encodeCall(IwstETHV1Adapter.wrap, (amount))}); 15 | } 16 | 17 | function wrapAll(WstETHV1_Multicaller c) internal pure returns (MultiCall memory) { 18 | return MultiCall({target: address(c), callData: abi.encodeCall(IwstETHV1Adapter.wrapAll, ())}); 19 | } 20 | 21 | function unwrap(WstETHV1_Multicaller c, uint256 amount) internal pure returns (MultiCall memory) { 22 | return MultiCall({target: address(c), callData: abi.encodeCall(IwstETHV1Adapter.unwrap, (amount))}); 23 | } 24 | 25 | function unwrapAll(WstETHV1_Multicaller c) internal pure returns (MultiCall memory) { 26 | return MultiCall({target: address(c), callData: abi.encodeCall(IwstETHV1Adapter.unwrapAll, ())}); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/multicall/uniswap/UniswapV2_Calls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | import {IUniswapV2Adapter} from "../../interfaces/uniswap/IUniswapV2Adapter.sol"; 8 | 9 | interface UniswapV2_Multicaller {} 10 | 11 | library UniswapV2_Calls { 12 | function swapTokensForExactTokens( 13 | UniswapV2_Multicaller c, 14 | uint256 amountOut, 15 | uint256 amountInMax, 16 | address[] memory path, 17 | address, 18 | uint256 deadline 19 | ) internal pure returns (MultiCall memory) { 20 | return MultiCall({ 21 | target: address(c), 22 | callData: abi.encodeCall( 23 | IUniswapV2Adapter.swapTokensForExactTokens, (amountOut, amountInMax, path, address(0), deadline) 24 | ) 25 | }); 26 | } 27 | 28 | function swapExactTokensForTokens( 29 | UniswapV2_Multicaller c, 30 | uint256 amountIn, 31 | uint256 amountOutMin, 32 | address[] memory path, 33 | address, 34 | uint256 deadline 35 | ) internal pure returns (MultiCall memory) { 36 | return MultiCall({ 37 | target: address(c), 38 | callData: abi.encodeCall( 39 | IUniswapV2Adapter.swapExactTokensForTokens, (amountIn, amountOutMin, path, address(0), deadline) 40 | ) 41 | }); 42 | } 43 | 44 | function swapAllTokensForTokens( 45 | UniswapV2_Multicaller c, 46 | uint256 rateMinRAY, 47 | address[] memory path, 48 | uint256 deadline 49 | ) internal pure returns (MultiCall memory) { 50 | return MultiCall({ 51 | target: address(c), 52 | callData: abi.encodeCall(IUniswapV2Adapter.swapAllTokensForTokens, (rateMinRAY, path, deadline)) 53 | }); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /contracts/multicall/uniswap/UniswapV3_Calls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | import {ISwapRouter} from "../../integrations/uniswap/IUniswapV3.sol"; 8 | import {IUniswapV3Adapter} from "../../interfaces/uniswap/IUniswapV3Adapter.sol"; 9 | 10 | interface UniswapV3_Multicaller {} 11 | 12 | library UniswapV3_Calls { 13 | function exactInputSingle(UniswapV3_Multicaller c, ISwapRouter.ExactInputSingleParams memory params) 14 | internal 15 | pure 16 | returns (MultiCall memory) 17 | { 18 | return MultiCall({target: address(c), callData: abi.encodeCall(IUniswapV3Adapter.exactInputSingle, (params))}); 19 | } 20 | 21 | function exactAllInputSingle(UniswapV3_Multicaller c, IUniswapV3Adapter.ExactAllInputSingleParams memory params) 22 | internal 23 | pure 24 | returns (MultiCall memory) 25 | { 26 | return 27 | MultiCall({target: address(c), callData: abi.encodeCall(IUniswapV3Adapter.exactAllInputSingle, (params))}); 28 | } 29 | 30 | function exactInput(UniswapV3_Multicaller c, ISwapRouter.ExactInputParams memory params) 31 | internal 32 | pure 33 | returns (MultiCall memory) 34 | { 35 | return MultiCall({target: address(c), callData: abi.encodeCall(IUniswapV3Adapter.exactInput, (params))}); 36 | } 37 | 38 | function exactAllInput(UniswapV3_Multicaller c, IUniswapV3Adapter.ExactAllInputParams memory params) 39 | internal 40 | pure 41 | returns (MultiCall memory) 42 | { 43 | return MultiCall({target: address(c), callData: abi.encodeCall(IUniswapV3Adapter.exactAllInput, (params))}); 44 | } 45 | 46 | function exactOutputSingle(UniswapV3_Multicaller c, ISwapRouter.ExactOutputSingleParams memory params) 47 | internal 48 | pure 49 | returns (MultiCall memory) 50 | { 51 | return MultiCall({target: address(c), callData: abi.encodeCall(IUniswapV3Adapter.exactOutputSingle, (params))}); 52 | } 53 | 54 | function exactOutput(UniswapV3_Multicaller c, ISwapRouter.ExactOutputParams memory params) 55 | internal 56 | pure 57 | returns (MultiCall memory) 58 | { 59 | return MultiCall({target: address(c), callData: abi.encodeCall(IUniswapV3Adapter.exactOutput, (params))}); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/multicall/yearn/YearnV2_Calls.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/libraries/MultiCall.sol"; 7 | 8 | interface YearnV2_Multicaller {} 9 | 10 | library YearnV2_Calls { 11 | function deposit(YearnV2_Multicaller c) internal pure returns (MultiCall memory) { 12 | return MultiCall({target: address(c), callData: abi.encodeWithSignature("deposit()")}); 13 | } 14 | 15 | function deposit(YearnV2_Multicaller c, uint256 amount) internal pure returns (MultiCall memory) { 16 | return MultiCall({target: address(c), callData: abi.encodeWithSignature("deposit(uint256)", amount)}); 17 | } 18 | 19 | function deposit(YearnV2_Multicaller c, uint256 amount, address) internal pure returns (MultiCall memory) { 20 | return MultiCall({ 21 | target: address(c), 22 | callData: abi.encodeWithSignature("deposit(uint256,address)", amount, address(0)) 23 | }); 24 | } 25 | 26 | function withdraw(YearnV2_Multicaller c) internal pure returns (MultiCall memory) { 27 | return MultiCall({target: address(c), callData: abi.encodeWithSignature("withdraw()")}); 28 | } 29 | 30 | function withdraw(YearnV2_Multicaller c, uint256 maxShares) internal pure returns (MultiCall memory) { 31 | return MultiCall({target: address(c), callData: abi.encodeWithSignature("withdraw(uint256)", maxShares)}); 32 | } 33 | 34 | function withdraw(YearnV2_Multicaller c, uint256 maxShares, address) internal pure returns (MultiCall memory) { 35 | return MultiCall({ 36 | target: address(c), 37 | callData: abi.encodeWithSignature("withdraw(uint256,address)", maxShares, address(0)) 38 | }); 39 | } 40 | 41 | function withdraw(YearnV2_Multicaller c, uint256 maxShares, address, uint256 maxLoss) 42 | internal 43 | pure 44 | returns (MultiCall memory) 45 | { 46 | return MultiCall({ 47 | target: address(c), 48 | callData: abi.encodeWithSignature("withdraw(uint256,address,uint256)", maxShares, address(0), maxLoss) 49 | }); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/oracles/aave/AavePriceFeed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 7 | import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; 8 | import {PriceFeedType} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeedType.sol"; 9 | import {LPPriceFeed} from "@gearbox-protocol/core-v2/contracts/oracles/LPPriceFeed.sol"; 10 | import {WAD} from "@gearbox-protocol/core-v2/contracts/libraries/Constants.sol"; 11 | 12 | import {IWrappedAToken} from "../../interfaces/aave/IWrappedAToken.sol"; 13 | 14 | // EXCEPTIONS 15 | import {ZeroAddressException} from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; 16 | 17 | uint256 constant RANGE_WIDTH = 200; // 2% 18 | 19 | /// @title Aave V2 wrapped aToken price feed 20 | contract AavePriceFeed is LPPriceFeed { 21 | /// @dev Chainlink price feed for the aToken's underlying token 22 | AggregatorV3Interface public immutable priceFeed; 23 | 24 | /// @dev Address of the waToken to compute prices for 25 | IWrappedAToken public immutable waToken; 26 | 27 | /// @dev Scale of the waToken's exchange rate 28 | uint256 public constant decimalsDivider = WAD; 29 | 30 | PriceFeedType public constant override priceFeedType = PriceFeedType.AAVE_ORACLE; 31 | uint256 public constant override version = 1; 32 | 33 | /// @dev Whether to skip price sanity checks. 34 | /// @notice Always set to true for LP price feeds, 35 | /// since they perform their own sanity checks 36 | bool public constant override skipPriceCheck = true; 37 | 38 | constructor(address addressProvider, address _waToken, address _priceFeed) 39 | LPPriceFeed( 40 | addressProvider, 41 | RANGE_WIDTH, 42 | _waToken != address(0) ? string(abi.encodePacked(IWrappedAToken(_waToken).name(), " priceFeed")) : "" 43 | ) 44 | { 45 | if (_waToken == address(0) || _priceFeed == address(0)) { 46 | revert ZeroAddressException(); 47 | } 48 | 49 | waToken = IWrappedAToken(_waToken); 50 | priceFeed = AggregatorV3Interface(_priceFeed); 51 | 52 | uint256 exchangeRate = waToken.exchangeRate(); 53 | _setLimiter(exchangeRate); 54 | } 55 | 56 | /// @dev Returns the USD price of the waToken 57 | /// @notice Computes the waToken price as (price(underlying) * exchangeRate) 58 | function latestRoundData() 59 | external 60 | view 61 | override 62 | returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) 63 | { 64 | (roundId, answer, startedAt, updatedAt, answeredInRound) = priceFeed.latestRoundData(); 65 | 66 | // Sanity check for chainlink pricefeed 67 | _checkAnswer(roundId, answer, updatedAt, answeredInRound); 68 | 69 | uint256 exchangeRate = waToken.exchangeRate(); 70 | 71 | // Checks that exchangeRate is within bounds 72 | exchangeRate = _checkAndUpperBoundValue(exchangeRate); 73 | 74 | answer = int256((exchangeRate * uint256(answer)) / decimalsDivider); 75 | } 76 | 77 | function _checkCurrentValueInBounds(uint256 _lowerBound, uint256 _uBound) internal view override returns (bool) { 78 | uint256 rate = waToken.exchangeRate(); 79 | if (rate < _lowerBound || rate > _uBound) { 80 | return false; 81 | } 82 | return true; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /contracts/oracles/compound/CompoundPriceFeed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; 7 | import {PriceFeedType} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeedType.sol"; 8 | import {LPPriceFeed} from "@gearbox-protocol/core-v2/contracts/oracles/LPPriceFeed.sol"; 9 | import {WAD} from "@gearbox-protocol/core-v2/contracts/libraries/Constants.sol"; 10 | 11 | import {ICToken} from "../../integrations/compound/ICToken.sol"; 12 | 13 | // EXCEPTIONS 14 | import {ZeroAddressException} from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; 15 | 16 | uint256 constant RANGE_WIDTH = 200; // 2% 17 | 18 | /// @title Compound V2 cToken price feed 19 | contract CompoundPriceFeed is LPPriceFeed { 20 | /// @dev Chainlink price feed for the underlying token 21 | AggregatorV3Interface public immutable priceFeed; 22 | 23 | /// @dev Address of the cToken to compute prices for 24 | ICToken public immutable cToken; 25 | 26 | /// @dev Scale of the cToken's exchangeRate 27 | uint256 public constant decimalsDivider = WAD; 28 | 29 | PriceFeedType public constant override priceFeedType = PriceFeedType.COMPOUND_ORACLE; 30 | uint256 public constant override version = 1; 31 | 32 | /// @dev Whether to skip price sanity checks. 33 | /// @notice Always set to true for LP price feeds, 34 | /// since they perform their own sanity checks 35 | bool public constant override skipPriceCheck = true; 36 | 37 | constructor(address addressProvider, address _cToken, address _priceFeed) 38 | LPPriceFeed( 39 | addressProvider, 40 | RANGE_WIDTH, 41 | _cToken != address(0) ? string(abi.encodePacked(ICToken(_cToken).name(), " priceFeed")) : "" 42 | ) 43 | { 44 | if (_cToken == address(0) || _priceFeed == address(0)) { 45 | revert ZeroAddressException(); 46 | } 47 | 48 | cToken = ICToken(_cToken); 49 | priceFeed = AggregatorV3Interface(_priceFeed); 50 | 51 | uint256 exchangeRate = cToken.exchangeRateCurrent(); 52 | _setLimiter(exchangeRate); 53 | } 54 | 55 | /// @dev Returns the USD price of the cToken 56 | /// @notice Computes the cToken price as (price(underlying) * exchangeRate) 57 | function latestRoundData() 58 | external 59 | view 60 | override 61 | returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) 62 | { 63 | (roundId, answer, startedAt, updatedAt, answeredInRound) = priceFeed.latestRoundData(); 64 | 65 | // Sanity check for chainlink pricefeed 66 | _checkAnswer(roundId, answer, updatedAt, answeredInRound); 67 | 68 | uint256 exchangeRate = cToken.exchangeRateStored(); 69 | 70 | // Checks that exchangeRate is within bounds 71 | exchangeRate = _checkAndUpperBoundValue(exchangeRate); 72 | 73 | answer = int256((exchangeRate * uint256(answer)) / decimalsDivider); 74 | } 75 | 76 | function _checkCurrentValueInBounds(uint256 _lowerBound, uint256 _uBound) internal view override returns (bool) { 77 | uint256 rate = cToken.exchangeRateStored(); 78 | if (rate < _lowerBound || rate > _uBound) { 79 | return false; 80 | } 81 | return true; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /contracts/oracles/curve/AbstractCurveLPPriceFeed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {LPPriceFeed} from "@gearbox-protocol/core-v2/contracts/oracles/LPPriceFeed.sol"; 7 | import {ICurvePool} from "../../integrations/curve/ICurvePool.sol"; 8 | 9 | // EXCEPTIONS 10 | import { 11 | ZeroAddressException, NotImplementedException 12 | } from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; 13 | 14 | uint256 constant RANGE_WIDTH = 200; // 2% 15 | 16 | /// @title Abstract CurveLP pricefeed 17 | abstract contract AbstractCurveLPPriceFeed is LPPriceFeed { 18 | /// @dev The Curve pool associated with the evaluated LP token 19 | ICurvePool public immutable curvePool; 20 | 21 | /// @dev Format of pool's virtual_price 22 | int256 public immutable decimalsDivider; 23 | 24 | /// @dev Contract version 25 | uint256 public constant override version = 1; 26 | 27 | /// @dev Whether to skip price sanity checks. 28 | /// @notice Always set to true for LP price feeds, 29 | /// since they perform their own sanity checks 30 | bool public constant override skipPriceCheck = true; 31 | 32 | constructor(address addressProvider, address _curvePool, string memory _description) 33 | LPPriceFeed(addressProvider, RANGE_WIDTH, _description) 34 | { 35 | if (_curvePool == address(0)) revert ZeroAddressException(); 36 | 37 | curvePool = ICurvePool(_curvePool); // F:[OCLP-1] 38 | decimalsDivider = 10 ** 18; 39 | 40 | uint256 virtualPrice = ICurvePool(_curvePool).get_virtual_price(); 41 | _setLimiter(virtualPrice); 42 | } 43 | 44 | function _checkCurrentValueInBounds(uint256 _lowerBound, uint256 _upperBound) 45 | internal 46 | view 47 | override 48 | returns (bool) 49 | { 50 | uint256 virtualPrice = curvePool.get_virtual_price(); 51 | if (virtualPrice < _lowerBound || virtualPrice > _upperBound) { 52 | return false; 53 | } 54 | return true; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/oracles/curve/CurveLP2PriceFeed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; 7 | import {AbstractCurveLPPriceFeed} from "./AbstractCurveLPPriceFeed.sol"; 8 | 9 | import {PriceFeedType} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeedType.sol"; 10 | 11 | // EXCEPTIONS 12 | import { 13 | ZeroAddressException, NotImplementedException 14 | } from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; 15 | 16 | /// @title CurveLP price feed for 2 assets 17 | contract CurveLP2PriceFeed is AbstractCurveLPPriceFeed { 18 | /// @dev Price feed of coin 0 in the pool 19 | AggregatorV3Interface public immutable priceFeed1; 20 | 21 | /// @dev Price feed of coin 1 in the pool 22 | AggregatorV3Interface public immutable priceFeed2; 23 | 24 | PriceFeedType public constant override priceFeedType = PriceFeedType.CURVE_2LP_ORACLE; 25 | 26 | constructor( 27 | address addressProvider, 28 | address _curvePool, 29 | address _priceFeed1, 30 | address _priceFeed2, 31 | string memory _description 32 | ) AbstractCurveLPPriceFeed(addressProvider, _curvePool, _description) { 33 | if (_priceFeed1 == address(0) || _priceFeed2 == address(0)) { 34 | revert ZeroAddressException(); 35 | } 36 | 37 | priceFeed1 = AggregatorV3Interface(_priceFeed1); // F:[OCLP-1] 38 | priceFeed2 = AggregatorV3Interface(_priceFeed2); // F:[OCLP-1] 39 | } 40 | 41 | /// @dev Returns the USD price of the pool's LP token 42 | /// @notice Computes the LP token price as (min_t(price(coin_t)) * virtual_price()) 43 | /// See more at https://dev.gearbox.fi/docs/documentation/oracle/curve-pricefeed 44 | function latestRoundData() 45 | external 46 | view 47 | virtual 48 | override 49 | returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) 50 | { 51 | (roundId, answer, startedAt, updatedAt, answeredInRound) = priceFeed1.latestRoundData(); // F:[OCLP-4] 52 | 53 | // Sanity check for the Chainlink pricefeed 54 | _checkAnswer(roundId, answer, updatedAt, answeredInRound); 55 | 56 | (uint80 roundId2, int256 answer2, uint256 startedAt2, uint256 updatedAt2, uint80 answeredInRound2) = 57 | priceFeed2.latestRoundData(); // F:[OCLP-4] 58 | 59 | // Sanity check for the Chainlink pricefeed 60 | _checkAnswer(roundId2, answer2, updatedAt2, answeredInRound2); 61 | 62 | if (answer2 < answer) { 63 | roundId = roundId2; 64 | answer = answer2; 65 | startedAt = startedAt2; 66 | updatedAt = updatedAt2; 67 | answeredInRound = answeredInRound2; 68 | } // F:[OCLP-4] 69 | 70 | uint256 virtualPrice = curvePool.get_virtual_price(); 71 | 72 | // Checks that virtual_price is in within bounds 73 | virtualPrice = _checkAndUpperBoundValue(virtualPrice); // F: [OCLP-7] 74 | 75 | answer = (answer * int256(virtualPrice)) / decimalsDivider; // F:[OCLP-4] 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /contracts/oracles/euler/EulerPriceFeed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 7 | import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; 8 | import {PriceFeedType} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeedType.sol"; 9 | import {LPPriceFeed} from "@gearbox-protocol/core-v2/contracts/oracles/LPPriceFeed.sol"; 10 | import {WAD} from "@gearbox-protocol/core-v2/contracts/libraries/Constants.sol"; 11 | 12 | import {IEToken} from "../../integrations/euler/IEToken.sol"; 13 | 14 | // EXCEPTIONS 15 | import {ZeroAddressException} from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; 16 | 17 | uint256 constant RANGE_WIDTH = 200; // 2% 18 | 19 | /// @title Euler price feed 20 | contract EulerPriceFeed is LPPriceFeed { 21 | /// @dev Chainlink price feed for the underlying token 22 | AggregatorV3Interface public immutable priceFeed; 23 | 24 | /// @dev Address of the eToken to compute prices for 25 | IEToken public immutable eToken; 26 | 27 | /// @dev Scale of the eToken's exchange rate 28 | uint256 public immutable decimalsDivider; 29 | 30 | PriceFeedType public constant override priceFeedType = PriceFeedType.EULER_ORACLE; 31 | uint256 public constant override version = 1; 32 | 33 | /// @dev Whether to skip price sanity checks. 34 | /// @notice Always set to true for LP price feeds, 35 | /// since they perform their own sanity checks 36 | bool public constant override skipPriceCheck = true; 37 | 38 | constructor(address addressProvider, address _eToken, address _priceFeed) 39 | LPPriceFeed( 40 | addressProvider, 41 | RANGE_WIDTH, 42 | _eToken != address(0) ? string(abi.encodePacked(IEToken(_eToken).name(), " priceFeed")) : "" 43 | ) 44 | { 45 | if (_eToken == address(0) || _priceFeed == address(0)) { 46 | revert ZeroAddressException(); 47 | } 48 | 49 | eToken = IEToken(_eToken); 50 | priceFeed = AggregatorV3Interface(_priceFeed); 51 | 52 | decimalsDivider = 10 ** IERC20Metadata(eToken.underlyingAsset()).decimals(); 53 | uint256 exchangeRate = _exchangeRate(); 54 | _setLimiter(exchangeRate); 55 | } 56 | 57 | /// @dev Returns the USD price of the eToken 58 | /// @notice Computes the eToken price as (price(underlying) * exchangeRate) 59 | function latestRoundData() 60 | external 61 | view 62 | override 63 | returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) 64 | { 65 | (roundId, answer, startedAt, updatedAt, answeredInRound) = priceFeed.latestRoundData(); 66 | 67 | // Sanity check for chainlink pricefeed 68 | _checkAnswer(roundId, answer, updatedAt, answeredInRound); 69 | 70 | uint256 exchangeRate = _exchangeRate(); 71 | 72 | // Checks that exchangeRate is within bounds 73 | exchangeRate = _checkAndUpperBoundValue(exchangeRate); 74 | 75 | answer = int256((exchangeRate * uint256(answer)) / decimalsDivider); 76 | } 77 | 78 | function _checkCurrentValueInBounds(uint256 _lowerBound, uint256 _uBound) internal view override returns (bool) { 79 | uint256 rate = _exchangeRate(); 80 | if (rate < _lowerBound || rate > _uBound) { 81 | return false; 82 | } 83 | return true; 84 | } 85 | 86 | function _exchangeRate() internal view returns (uint256) { 87 | return eToken.convertBalanceToUnderlying(WAD); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /contracts/oracles/lido/WstETHPriceFeed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 7 | import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; 8 | import {PriceFeedType} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeedType.sol"; 9 | import {LPPriceFeed} from "@gearbox-protocol/core-v2/contracts/oracles/LPPriceFeed.sol"; 10 | 11 | import {IwstETH} from "../../integrations/lido/IwstETH.sol"; 12 | // EXCEPTIONS 13 | import { 14 | ZeroAddressException, NotImplementedException 15 | } from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; 16 | 17 | uint256 constant RANGE_WIDTH = 200; // 2% 18 | 19 | /// @title Yearn price feed 20 | contract WstETHPriceFeed is LPPriceFeed { 21 | /// @dev Chainlink price feed for the stETH token 22 | AggregatorV3Interface public immutable priceFeed; 23 | 24 | /// @dev wstETH token address 25 | IwstETH public immutable wstETH; 26 | 27 | /// @dev Format of the wstETH's stETHperToken() 28 | uint256 public immutable decimalsDivider; 29 | 30 | PriceFeedType public constant override priceFeedType = PriceFeedType.WSTETH_ORACLE; 31 | 32 | uint256 public constant override version = 1; 33 | 34 | /// @dev Whether to skip price sanity checks. 35 | /// @notice Always set to true for LP price feeds, 36 | /// since they perform their own sanity checks 37 | bool public constant override skipPriceCheck = true; 38 | 39 | constructor(address addressProvider, address _wstETH, address _priceFeed) 40 | LPPriceFeed( 41 | addressProvider, 42 | RANGE_WIDTH, 43 | _wstETH != address(0) ? string(abi.encodePacked(IERC20Metadata(_wstETH).name(), " priceFeed")) : "" 44 | ) // F:[WSTPF-1] 45 | { 46 | if (_wstETH == address(0) || _priceFeed == address(0)) { 47 | revert ZeroAddressException(); 48 | } // F:[WSTPF-2] 49 | 50 | wstETH = IwstETH(_wstETH); // F:[WSTPF-1] 51 | priceFeed = AggregatorV3Interface(_priceFeed); // F:[WSTPF-1] 52 | 53 | decimalsDivider = 10 ** IwstETH(_wstETH).decimals(); // F:[WSTPF-1] 54 | uint256 stEthPerToken = IwstETH(_wstETH).stEthPerToken(); // F:[WSTPF-1] 55 | _setLimiter(stEthPerToken); // F:[WSTPF-1] 56 | } 57 | 58 | /// @dev Returns the USD price of the pool's LP token 59 | /// @notice Computes the vault share price as (price(underlying) * pricePerShare()) 60 | /// See more at https://dev.gearbox.fi/docs/documentation/oracle/yearn-pricefeed 61 | function latestRoundData() 62 | external 63 | view 64 | override 65 | returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) 66 | { 67 | (roundId, answer, startedAt, updatedAt, answeredInRound) = priceFeed.latestRoundData(); // F:[WSTPF-4] 68 | 69 | // Sanity check for chainlink pricefeed 70 | _checkAnswer(roundId, answer, updatedAt, answeredInRound); // F:[WSTPF-5] 71 | 72 | uint256 stEthPerToken = wstETH.stEthPerToken(); // F:[WSTPF-4] 73 | 74 | // Checks that pricePerShare is within bounds 75 | stEthPerToken = _checkAndUpperBoundValue(stEthPerToken); // F:[WSTPF-5] 76 | 77 | answer = int256((stEthPerToken * uint256(answer)) / decimalsDivider); // F:[WSTPF-4] 78 | } 79 | 80 | function _checkCurrentValueInBounds(uint256 _lowerBound, uint256 _uBound) internal view override returns (bool) { 81 | uint256 pps = wstETH.stEthPerToken(); 82 | if (pps < _lowerBound || pps > _uBound) { 83 | return false; 84 | } 85 | return true; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /contracts/oracles/yearn/YearnPriceFeed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BUSL-1.1 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; 7 | import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; 8 | import {PriceFeedType} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeedType.sol"; 9 | import {LPPriceFeed} from "@gearbox-protocol/core-v2/contracts/oracles/LPPriceFeed.sol"; 10 | 11 | import {IYVault} from "../../integrations/yearn/IYVault.sol"; 12 | 13 | // EXCEPTIONS 14 | import { 15 | ZeroAddressException, NotImplementedException 16 | } from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; 17 | 18 | uint256 constant RANGE_WIDTH = 200; // 2% 19 | 20 | /// @title Yearn price feed 21 | contract YearnPriceFeed is LPPriceFeed { 22 | /// @dev Chainlink price feed for the Vault's underlying 23 | AggregatorV3Interface public immutable priceFeed; 24 | 25 | /// @dev Address of the vault to compute prices for 26 | IYVault public immutable yVault; 27 | 28 | /// @dev Format of the vault's pricePerShare() 29 | uint256 public immutable decimalsDivider; 30 | 31 | PriceFeedType public constant override priceFeedType = PriceFeedType.YEARN_ORACLE; 32 | uint256 public constant override version = 2; 33 | 34 | /// @dev Whether to skip price sanity checks. 35 | /// @notice Always set to true for LP price feeds, 36 | /// since they perform their own sanity checks 37 | bool public constant override skipPriceCheck = true; 38 | 39 | constructor(address addressProvider, address _yVault, address _priceFeed) 40 | LPPriceFeed( 41 | addressProvider, 42 | RANGE_WIDTH, // F:[YPF-1] 43 | _yVault != address(0) 44 | ? string( 45 | abi.encodePacked(IERC20Metadata(_yVault).name(), " priceFeed") // F:[YPF-1] 46 | ) 47 | : "" 48 | ) 49 | { 50 | if (_yVault == address(0) || _priceFeed == address(0)) { 51 | revert ZeroAddressException(); 52 | } // F:[OYPF-2] 53 | 54 | yVault = IYVault(_yVault); // F:[OYPF-1] 55 | priceFeed = AggregatorV3Interface(_priceFeed); // F:[OYPF-1] 56 | 57 | decimalsDivider = 10 ** IYVault(_yVault).decimals(); // F:[OYPF-1] 58 | uint256 pricePerShare = IYVault(_yVault).pricePerShare(); // F:[OYPF-1] 59 | _setLimiter(pricePerShare); // F:[OYPF-1] 60 | } 61 | 62 | /// @dev Returns the USD price of the pool's LP token 63 | /// @notice Computes the vault share price as (price(underlying) * pricePerShare()) 64 | /// See more at https://dev.gearbox.fi/docs/documentation/oracle/yearn-pricefeed 65 | function latestRoundData() 66 | external 67 | view 68 | override 69 | returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) 70 | { 71 | (roundId, answer, startedAt, updatedAt, answeredInRound) = priceFeed.latestRoundData(); // F:[OYPF-4] 72 | 73 | // Sanity check for chainlink pricefeed 74 | _checkAnswer(roundId, answer, updatedAt, answeredInRound); // F:[OYPF-5] 75 | 76 | uint256 pricePerShare = yVault.pricePerShare(); // F:[OYPF-4] 77 | 78 | // Checks that pricePerShare is within bounds 79 | pricePerShare = _checkAndUpperBoundValue(pricePerShare); // F:[OYPF-5] 80 | 81 | answer = int256((pricePerShare * uint256(answer)) / decimalsDivider); // F:[OYPF-4] 82 | } 83 | 84 | function _checkCurrentValueInBounds(uint256 _lowerBound, uint256 _uBound) internal view override returns (bool) { 85 | uint256 pps = yVault.pricePerShare(); 86 | if (pps < _lowerBound || pps > _uBound) { 87 | return false; 88 | } 89 | return true; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /contracts/test/adapters/AdapterTestHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import { 7 | ICreditManagerV2, 8 | ICreditManagerV2Events 9 | } from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditManagerV2.sol"; 10 | import {ICreditFacadeEvents} from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditFacade.sol"; 11 | import {IAdapterExceptions} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; 12 | 13 | // TEST 14 | import "../lib/constants.sol"; 15 | 16 | // SUITES 17 | import {TokensTestSuite} from "../suites/TokensTestSuite.sol"; 18 | import {Tokens} from "../config/Tokens.sol"; 19 | 20 | import {CreditFacadeTestSuite} from "@gearbox-protocol/core-v2/contracts/test/suites/CreditFacadeTestSuite.sol"; 21 | 22 | import {BalanceHelper} from "../helpers/BalanceHelper.sol"; 23 | import {CreditFacadeTestHelper} from "../helpers/CreditFacadeTestHelper.sol"; 24 | import {CreditConfig} from "../config/CreditConfig.sol"; 25 | 26 | contract AdapterTestHelper is 27 | DSTest, 28 | ICreditManagerV2Events, 29 | ICreditFacadeEvents, 30 | BalanceHelper, 31 | CreditFacadeTestHelper 32 | { 33 | error TokenIsNotInAllowedList(address); 34 | 35 | function _setUp() internal { 36 | _setUp(Tokens.DAI); 37 | } 38 | 39 | function _setUp(Tokens t) internal { 40 | require(t == Tokens.DAI || t == Tokens.WETH || t == Tokens.STETH, "Unsupported token"); 41 | 42 | tokenTestSuite = new TokensTestSuite(); 43 | tokenTestSuite.topUpWETH{value: 100 * WAD}(); 44 | 45 | CreditConfig creditConfig = new CreditConfig(tokenTestSuite, t); 46 | 47 | cft = new CreditFacadeTestSuite(creditConfig); 48 | 49 | underlying = cft.underlying(); 50 | 51 | creditManager = cft.creditManager(); 52 | creditFacade = cft.creditFacade(); 53 | creditConfigurator = cft.creditConfigurator(); 54 | } 55 | 56 | function _getUniswapDeadline() internal view returns (uint256) { 57 | return block.timestamp + 1; 58 | } 59 | 60 | function expectMulticallStackCalls( 61 | address, // adapter, 62 | address targetContract, 63 | address borrower, 64 | bytes memory callData, 65 | address tokenIn, 66 | address, // tokenOut, 67 | bool allowTokenIn 68 | ) internal { 69 | evm.expectEmit(true, false, false, false); 70 | emit MultiCallStarted(borrower); 71 | 72 | if (allowTokenIn) { 73 | evm.expectCall( 74 | address(creditManager), 75 | abi.encodeCall(ICreditManagerV2.approveCreditAccount, (targetContract, tokenIn, type(uint256).max)) 76 | ); 77 | } 78 | 79 | evm.expectCall( 80 | address(creditManager), abi.encodeCall(ICreditManagerV2.executeOrder, (targetContract, callData)) 81 | ); 82 | 83 | evm.expectEmit(true, false, false, false); 84 | emit ExecuteOrder(targetContract); 85 | 86 | if (allowTokenIn) { 87 | evm.expectCall( 88 | address(creditManager), 89 | abi.encodeCall(ICreditManagerV2.approveCreditAccount, (targetContract, tokenIn, 1)) 90 | ); 91 | } 92 | 93 | evm.expectEmit(false, false, false, false); 94 | emit MultiCallFinished(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /contracts/test/adapters/mainnet/WstETHV1Adapter.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {PoolService} from "@gearbox-protocol/core-v2/contracts/pool/PoolService.sol"; 7 | import {CreditFacade} from "@gearbox-protocol/core-v2/contracts/credit/CreditFacade.sol"; 8 | 9 | import {CreditManager} from "@gearbox-protocol/core-v2/contracts/credit/CreditManager.sol"; 10 | 11 | // TEST 12 | import "../../lib/constants.sol"; 13 | import {Tokens} from "../../config/Tokens.sol"; 14 | 15 | // SUITES 16 | 17 | import {LiveEnvHelper} from "../../suites/LiveEnvHelper.sol"; 18 | import {IwstETH} from "../../../integrations/lido/IwstETH.sol"; 19 | 20 | contract LiveWstETHV1AdapterTest is DSTest, LiveEnvHelper { 21 | function setUp() public liveOnly { 22 | _setUp(); 23 | } 24 | 25 | /// @dev [WSTETHA-1]: Credit account for wsteth CM can be opened 26 | function test_live_WSTETHA_01_credit_account_can_be_opened() public liveOnly { 27 | CreditFacade cf = lts.creditFacades(Tokens.wstETH); 28 | CreditManager cm = lts.creditManagers(Tokens.wstETH); 29 | 30 | tokenTestSuite.mint(Tokens.STETH, USER, wstETH_ACCOUNT_AMOUNT); 31 | 32 | tokenTestSuite.approve(Tokens.STETH, USER, tokenTestSuite.addressOf(Tokens.wstETH)); 33 | 34 | IwstETH wstETH = IwstETH(tokenTestSuite.addressOf(Tokens.wstETH)); 35 | 36 | evm.startPrank(USER); 37 | 38 | uint256 amount = wstETH.wrap(wstETH_ACCOUNT_AMOUNT); 39 | wstETH.approve(address(cm), type(uint256).max); 40 | 41 | cf.openCreditAccount(amount, USER, 300, 0); 42 | evm.stopPrank(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /contracts/test/config/Tokens.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way. 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | /// @dev c-Tokens and LUNA are added for unit test purposes 7 | enum Tokens { 8 | NO_TOKEN, 9 | cDAI, 10 | cUSDC, 11 | cUSDT, 12 | cLINK, 13 | LUNA, 14 | _1INCH, 15 | AAVE, 16 | COMP, 17 | CRV, 18 | DAI, 19 | DPI, 20 | FEI, 21 | LINK, 22 | SNX, 23 | UNI, 24 | USDC, 25 | USDT, 26 | WBTC, 27 | WETH, 28 | YFI, 29 | STETH, 30 | wstETH, 31 | CVX, 32 | FRAX, 33 | FXS, 34 | LDO, 35 | LUSD, 36 | sUSD, 37 | GUSD, 38 | LQTY, 39 | _3Crv, 40 | crvFRAX, 41 | steCRV, 42 | crvPlain3andSUSD, 43 | FRAX3CRV, 44 | LUSD3CRV, 45 | gusd3CRV, 46 | cvx3Crv, 47 | cvxcrvFRAX, 48 | cvxsteCRV, 49 | cvxFRAX3CRV, 50 | cvxLUSD3CRV, 51 | cvxcrvPlain3andSUSD, 52 | cvxgusd3CRV, 53 | stkcvx3Crv, 54 | stkcvxcrvFRAX, 55 | stkcvxsteCRV, 56 | stkcvxFRAX3CRV, 57 | stkcvxLUSD3CRV, 58 | stkcvxcrvPlain3andSUSD, 59 | stkcvxgusd3CRV, 60 | yvDAI, 61 | yvUSDC, 62 | yvWETH, 63 | yvWBTC, 64 | yvCurve_stETH, 65 | yvCurve_FRAX, 66 | dDAI, 67 | dUSDC, 68 | dWBTC, 69 | dWETH, 70 | dwstETH, 71 | GEAR 72 | } 73 | -------------------------------------------------------------------------------- /contracts/test/helpers/BalanceHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {TokensTestSuite} from "../suites/TokensTestSuite.sol"; 7 | import {Tokens} from "../config/Tokens.sol"; 8 | 9 | import {BalanceEngine} from "@gearbox-protocol/core-v2/contracts/test/helpers/BalanceEngine.sol"; 10 | 11 | /// @title CreditManagerTestSuite 12 | /// @notice Deploys contract for unit testing of CreditManager.sol 13 | contract BalanceHelper is BalanceEngine { 14 | // Suites 15 | TokensTestSuite internal tokenTestSuite; 16 | 17 | modifier withTokenSuite() { 18 | require(address(tokenTestSuite) != address(0), "tokenTestSuite is not set"); 19 | _; 20 | } 21 | 22 | function expectBalance(Tokens t, address holder, uint256 expectedBalance) internal withTokenSuite { 23 | expectBalance(t, holder, expectedBalance, ""); 24 | } 25 | 26 | function expectBalance(Tokens t, address holder, uint256 expectedBalance, string memory reason) 27 | internal 28 | withTokenSuite 29 | { 30 | expectBalance(tokenTestSuite.addressOf(t), holder, expectedBalance, reason); 31 | } 32 | 33 | function expectBalanceGe(Tokens t, address holder, uint256 minBalance, string memory reason) 34 | internal 35 | withTokenSuite 36 | { 37 | require(address(tokenTestSuite) != address(0), "tokenTestSuite is not set"); 38 | 39 | expectBalanceGe(tokenTestSuite.addressOf(t), holder, minBalance, reason); 40 | } 41 | 42 | function expectBalanceLe(Tokens t, address holder, uint256 maxBalance, string memory reason) 43 | internal 44 | withTokenSuite 45 | { 46 | expectBalanceLe(tokenTestSuite.addressOf(t), holder, maxBalance, reason); 47 | } 48 | 49 | function expectAllowance(Tokens t, address owner, address spender, uint256 expectedAllowance) 50 | internal 51 | withTokenSuite 52 | { 53 | expectAllowance(t, owner, spender, expectedAllowance, ""); 54 | } 55 | 56 | function expectAllowance(Tokens t, address owner, address spender, uint256 expectedAllowance, string memory reason) 57 | internal 58 | withTokenSuite 59 | { 60 | require(address(tokenTestSuite) != address(0), "tokenTestSuite is not set"); 61 | 62 | expectAllowance(tokenTestSuite.addressOf(t), owner, spender, expectedAllowance, reason); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /contracts/test/helpers/CreditFacadeTestHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; 7 | import {TokensTestSuite} from "../suites/TokensTestSuite.sol"; 8 | import {CreditFacadeTestEngine} from "@gearbox-protocol/core-v2/contracts/test/helpers/CreditFacadeTestEngine.sol"; 9 | 10 | import {PriceFeedMock} from "@gearbox-protocol/core-v2/contracts/test/mocks/oracles/PriceFeedMock.sol"; 11 | import {Tokens} from "../config/Tokens.sol"; 12 | 13 | import "../lib/constants.sol"; 14 | 15 | /// @title CreditManagerTestSuite 16 | /// @notice Deploys contract for unit testing of CreditManager.sol 17 | contract CreditFacadeTestHelper is CreditFacadeTestEngine { 18 | function expectTokenIsEnabled(Tokens t, bool expectedState) internal { 19 | expectTokenIsEnabled(t, expectedState, ""); 20 | } 21 | 22 | function expectTokenIsEnabled(Tokens t, bool expectedState, string memory reason) internal { 23 | expectTokenIsEnabled(tokenTestSuite().addressOf(t), expectedState, reason); 24 | } 25 | 26 | function addCollateral(Tokens t, uint256 amount) internal { 27 | tokenTestSuite().mint(t, USER, amount); 28 | tokenTestSuite().approve(t, USER, address(creditManager)); 29 | 30 | evm.startPrank(USER); 31 | creditFacade.addCollateral(USER, tokenTestSuite().addressOf(t), amount); 32 | evm.stopPrank(); 33 | } 34 | 35 | function tokenTestSuite() private view returns (TokensTestSuite) { 36 | return TokensTestSuite(payable(address(cft.tokenTestSuite()))); 37 | } 38 | 39 | function addMockPriceFeed(address token, uint256 price) public { 40 | AggregatorV3Interface priceFeed = new PriceFeedMock(int256(price), 8); 41 | 42 | evm.startPrank(CONFIGURATOR); 43 | cft.priceOracle().addPriceFeed(token, address(priceFeed)); 44 | evm.stopPrank(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/test/lib/Path.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.6.0; 3 | 4 | import "../../integrations/uniswap/BytesLib.sol"; 5 | 6 | /// @title Functions for manipulating path data for multihop swaps 7 | library Path { 8 | using BytesLib for bytes; 9 | 10 | /// @dev The length of the bytes encoded address 11 | uint256 private constant ADDR_SIZE = 20; 12 | /// @dev The length of the bytes encoded fee 13 | uint256 private constant FEE_SIZE = 3; 14 | 15 | /// @dev The offset of a single token address and pool fee 16 | uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE; 17 | /// @dev The offset of an encoded pool key 18 | uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE; 19 | /// @dev The minimum length of an encoding that contains 2 or more pools 20 | uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET; 21 | 22 | /// @notice Returns true iff the path contains two or more pools 23 | /// @param path The encoded swap path 24 | /// @return True if path contains two or more pools, otherwise false 25 | function hasMultiplePools(bytes memory path) internal pure returns (bool) { 26 | return path.length >= MULTIPLE_POOLS_MIN_LENGTH; 27 | } 28 | 29 | /// @notice Returns the number of pools in the path 30 | /// @param path The encoded swap path 31 | /// @return The number of pools in the path 32 | function numPools(bytes memory path) internal pure returns (uint256) { 33 | // Ignore the first token address. From then on every fee and token offset indicates a pool. 34 | return ((path.length - ADDR_SIZE) / NEXT_OFFSET); 35 | } 36 | 37 | /// @notice Decodes the first pool in path 38 | /// @param path The bytes encoded swap path 39 | /// @return tokenA The first token of the given pool 40 | /// @return tokenB The second token of the given pool 41 | /// @return fee The fee level of the pool 42 | function decodeFirstPool(bytes memory path) internal pure returns (address tokenA, address tokenB, uint24 fee) { 43 | tokenA = path.toAddress(0); 44 | fee = path.toUint24(ADDR_SIZE); 45 | tokenB = path.toAddress(NEXT_OFFSET); 46 | } 47 | 48 | /// @notice Gets the segment corresponding to the first pool in the path 49 | /// @param path The bytes encoded swap path 50 | /// @return The segment containing all data necessary to target the first pool in the path 51 | function getFirstPool(bytes memory path) internal pure returns (bytes memory) { 52 | return path.slice(0, POP_OFFSET); 53 | } 54 | 55 | /// @notice Skips a token + fee element from the buffer and returns the remainder 56 | /// @param path The swap path 57 | /// @return The remaining token + fee elements in the path 58 | function skipToken(bytes memory path) internal pure returns (bytes memory) { 59 | return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/test/lib/constants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import "@gearbox-protocol/core-v2/contracts/test/lib/constants.sol"; 7 | -------------------------------------------------------------------------------- /contracts/test/mocks/credit/CreditManagerLiveMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {CreditManager} from "@gearbox-protocol/core-v2/contracts/credit/CreditManager.sol"; 7 | 8 | contract CreditManagerLiveMock is CreditManager { 9 | constructor(address _pool) CreditManager(_pool) {} 10 | 11 | function _fullCollateralCheck(address creditAccount, uint256[] memory collateralHints, uint16 minHealthFactor) 12 | internal 13 | override 14 | {} 15 | 16 | function _checkAndEnableToken(address creditAccount, address token) internal override {} 17 | 18 | function _disableToken(address creditAccount, address token) internal override returns (bool) {} 19 | 20 | function _changeEnabledTokens(address creditAccount, uint256 tokensToEnable, uint256 tokensToDisable) 21 | internal 22 | override 23 | returns (bool, bool) 24 | {} 25 | } 26 | -------------------------------------------------------------------------------- /contracts/test/mocks/integrations/BPTMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; 7 | import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 8 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | 10 | contract BPTMock is ERC20, Ownable { 11 | uint8 private immutable _decimals; 12 | uint256[] weights; 13 | bytes32 poolId; 14 | 15 | constructor(string memory name_, string memory symbol_, uint8 decimals_, uint256[] memory _weights, bytes32 _poolId) 16 | ERC20(name_, symbol_) 17 | { 18 | _decimals = decimals_; 19 | weights = _weights; 20 | poolId = _poolId; 21 | } 22 | 23 | function decimals() public view override returns (uint8) { 24 | return _decimals; 25 | } 26 | 27 | function mint(address to, uint256 amount) external { 28 | _mint(to, amount); 29 | } 30 | 31 | function burn(address to, uint256 amount) external returns (bool) { 32 | _burn(to, amount); 33 | return true; 34 | } 35 | 36 | function getNormalizedWeights() external view returns (uint256[] memory) { 37 | return weights; 38 | } 39 | 40 | function getPoolId() external view returns (bytes32) { 41 | return poolId; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /contracts/test/mocks/integrations/BPTStableMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2023 4 | pragma solidity ^0.8.17; 5 | 6 | import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; 7 | import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 8 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | 10 | contract BPTStableMock is ERC20, Ownable { 11 | uint8 private immutable _decimals; 12 | bytes32 poolId; 13 | uint256 rate; 14 | 15 | constructor(string memory name_, string memory symbol_, uint8 decimals_, bytes32 _poolId) ERC20(name_, symbol_) { 16 | _decimals = decimals_; 17 | poolId = _poolId; 18 | rate = 1e18; 19 | } 20 | 21 | function decimals() public view override returns (uint8) { 22 | return _decimals; 23 | } 24 | 25 | function mint(address to, uint256 amount) external { 26 | _mint(to, amount); 27 | } 28 | 29 | function burn(address to, uint256 amount) external returns (bool) { 30 | _burn(to, amount); 31 | return true; 32 | } 33 | 34 | function setRate(uint256 newRate) external { 35 | rate = newRate; 36 | } 37 | 38 | function getRate() external view returns (uint256) { 39 | return rate; 40 | } 41 | 42 | function getPoolId() external view returns (bytes32) { 43 | return poolId; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /contracts/test/mocks/integrations/ConvexClaimZapMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | pragma abicoder v1; 6 | 7 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 8 | import "@openzeppelin/contracts/utils/math/SafeMath.sol"; 9 | 10 | interface IBasicRewards { 11 | function getReward(address _account, bool _claimExtras) external; 12 | 13 | function getReward(address _account) external; 14 | 15 | function getReward(address _account, address _token) external; 16 | 17 | function stakeFor(address, uint256) external; 18 | } 19 | 20 | contract ClaimZapMock { 21 | using SafeERC20 for IERC20; 22 | using SafeMath for uint256; 23 | 24 | address public immutable owner; 25 | address public immutable crv; 26 | address public immutable cvx; 27 | 28 | constructor(address _crv, address _cvx) { 29 | owner = msg.sender; 30 | crv = _crv; 31 | cvx = _cvx; 32 | } 33 | 34 | function getName() external pure returns (string memory) { 35 | return "ClaimZap V2.0"; 36 | } 37 | 38 | function claimRewards( 39 | address[] calldata rewardContracts, 40 | address[] calldata extraRewardContracts, 41 | address[] calldata, 42 | address[] calldata, 43 | uint256 depositCrvMaxAmount, 44 | uint256 minAmountOut, 45 | uint256 depositCvxMaxAmount, 46 | uint256 spendCvxAmount, 47 | uint256 options 48 | ) external { 49 | //claim from main curve LP pools 50 | for (uint256 i = 0; i < rewardContracts.length; i++) { 51 | IBasicRewards(rewardContracts[i]).getReward(msg.sender, true); 52 | } 53 | //claim from extra rewards 54 | for (uint256 i = 0; i < extraRewardContracts.length; i++) { 55 | IBasicRewards(extraRewardContracts[i]).getReward(msg.sender); 56 | } 57 | 58 | _claimExtras(depositCrvMaxAmount, minAmountOut, depositCvxMaxAmount, spendCvxAmount, 0, 0, options); 59 | } 60 | 61 | function _claimExtras( 62 | uint256 depositCrvMaxAmount, 63 | uint256 minAmountOut, 64 | uint256 depositCvxMaxAmount, 65 | uint256 spendCvxAmount, 66 | uint256 removeCrvBalance, 67 | uint256 removeCvxBalance, 68 | uint256 options 69 | ) internal pure { 70 | require(depositCrvMaxAmount == 0, "Claim Zap Mock: Non-zero extra parameter was passed to target"); 71 | require(minAmountOut == 0, "Claim Zap Mock: Non-zero extra parameter was passed to target"); 72 | require(depositCvxMaxAmount == 0, "Claim Zap Mock: Non-zero extra parameter was passed to target"); 73 | require(spendCvxAmount == 0, "Claim Zap Mock: Non-zero extra parameter was passed to target"); 74 | require(removeCrvBalance == 0, "Claim Zap Mock: Non-zero extra parameter was passed to target"); 75 | require(removeCvxBalance == 0, "Claim Zap Mock: Non-zero extra parameter was passed to target"); 76 | require(options == 0, "Claim Zap Mock: Non-zero extra parameter was passed to target"); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /contracts/test/mocks/integrations/ConvexTokenRewardContractMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import "../../../integrations/convex/Interfaces.sol"; 7 | import "@openzeppelin/contracts/utils/math/SafeMath.sol"; 8 | 9 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 10 | import {ERC20Mock} from "@gearbox-protocol/core-v2/contracts/test/mocks/token/ERC20Mock.sol"; 11 | import {CheatCodes, HEVM_ADDRESS} from "@gearbox-protocol/core-v2/contracts/test/lib/cheatCodes.sol"; 12 | 13 | import {VirtualBalanceWrapper} from "./ConvexExtraRewardPoolMock.sol"; 14 | 15 | contract TokenRewardContractMock is VirtualBalanceWrapper { 16 | using SafeMath for uint256; 17 | using SafeERC20 for IERC20; 18 | using SafeERC20 for ERC20Mock; 19 | 20 | CheatCodes evm = CheatCodes(HEVM_ADDRESS); 21 | 22 | uint256 public constant duration = 7 days; 23 | 24 | address public operator; 25 | 26 | /// MOCK PARAMS 27 | mapping(address => uint256) totalRewards; 28 | 29 | constructor(address deposit_, address op_) { 30 | deposits = IDeposit(deposit_); 31 | operator = op_; 32 | } 33 | 34 | function stake(address, uint256) public pure returns (bool) { 35 | return true; 36 | } 37 | 38 | function withdraw(address, uint256) public pure returns (bool) { 39 | return true; 40 | } 41 | 42 | function getReward(address _account, address _token) public returns (bool) { 43 | uint256 reward = totalRewards[_token]; 44 | if (reward > 0) { 45 | totalRewards[_token] = 0; 46 | ERC20Mock(_token).safeTransfer(_account, reward); 47 | } 48 | return true; 49 | } 50 | 51 | function getReward(address _token) external returns (bool) { 52 | getReward(msg.sender, _token); 53 | return true; 54 | } 55 | 56 | /// 57 | /// MOCK FUNCTIONS 58 | /// 59 | 60 | function addRewardAmount(address token, uint256 amount) public { 61 | evm.prank(ERC20Mock(token).minter()); 62 | ERC20Mock(token).mint(address(this), amount); 63 | 64 | totalRewards[token] += amount; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /contracts/test/mocks/integrations/LidoMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.10; 2 | 3 | import "../token/StETHMock.sol"; 4 | 5 | interface ILidoMockEvents { 6 | event Mock_Submitted(address indexed sender, uint256 amount, address referral); 7 | } 8 | 9 | contract LidoMock is StETHMock, ILidoMockEvents { 10 | using SafeMath for uint256; 11 | 12 | receive() external payable { 13 | _submit(address(0)); 14 | } 15 | 16 | function submit(address _referral) external payable returns (uint256) { 17 | return _submit(_referral); 18 | } 19 | 20 | function burnShares(address _account, uint256 _sharesAmount) external { 21 | _burnShares(_account, _sharesAmount); 22 | } 23 | 24 | /** 25 | * @dev Process user deposit, mints liquid tokens and increase the pool buffer 26 | * @param _referral address of referral. 27 | * @return amount of StETH shares generated 28 | */ 29 | function _submit(address _referral) internal returns (uint256) { 30 | address sender = msg.sender; 31 | uint256 deposit = msg.value; 32 | require(deposit != 0, "ZERO_DEPOSIT"); 33 | 34 | uint256 sharesAmount = getSharesByPooledEth(deposit); 35 | if (sharesAmount == 0) { 36 | // totalControlledEther is 0: either the first-ever deposit or complete slashing 37 | // assume that shares correspond to Ether 1-to-1 38 | sharesAmount = deposit; 39 | } 40 | 41 | totalPooledEtherSynced += deposit; 42 | 43 | _mintShares(sender, sharesAmount); 44 | _submitted(sender, deposit, _referral); 45 | _emitTransferAfterMintingShares(sender, sharesAmount); 46 | return sharesAmount; 47 | } 48 | 49 | function _emitTransferAfterMintingShares(address _to, uint256 _sharesAmount) internal { 50 | emit Transfer(address(0), _to, getPooledEthByShares(_sharesAmount)); 51 | } 52 | 53 | function _submitted(address _sender, uint256 _value, address _referral) internal { 54 | emit Mock_Submitted(_sender, _value, _referral); 55 | } 56 | 57 | function syncExchangeRate(uint256 totalPooledEther, uint256 totalShares) external { 58 | totalPooledEtherSynced = totalPooledEther; 59 | totalSharesSynced = totalShares; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/test/mocks/integrations/WstETHV1Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; 7 | 8 | import {WAD} from "@gearbox-protocol/core-v2/contracts/libraries/Constants.sol"; 9 | 10 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 11 | import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 12 | import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 13 | 14 | import {IwstETH} from "../../../integrations/lido/IwstETH.sol"; 15 | 16 | contract WstETHV1Mock is IwstETH, ERC20, Ownable { 17 | using SafeERC20 for IERC20; 18 | 19 | address public immutable stETH; 20 | uint256 immutable decimalsMul; 21 | uint256 public override stEthPerToken; 22 | 23 | constructor(address _token) ERC20(string("Wrapped stETH"), string("wstETH")) { 24 | stETH = _token; 25 | decimalsMul = 10 ** ERC20.decimals(); 26 | stEthPerToken = decimalsMul; 27 | } 28 | 29 | function setStEthPerToken(uint256 value) external { 30 | stEthPerToken = value; 31 | } 32 | 33 | function tokensPerStEth() external view returns (uint256) { 34 | return getWstETHByStETH(WAD); 35 | } 36 | 37 | function wrap(uint256 _stETHAmount) external returns (uint256 wstETHAmount) { 38 | IERC20(stETH).safeTransferFrom(msg.sender, address(this), _stETHAmount); 39 | wstETHAmount = getWstETHByStETH(_stETHAmount); 40 | _mint(msg.sender, wstETHAmount); 41 | } 42 | 43 | function unwrap(uint256 _wstETHAmount) external returns (uint256 stETHAmount) { 44 | stETHAmount = getStETHByWstETH(_wstETHAmount); 45 | _burn(msg.sender, _wstETHAmount); 46 | IERC20(stETH).safeTransfer(msg.sender, stETHAmount); 47 | } 48 | 49 | function getStETHByWstETH(uint256 _wstETHAmount) public view returns (uint256) { 50 | return (_wstETHAmount * stEthPerToken) / decimalsMul; 51 | } 52 | 53 | function getWstETHByStETH(uint256 _stETHAmount) public view returns (uint256) { 54 | return (_stETHAmount * decimalsMul) / stEthPerToken; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/test/mocks/integrations/YearnV2Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; 7 | 8 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 10 | import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; 11 | 12 | import {IYVault} from "../../../integrations/yearn/IYVault.sol"; 13 | 14 | contract YearnV2Mock is IYVault, ERC20, Ownable { 15 | using SafeERC20 for IERC20; 16 | 17 | address public override token; 18 | uint256 public override pricePerShare; 19 | 20 | uint256 immutable decimalsMul; 21 | 22 | constructor(address _token) 23 | ERC20( 24 | string(abi.encodePacked("yearn ", ERC20(_token).name())), 25 | string(abi.encodePacked("yv", ERC20(_token).symbol())) 26 | ) 27 | { 28 | token = _token; 29 | decimalsMul = 10 ** ERC20.decimals(); 30 | pricePerShare = decimalsMul; 31 | } 32 | 33 | function deposit() public override returns (uint256) { 34 | return deposit(IERC20(token).balanceOf(msg.sender)); 35 | } 36 | 37 | function deposit(uint256 _amount) public override returns (uint256) { 38 | return deposit(_amount, msg.sender); 39 | } 40 | 41 | function deposit(uint256 _amount, address recipient) public override returns (uint256 shares) { 42 | IERC20(token).safeTransferFrom(msg.sender, address(this), _amount); 43 | shares = (_amount * decimalsMul) / pricePerShare; 44 | _mint(recipient, shares); 45 | } 46 | 47 | function withdraw() external override returns (uint256) { 48 | return withdraw(balanceOf(msg.sender)); 49 | } 50 | 51 | function withdraw(uint256 maxShares) public override returns (uint256) { 52 | return withdraw(maxShares, msg.sender); 53 | } 54 | 55 | function withdraw(uint256 maxShares, address recipient) public override returns (uint256) { 56 | return withdraw(maxShares, recipient, 1); 57 | } 58 | 59 | function withdraw( 60 | uint256 maxShares, 61 | address, // recipient, 62 | uint256 maxLoss 63 | ) public override returns (uint256 amount) { 64 | _burn(msg.sender, maxShares); 65 | amount = (maxShares * pricePerShare) / decimalsMul; 66 | 67 | // pretend that loss is 1 basis point 68 | require(maxLoss <= 1, "Loss too big"); 69 | 70 | IERC20(token).safeTransfer(msg.sender, amount); 71 | } 72 | 73 | function setPricePerShare(uint256 newPrice) public { 74 | pricePerShare = newPrice; 75 | } 76 | 77 | function name() public view override(IYVault, ERC20) returns (string memory) { 78 | return ERC20.name(); 79 | } 80 | 81 | function symbol() public view override(IYVault, ERC20) returns (string memory) { 82 | return ERC20.symbol(); 83 | } 84 | 85 | function decimals() public view override(IYVault, ERC20) returns (uint8) { 86 | return ERC20.decimals(); 87 | } 88 | 89 | function mintShares(address to, uint256 amount) public { 90 | _mint(to, amount); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /contracts/test/mocks/token/WETHMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.10; 3 | 4 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 5 | 6 | contract WETHMock is IERC20 { 7 | string public name = "Wrapped Ether"; 8 | string public symbol = "WETH"; 9 | uint8 public decimals = 18; 10 | 11 | // event Approval(address indexed src, address indexed guy, uint256 wad); 12 | // event Transfer(address indexed src, address indexed dst, uint256 wad); 13 | event Deposit(address indexed dst, uint256 wad); 14 | event Withdrawal(address indexed src, uint256 wad); 15 | 16 | mapping(address => uint256) public balanceOf; 17 | mapping(address => mapping(address => uint256)) public allowance; 18 | 19 | function mint(address to, uint256 amount) external { 20 | balanceOf[to] += amount; 21 | } 22 | 23 | receive() external payable { 24 | deposit(); // T:[WM-1] 25 | } 26 | 27 | function deposit() public payable { 28 | balanceOf[msg.sender] += msg.value; // T:[WM-1] 29 | emit Deposit(msg.sender, msg.value); // T:[WM-1] 30 | } 31 | 32 | function withdraw(uint256 wad) public { 33 | require(balanceOf[msg.sender] >= wad); // T:[WM-2] 34 | balanceOf[msg.sender] -= wad; // T:[WM-2] 35 | payable(msg.sender).transfer(wad); // T:[WM-3] 36 | emit Withdrawal(msg.sender, wad); // T:[WM-4] 37 | } 38 | 39 | function totalSupply() public view returns (uint256) { 40 | return address(this).balance; // T:[WM-1, 2] 41 | } 42 | 43 | function approve(address guy, uint256 wad) public returns (bool) { 44 | allowance[msg.sender][guy] = wad; // T:[WM-3] 45 | emit Approval(msg.sender, guy, wad); // T:[WM-3] 46 | return true; 47 | } 48 | 49 | function transfer(address dst, uint256 wad) public returns (bool) { 50 | return transferFrom(msg.sender, dst, wad); // T:[WM-4,5,6] 51 | } 52 | 53 | function transferFrom(address src, address dst, uint256 wad) public returns (bool) { 54 | require(balanceOf[src] >= wad); // T:[WM-4] 55 | 56 | if (src != msg.sender && allowance[src][msg.sender] != type(uint256).max) { 57 | require(allowance[src][msg.sender] >= wad); // T:[WM-4] 58 | allowance[src][msg.sender] -= wad; // T:[WM-7] 59 | } 60 | 61 | balanceOf[src] -= wad; // T:[WM-5] 62 | balanceOf[dst] += wad; // T:[WM-5] 63 | 64 | emit Transfer(src, dst, wad); // T:[WM-6] 65 | 66 | return true; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /contracts/test/mocks/token/cERC20Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; 7 | import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 8 | import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | 10 | contract cERC20Mock is ERC20, Ownable { 11 | uint8 private immutable _decimals; 12 | address public immutable underlying; 13 | 14 | constructor(string memory name_, string memory symbol_, uint8 decimals_, address underlying_) 15 | ERC20(name_, symbol_) 16 | { 17 | _decimals = decimals_; 18 | underlying = underlying_; 19 | } 20 | 21 | function decimals() public view override returns (uint8) { 22 | return _decimals; 23 | } 24 | 25 | function mint(address to, uint256 amount) external { 26 | IERC20(underlying).transferFrom(msg.sender, address(this), amount); 27 | _mint(to, amount); 28 | } 29 | 30 | function redeem(address to, uint256 amount) external { 31 | _burn(msg.sender, amount); 32 | IERC20(underlying).transfer(to, amount); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/test/suites/LiveEnvHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {LiveEnvTestSuite} from "./LiveEnvTestSuite.sol"; 7 | import {CheatCodes, HEVM_ADDRESS} from "@gearbox-protocol/core-v2/contracts/test/lib/cheatCodes.sol"; 8 | import {Tokens} from "../config/Tokens.sol"; 9 | 10 | import {SupportedContracts, Contracts} from "../config/SupportedContracts.sol"; 11 | import {IUniswapV2Router02} from "../../integrations/uniswap/IUniswapV2Router02.sol"; 12 | import {MultiCall} from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditFacade.sol"; 13 | import {TokenType} from "../../integrations/TokenType.sol"; 14 | import {TokensTestSuite} from "../suites/TokensTestSuite.sol"; 15 | 16 | contract LiveEnvHelper { 17 | CheatCodes evm = CheatCodes(HEVM_ADDRESS); 18 | LiveEnvTestSuite lts; 19 | 20 | address public MAINNET_CONFIGURATOR; 21 | 22 | TokensTestSuite public tokenTestSuite; 23 | SupportedContracts public supportedContracts; 24 | 25 | modifier liveOnly() { 26 | if (block.chainid == 1337) { 27 | _; 28 | } 29 | } 30 | 31 | function _setUp() public virtual liveOnly { 32 | lts = new LiveEnvTestSuite(); 33 | MAINNET_CONFIGURATOR = lts.ROOT_ADDRESS(); 34 | tokenTestSuite = lts.tokenTestSuite(); 35 | supportedContracts = lts.supportedContracts(); 36 | } 37 | 38 | function getUniV2() internal view returns (IUniswapV2Router02) { 39 | return IUniswapV2Router02(supportedContracts.addressOf(Contracts.UNISWAP_V2_ROUTER)); 40 | } 41 | 42 | function swapEthToTokens(address onBehalfOf, Tokens t, uint256 amount) internal { 43 | evm.startPrank(onBehalfOf); 44 | 45 | getUniV2().swapExactETHForTokens{value: amount}( 46 | 0, arrayOf(tokenTestSuite.addressOf(Tokens.WETH), tokenTestSuite.addressOf(t)), onBehalfOf, block.timestamp 47 | ); 48 | 49 | evm.stopPrank(); 50 | } 51 | 52 | // [TODO]: add new lib for arrayOf 53 | function arrayOf(address addr0, address addr1) internal pure returns (address[] memory result) { 54 | result = new address[](2); 55 | result[0] = addr0; 56 | result[1] = addr1; 57 | } 58 | 59 | function multicallBuilder() internal pure returns (MultiCall[] memory calls) {} 60 | 61 | function multicallBuilder(MultiCall memory call1) internal pure returns (MultiCall[] memory calls) { 62 | calls = new MultiCall[](1); 63 | calls[0] = call1; 64 | } 65 | 66 | function multicallBuilder(MultiCall memory call1, MultiCall memory call2) 67 | internal 68 | pure 69 | returns (MultiCall[] memory calls) 70 | { 71 | calls = new MultiCall[](2); 72 | calls[0] = call1; 73 | calls[1] = call2; 74 | } 75 | 76 | function multicallBuilder(MultiCall memory call1, MultiCall memory call2, MultiCall memory call3) 77 | internal 78 | pure 79 | returns (MultiCall[] memory calls) 80 | { 81 | calls = new MultiCall[](3); 82 | calls[0] = call1; 83 | calls[1] = call2; 84 | calls[2] = call3; 85 | } 86 | 87 | function getTokensOfType(TokenType tokenType) internal view returns (Tokens[] memory tokens) { 88 | uint256 tokenCount = tokenTestSuite.tokenCount(); 89 | 90 | uint256[] memory temp = new uint256[](tokenCount); 91 | uint256 found; 92 | 93 | for (uint256 i = 0; i < tokenCount; ++i) { 94 | if (tokenTestSuite.tokenTypes(Tokens(i)) == tokenType) { 95 | temp[found] = i; 96 | ++found; 97 | } 98 | } 99 | 100 | tokens = new Tokens[](found); 101 | 102 | for (uint256 i = 0; i < found; ++i) { 103 | tokens[i] = Tokens(temp[i]); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /contracts/test/suites/WstETHPoolSetup.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | // Gearbox Protocol. Generalized leverage for DeFi protocols 3 | // (c) Gearbox Holdings, 2022 4 | pragma solidity ^0.8.10; 5 | 6 | import {ITokenTestSuite} from "@gearbox-protocol/core-v2/contracts/test/interfaces/ITokenTestSuite.sol"; 7 | 8 | import {IAddressProvider} from "@gearbox-protocol/core-v2/contracts/interfaces/IAddressProvider.sol"; 9 | import {PoolService} from "@gearbox-protocol/core-v2/contracts/pool/PoolService.sol"; 10 | 11 | import {ContractsRegister} from "@gearbox-protocol/core-v2/contracts/core/ContractsRegister.sol"; 12 | import {LinearInterestRateModel} from "@gearbox-protocol/core-v2/contracts/pool/LinearInterestRateModel.sol"; 13 | 14 | import {IwstETH} from "../../integrations/lido/IwstETH.sol"; 15 | import "../lib/constants.sol"; 16 | 17 | uint256 constant U_OPTIMAL = 80_00; 18 | uint256 constant U_RESERVE = 90_00; 19 | uint256 constant R_BASE = 2_00; 20 | uint256 constant R_SLOPE_1 = 5_00; 21 | uint256 constant R_SLOPE_2 = 40_00; 22 | uint256 constant R_SLOPE_3 = 75_00; 23 | 24 | uint256 constant EXPECTED_LIQUIDITY_LIMIT = 10_000 * WAD; 25 | uint256 constant WITHDRAW_FEE = 1_00; 26 | 27 | /// @title WstETHPoolSetup 28 | /// @notice Setup and add wstETH pool to the system 29 | contract WstETHPoolSetup { 30 | CheatCodes evm = CheatCodes(HEVM_ADDRESS); 31 | 32 | constructor(address addressProvider, address wstETH, ITokenTestSuite tokensTestSuite, address root) { 33 | LinearInterestRateModel linearModel = new LinearInterestRateModel( 34 | U_OPTIMAL, 35 | U_RESERVE, 36 | R_BASE, 37 | R_SLOPE_1, 38 | R_SLOPE_2, 39 | R_SLOPE_3, 40 | false 41 | ); 42 | 43 | PoolService pool = new PoolService( 44 | addressProvider, 45 | wstETH, 46 | address(linearModel), 47 | EXPECTED_LIQUIDITY_LIMIT 48 | ); 49 | 50 | ContractsRegister cr = ContractsRegister(IAddressProvider(addressProvider).getContractsRegister()); 51 | 52 | evm.prank(root); 53 | pool.setWithdrawFee(WITHDRAW_FEE); 54 | 55 | evm.prank(root); 56 | cr.addPool(address(pool)); 57 | 58 | uint256 poolLiquidityAmount = EXPECTED_LIQUIDITY_LIMIT / 3; 59 | 60 | uint256 wrappedAmount = IwstETH(wstETH).getStETHByWstETH(poolLiquidityAmount); 61 | 62 | address stETH = IwstETH(wstETH).stETH(); 63 | 64 | tokensTestSuite.mint(stETH, address(this), wrappedAmount); 65 | 66 | tokensTestSuite.approve(stETH, address(this), wstETH); 67 | 68 | uint256 updatedPoolLiquidityAmount = IwstETH(wstETH).wrap(wrappedAmount); 69 | IwstETH(wstETH).approve(address(pool), type(uint256).max); 70 | 71 | pool.addLiquidity(updatedPoolLiquidityAmount, address(this), 0); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /core/creditFilter.ts: -------------------------------------------------------------------------------- 1 | import { SupportedToken } from "@gearbox-protocol/sdk"; 2 | 3 | export interface AllowedToken { 4 | address: string; 5 | liquidationThreshold: number; 6 | } 7 | 8 | export interface CollateralTokenSymbol { 9 | symbol: SupportedToken; 10 | liquidationThreshold: number; 11 | } 12 | -------------------------------------------------------------------------------- /core/pool.ts: -------------------------------------------------------------------------------- 1 | import { NormalToken, SupportedContract } from "@gearbox-protocol/sdk"; 2 | import { BigNumberish } from "ethers"; 3 | 4 | import { CollateralTokenSymbol } from "./creditFilter"; 5 | 6 | export interface CreditConfigLive { 7 | minAmount: BigNumberish; 8 | maxAmount: BigNumberish; 9 | collateralTokens: Array; 10 | adapters: Array; 11 | } 12 | 13 | export interface CMConfig extends CreditConfigLive { 14 | symbol: NormalToken; 15 | } 16 | -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | libs = ['lib'] 3 | out = 'forge-out' 4 | remappings = [ 5 | 'ds-test/=lib/ds-test/src/', 6 | 'hardhat/=node_modules/hardhat/', 7 | 'forge-std/=node_modules/forge-std/', 8 | '@ensdomains/=node_modules/@ensdomains/', 9 | '@openzeppelin/=node_modules/@openzeppelin/', 10 | '@chainlink/=node_modules/@chainlink/', 11 | '@gearbox-protocol=node_modules/@gearbox-protocol/' 12 | ] 13 | solc_version = '0.8.17' 14 | src = 'contracts' 15 | optimizer_runs = 1000000 16 | 17 | # See more config options https://github.com/gakonst/foundry/tree/master/config 18 | block_number = 120000 19 | block_timestamp = 1640000000 20 | gas_limit = 9223372036854775807 # the gas limit in tests 21 | block_base_fee_per_gas = 100 22 | fs_permissions = [{ access = "read-write", path = "./"}] 23 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import "@nomiclabs/hardhat-waffle"; 2 | import "@nomiclabs/hardhat-etherscan"; 3 | import "@nomiclabs/hardhat-ethers"; 4 | import "@typechain/hardhat"; 5 | import "hardhat-gas-reporter"; 6 | import "hardhat-abi-exporter"; 7 | import "hardhat-contract-sizer"; 8 | import "solidity-coverage"; 9 | 10 | import { LOCAL_NETWORK, MAINNET_NETWORK } from "@gearbox-protocol/sdk"; 11 | import { config as dotEnvConfig } from "dotenv"; 12 | import { HardhatUserConfig } from "hardhat/types"; 13 | 14 | // gets data from .env file 15 | dotEnvConfig(); 16 | 17 | const GOERLI_PRIVATE_KEY = 18 | process.env.GOERLI_PRIVATE_KEY! || 19 | "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3"; // well known private key 20 | 21 | const GOERLI_PRIVATE_KEY2 = 22 | process.env.KOVAN2_PRIVATE_KEY! || 23 | "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3"; // well known private key 24 | 25 | const BOXCODE_PRIVATE_KEY = 26 | process.env.BOXCODE_PRIVATE_KEY! || 27 | "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3"; // well known private key 28 | 29 | const BVI_PRIVATE_KEY = 30 | process.env.BVI_PRIVATE_KEY! || 31 | "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3"; // well known private key 32 | 33 | const config: HardhatUserConfig = { 34 | defaultNetwork: "hardhat", 35 | solidity: { 36 | compilers: [ 37 | { 38 | version: "0.8.17", 39 | 40 | settings: { 41 | optimizer: { 42 | enabled: true, 43 | runs: 1000000, 44 | }, 45 | }, 46 | }, 47 | ], 48 | }, 49 | networks: { 50 | hardhat: { 51 | chainId: LOCAL_NETWORK, 52 | initialBaseFeePerGas: 0, 53 | allowUnlimitedContractSize: true, 54 | }, 55 | localhost: { 56 | timeout: 0, 57 | }, 58 | mainnet: { 59 | url: process.env.ETH_MAINNET_PROVIDER || "", 60 | accounts: [BOXCODE_PRIVATE_KEY, BVI_PRIVATE_KEY], 61 | chainId: MAINNET_NETWORK, 62 | timeout: 0, 63 | gasMultiplier: 1.15, 64 | minGasPrice: 1e9, 65 | allowUnlimitedContractSize: false, 66 | }, 67 | 68 | goerli: { 69 | url: process.env.ETH_GOERLI_PROVIDER || "", 70 | accounts: [GOERLI_PRIVATE_KEY, GOERLI_PRIVATE_KEY2], 71 | gasMultiplier: 1.8, 72 | minGasPrice: 1e9, 73 | timeout: 0, 74 | allowUnlimitedContractSize: false, 75 | }, 76 | }, 77 | gasReporter: { 78 | enabled: false, 79 | currency: "USD", 80 | gasPrice: 21, 81 | }, 82 | typechain: { 83 | outDir: "types", 84 | target: "ethers-v5", 85 | }, 86 | abiExporter: { 87 | path: "./abi", 88 | clear: true, 89 | flat: true, 90 | spacing: 2, 91 | }, 92 | contractSizer: { 93 | alphaSort: false, 94 | disambiguatePaths: false, 95 | runOnCompile: true, 96 | except: ["Test", "Mock"], 97 | }, 98 | }; 99 | 100 | if (process.env.ETHERSCAN_API_KEY) { 101 | config.etherscan = { 102 | // Your API key for Etherscan 103 | // Obtain one at https://etherscan.io/ 104 | apiKey: process.env.ETHERSCAN_API_KEY, 105 | }; 106 | } 107 | 108 | export default config; 109 | -------------------------------------------------------------------------------- /header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gearbox-protocol/integrations-v2/faa9cfd4921c62165782dcdc196ff5a0c0e6075d/header.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gearbox-protocol/integrations-v2", 3 | "description": "Core smart contracts of Gearbox V1", 4 | "version": "1.0.0", 5 | "homepage": "https://gearbox.fi", 6 | "keywords": [ 7 | "gearbox" 8 | ], 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/Gearbox-protocol/integrations-v2" 12 | }, 13 | "files": [ 14 | "contracts" 15 | ], 16 | "license": "BUSL-1.1", 17 | "scripts": { 18 | "build": "yarn clean && yarn compile", 19 | "charge": "npx hardhat run scripts/charge.ts --network localhost", 20 | "clean": "npx hardhat clean", 21 | "fork": "scripts/fork.sh", 22 | "fork-goerli": "scripts/fork-goerli.sh", 23 | "abigen": "scripts/abigen.sh", 24 | "compile": "npx hardhat compile", 25 | "test": "npx hardhat test", 26 | "update_abi": "scripts/abiCopy.sh", 27 | "coverage": "yarn build && npx hardhat coverage --temp artifacts", 28 | "verify": "npx hardhat run node_modules/@gearbox-protocol/devops/lib/verifier/verify.js", 29 | "deploy-fork": "npx hardhat run deploy/cmV2deploy.ts --network localhost", 30 | "prepare": "husky install", 31 | "prettier": "forge fmt", 32 | "prettier:ci": "forge fmt", 33 | "lint": "eslint \"**/*.ts\" --fix", 34 | "lint:ci": "eslint \"**/*.ts\"", 35 | "typecheck:ci": "tsc --noEmit", 36 | "bindings": "yarn ts-node ./bindings/generate.ts" 37 | }, 38 | "dependencies": { 39 | "@gearbox-protocol/core-v2": "^1.8.0-next.44", 40 | "@gearbox-protocol/sdk": "^1.20.7", 41 | "axios": "^1.1.3" 42 | }, 43 | "devDependencies": { 44 | "@chainlink/contracts": "^0.4.0", 45 | "@commitlint/cli": "^17.1.2", 46 | "@commitlint/config-conventional": "^17.1.0", 47 | "@gearbox-protocol/eslint-config": "^1.6.1", 48 | "@gearbox-protocol/prettier-config": "^1.5.0", 49 | "@nomiclabs/hardhat-ethers": "^2.1.1", 50 | "@nomiclabs/hardhat-etherscan": "^3.1.0", 51 | "@nomiclabs/hardhat-waffle": "^2.0.3", 52 | "@openzeppelin/contracts": "^4.4.2", 53 | "@typechain/ethers-v5": "^10.1.0", 54 | "@typechain/hardhat": "^6.1.3", 55 | "dotenv": "^16.0.3", 56 | "eslint": "^8.25.0", 57 | "ethers": "5.4.4", 58 | "forge-std": "^1.1.2", 59 | "hardhat": "^2.11.2", 60 | "hardhat-abi-exporter": "^2.10.0", 61 | "hardhat-contract-sizer": "^2.6.1", 62 | "hardhat-gas-reporter": "^1.0.9", 63 | "husky": "^8.0.1", 64 | "lint-staged": "^13.0.3", 65 | "prettier": "^2.7.1", 66 | "prettier-plugin-solidity": "^1.0.0-beta.24", 67 | "solidity-coverage": "^0.7.16", 68 | "ts-node": "^10.9.1", 69 | "typechain": "^8.1.0", 70 | "typescript": "^4.8.2" 71 | }, 72 | "prettier": "@gearbox-protocol/prettier-config", 73 | "lint-staged": { 74 | "*.ts": [ 75 | "eslint --fix", 76 | "prettier --write" 77 | ], 78 | "*.sol": "forge fmt", 79 | "*.{json,md}": "prettier --write" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /scripts/abigen.sh: -------------------------------------------------------------------------------- 1 | for f in ./abi/*.json; do 2 | echo "Processing $f file.."; 3 | GO_NAME=${f/json/go} 4 | DIR=./abi/ 5 | GO_PKG=${GO_NAME/$DIR/""} 6 | GO_PKG=${GO_PKG/.go/""} 7 | GO_PKG_FL="$(tr [A-Z] [a-z] <<< "${GO_PKG:0:1}")" 8 | GO_PKG=${GO_PKG_FL}${GO_PKG:1} 9 | OUT_DIR=../gearscan/artifacts/${GO_PKG} 10 | 11 | # Create dir if not exists 12 | [ ! -d $OUT_DIR ] && mkdir $OUT_DIR 13 | 14 | # Export file 15 | OUT_FILE=${OUT_DIR}/abi.go 16 | rm -rf ./gearscan/artifacts/* 17 | abigen --abi $f --pkg $GO_PKG --out $OUT_FILE 18 | done 19 | -------------------------------------------------------------------------------- /scripts/fork-goerli.sh: -------------------------------------------------------------------------------- 1 | set -o allexport; source ./.env; set +o allexport; 2 | export $(grep -v '^#' .env | xargs -d '\n') 3 | 4 | if [[ -z "${ETH_GOERLI_BLOCK}" ]]; then 5 | anvil -f $ETH_GOERLI_PROVIDER --chain-id 1337 6 | else 7 | anvil -f $ETH_GOERLI_PROVIDER --fork-block-number $ETH_GOERLI_BLOCK --chain-id 1337 8 | fi 9 | 10 | -------------------------------------------------------------------------------- /scripts/fork.sh: -------------------------------------------------------------------------------- 1 | set -o allexport; source ./.env; set +o allexport; 2 | export $(grep -v '^#' .env | xargs -d '\n') 3 | 4 | if [[ -z "${ETH_MAINNET_BLOCK}" ]]; then 5 | anvil -f $ETH_MAINNET_PROVIDER --chain-id 1337 6 | else 7 | anvil -f $ETH_MAINNET_PROVIDER --fork-block-number $ETH_MAINNET_BLOCK --chain-id 1337 8 | fi 9 | 10 | -------------------------------------------------------------------------------- /scripts/trimport.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This script tries to remove imports one by one while making sure that the 3 | # project can still be compiled, so that the minimum number of imports is used. 4 | # This approach is really inefficient, but good enough given that it can just 5 | # be run once in a while to unclutter imports. 6 | set -e 7 | set -u 8 | 9 | compile(){ 10 | echo Compiling... 11 | forge clean 12 | forge b >/dev/null 2>&1 13 | } 14 | 15 | echo "This script will run on the following files:" 16 | find 'contracts' -iname '*.sol' 17 | echo "Continue? [y/N]" 18 | 19 | read -r answer 20 | if [ "$answer" != "y" ]; then 21 | exit 2 22 | fi 23 | 24 | 25 | echo "Compiling once with original files as a sanity check" 26 | compile || exit 3 27 | 28 | tmp="$(mktemp)" 29 | 30 | find 'contracts' -type f -iname '*.sol' |\ 31 | while read -r f ; do 32 | grep -n '^ *import' "$f" | cut -d':' -f1 |\ 33 | while read -r line; do 34 | cp "$f" "$tmp" 35 | if [[ "$OSTYPE" == "darwin"* ]]; then 36 | gsed -i "$line"'s/.*//' "$f" || (echo "Install gnu-sed for macOS: brew install gnu-sed" && exit 4) 37 | else 38 | sed -i "$line"'s/.*//' "$f" 39 | fi 40 | compile || cp "$tmp" "$f" 41 | done 42 | done 43 | 44 | exit 0 --------------------------------------------------------------------------------