diff --git a/common/configuration.ts b/common/configuration.ts index 609bbe3a6..6794a846f 100644 --- a/common/configuration.ts +++ b/common/configuration.ts @@ -124,6 +124,9 @@ export interface ITokens { MOG?: string USDz?: string + cbBTC?: string + WELL?: string + DEGEN?: string // Sky USDS?: string @@ -159,6 +162,9 @@ export interface IPools { aeroWETHAERO?: string aeroMOGWETH?: string aeroUSDzUSDC?: string + aeroWETHcbBTC?: string + aeroWETHWELL?: string + aeroWETHDEGEN?: string } interface INetworkConfig { @@ -541,6 +547,9 @@ export const networkConfig: { [key: string]: INetworkConfig } = { USDz: '0x04D5ddf5f3a8939889F11E97f8c4BB48317F1938', meUSD: '0xbb819D845b573B5D7C538F5b85057160cfb5f313', AERO: '0x940181a94A35A4569E4529A3CDfB74e38FD98631', + cbBTC: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', + WELL: '0xA88594D404727625A9437C3f886C7643872296AE', + DEGEN: '0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed', }, chainlinkFeeds: { DAI: '0x591e79239a7d679378ec8c847e5038150364c78f', // 0.3%, 24hr @@ -561,6 +570,9 @@ export const networkConfig: { [key: string]: INetworkConfig } = { USDz: '0xe25969e2Fa633a0C027fAB8F30Fc9C6A90D60B48', // 0.5%, 24h AERO: '0x4EC5970fC728C5f65ba413992CD5fF6FD70fcfF0', // 0.5%, 24h MOG: '0x4aeb6D15769EaD32D0c5Be2940F40c7CFf53801d', // 0.5%, 24h + cbBTC: '0x07DA0E54543a844a80ABE69c8A12F22B3aA59f9D', // 0.3%, 20 min + WELL: '0xc15d9944dAefE2dB03e53bef8DDA25a56832C5fe', // 0.5%, 24h + DEGEN: '0xE62BcE5D7CB9d16AB8b4D622538bc0A50A5799c2', // 0.5%, 24h }, GNOSIS_EASY_AUCTION: '0xb1875Feaeea32Bbb02DE83D81772e07E37A40f02', // mock COMET_REWARDS: '0x123964802e6ABabBE1Bc9547D72Ef1B69B00A6b1', diff --git a/contracts/plugins/assets/aerodrome/AerodromePoolTokens.sol b/contracts/plugins/assets/aerodrome/AerodromePoolTokens.sol index 2ec03470a..fa62c625e 100644 --- a/contracts/plugins/assets/aerodrome/AerodromePoolTokens.sol +++ b/contracts/plugins/assets/aerodrome/AerodromePoolTokens.sol @@ -8,7 +8,7 @@ import "contracts/plugins/assets/OracleLib.sol"; import "contracts/libraries/Fixed.sol"; import "./vendor/IAeroPool.sol"; -/// Supports Aerodrome stable pools (2 tokens) +/// Supports Aerodrome stable and volatile pools (2 tokens) contract AerodromePoolTokens { using OracleLib for AggregatorV3Interface; using FixLib for uint192; @@ -20,7 +20,7 @@ contract AerodromePoolTokens { enum AeroPoolType { Stable, - Volatile // not supported in this version + Volatile } // === State (Immutable) === diff --git a/contracts/plugins/assets/aerodrome/AerodromeStableCollateral.sol b/contracts/plugins/assets/aerodrome/AerodromeStableCollateral.sol index 2410006c0..5c7965702 100644 --- a/contracts/plugins/assets/aerodrome/AerodromeStableCollateral.sol +++ b/contracts/plugins/assets/aerodrome/AerodromeStableCollateral.sol @@ -19,7 +19,7 @@ contract AerodromeStableCollateral is AerodromeVolatileCollateral { using FixLib for uint192; /// @dev config Unused members: chainlinkFeed, oracleError, oracleTimeout - /// @dev No revenue hiding (refPerTok() == FIX_ONE) + /// @dev No revenue hiding (refPerTok() is constant) /// @dev config.erc20 should be an AerodromeStakingWrapper constructor(CollateralConfig memory config, APTConfiguration memory aptConfig) AerodromeVolatileCollateral(config, aptConfig) @@ -73,15 +73,11 @@ contract AerodromeStableCollateral is AerodromeVolatileCollateral { sqrt256(1e18 * ratioHigh) * sqrt256(1e36 + ratioHigh * ratioHigh) ); - high = _safeWrap( - (((1e18 * sqrtReserve) / sqrtPriceHigh) * p0_high * 2) / totalSupply - ); + high = _safeWrap((((1e18 * sqrtReserve) / sqrtPriceHigh) * p0_high * 2) / totalSupply); } assert(low <= high); // not obviously true just by inspection - // {target/ref} = {UoA/ref} = {UoA/tok} / ({ref/tok} - // {target/ref} and {UoA/ref} are the same since target == UoA - pegPrice = ((low + high) / 2).div(refPerTok()); + pegPrice = 0; } // === Internal === diff --git a/contracts/plugins/assets/aerodrome/AerodromeVolatileCollateral.sol b/contracts/plugins/assets/aerodrome/AerodromeVolatileCollateral.sol index 9b1b8a075..8b8e8bd9f 100644 --- a/contracts/plugins/assets/aerodrome/AerodromeVolatileCollateral.sol +++ b/contracts/plugins/assets/aerodrome/AerodromeVolatileCollateral.sol @@ -31,7 +31,7 @@ contract AerodromeVolatileCollateral is FiatCollateral, AerodromePoolTokens { using FixLib for uint192; /// @dev config Unused members: chainlinkFeed, oracleError, oracleTimout - /// @dev No revenue hiding (refPerTok() == FIX_ONE) + /// @dev No revenue hiding (refPerTok() is constant) /// @dev config.erc20 should be an AerodromeStakingWrapper constructor(CollateralConfig memory config, APTConfiguration memory aptConfig) FiatCollateral(config) diff --git a/contracts/plugins/assets/aerodrome/README.md b/contracts/plugins/assets/aerodrome/README.md index 82cf963aa..0eea2e013 100644 --- a/contracts/plugins/assets/aerodrome/README.md +++ b/contracts/plugins/assets/aerodrome/README.md @@ -1,12 +1,12 @@ -# Aerodrome Stable Collateral Plugin +# Aerodrome Collateral Plugins -[Aerodrome Finance](https://aerodrome.finance) is an AMM designed to serve as Base's central liquidity hub. This plugin enables the use of any Aerodrome Stable LP token as collateral within the Reserve Protocol. +[Aerodrome Finance](https://aerodrome.finance) is an AMM designed to serve as Base's central liquidity hub. This plugin enables the use of any Aerodrome Stable and Volatile LP token as collateral within the Reserve Protocol. Aerodrome Finance offers two different liquidity pool types based on token pair needs, `Stable Pools` and `Volatile Pools`. -Only `Stable Pools` are currently supported. These pools are designed for tokens which have little to no volatility, and use the current formula for pricing tokens: +`Stable Pools` are designed for tokens which have little to no volatility, and use the current formula for pricing tokens: `x³y + y³x ≥ k` -`x³y + y³x ≥ k` +`Volatile Pools` are designed for tokens with high price volatility, and use a generic AMM formula: `x × y ≥ k` ## Usage @@ -36,10 +36,11 @@ Internally, all `tokensPriceFeeds` are stored as multiple separate immutable var ### refPerTok -Aerodrome Stable Pools do not appreciate in value over time, so `refPerTok()` will be constant for these plugins and will not change. This also means there are no hard default checks in place. +Aerodrome Pools do not appreciate in value over time, so `refPerTok()` will be constant for these plugins and will not change. This also means there are no hard default checks in place. ## Implementation -| `tok` | `ref` | `target` | `UoA` | -| :------------------: | :---------------: | :------: | :---: | -| Aero Staking Wrapper | LP token /w shift | USD | USD | +| `tok` | `ref` | `target` | `UoA` | +| :------------------: | :---------------: | :--------------: | :---: | +| Aero Staking Wrapper | LP token /w shift | USD (Stable) | USD | +| Aero Staking Wrapper | LP token /w shift | cpAMM (Volatile) | USD | diff --git a/scripts/addresses/8453-tmp-assets-collateral.json b/scripts/addresses/8453-tmp-assets-collateral.json index 7951c5b66..33e58ecf6 100644 --- a/scripts/addresses/8453-tmp-assets-collateral.json +++ b/scripts/addresses/8453-tmp-assets-collateral.json @@ -14,10 +14,13 @@ "cUSDCv3": "0xf7a9D27c3B60c78c6F6e2c2d6ED6E8B94b352461", "wstETH": "0x8b4374005291B8FCD14C4E947604b2FB3C660A73", "aeroUSDCeUSD": "0x9216CD5cA133aBBd23cc6F873bB4a95A78032db0", - "aeroWETHAERO": "0x1bD9eAEB0eD1aB51dA1Ff8D437892488790bbde7", - "aeroMOGWETH": "0x6Ec09BD7d32F1023626AaEa1090e178d81C7701A", + "aeroWETHAERO": "0xaC23df4289e2FeaFb2851e63958C2AAF41DB4833", + "aeroMOGWETH": "0xfAa0cfc986041a3aF69207C6fCF35316D58fEA6a", "meUSD": "0x0f1e10871e6a2D3A5Aa696b85b39d61a22A9e8C3", - "aeroUSDzUSDC": "0x8AAdfbea33146e28170F99D031B7747EAa87DDD4" + "aeroUSDzUSDC": "0x8AAdfbea33146e28170F99D031B7747EAa87DDD4", + "aeroWETHcbBTC": "0x5ABe1A8b04A2428589bAeF9486d12688d482D061", + "aeroWETHWELL": "0x7df3541FFeDAA956aE6136E64253f3749b055Be6", + "aeroWETHDEGEN": "0xc8E72288f717Da55b7231365daE17AcD91b59705" }, "erc20s": { "COMP": "0x9e1028F5F1D5eDE59748FFceE5532509976840E0", @@ -31,10 +34,13 @@ "cUSDCv3": "0x53f1Df4E5591Ae35Bf738742981669c3767241FA", "wstETH": "0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452", "aeroUSDCeUSD": "0xDB5b8cead52f77De0f6B5255f73F348AAf2CBb8D", - "aeroWETHAERO": "0x3712DDCF9aE516dD01042948B76A76901a84CD36", - "aeroMOGWETH": "0xCcC18B21be01a37ebFa5C932eD09574752F88C15", + "aeroWETHAERO": "0x65f2c1b253a3E45670aDD259C9688Edf1A3b814d", + "aeroMOGWETH": "0xfaAC26b279338dF8cF56B11A572617f674A2F69C", "meUSD": "0xbb819D845b573B5D7C538F5b85057160cfb5f313", "AERO": "0x940181a94A35A4569E4529A3CDfB74e38FD98631", - "aeroUSDzUSDC": "0x246Df11B856E9fD6120494F168475e1b41321c61" + "aeroUSDzUSDC": "0x246Df11B856E9fD6120494F168475e1b41321c61", + "aeroWETHcbBTC": "0x4BD08a771CdAbA5333CAc6F20322eD7d72b6cBfA", + "aeroWETHWELL": "0x1F599F8657CAA38Ee825e4E2d64F695749E2a161", + "aeroWETHDEGEN": "0xA762F790a31654D9AeF7DE550A473A0F5621E4F1" } } \ No newline at end of file diff --git a/scripts/addresses/8453-tmp-deployments.json b/scripts/addresses/8453-tmp-deployments.json index 7d32446fa..b34350b2b 100644 --- a/scripts/addresses/8453-tmp-deployments.json +++ b/scripts/addresses/8453-tmp-deployments.json @@ -37,4 +37,4 @@ "stRSR": "0x4Cf200D7fA568611DD8B4BD85053ba9419982C7D" } } -} \ No newline at end of file +} diff --git a/scripts/addresses/base-4.0.0/8453-tmp-assets-collateral.json b/scripts/addresses/base-4.0.0/8453-tmp-assets-collateral.json index e6cd64e24..36f009606 100644 --- a/scripts/addresses/base-4.0.0/8453-tmp-assets-collateral.json +++ b/scripts/addresses/base-4.0.0/8453-tmp-assets-collateral.json @@ -6,15 +6,21 @@ "meUSD": "0x0f1e10871e6a2D3A5Aa696b85b39d61a22A9e8C3", "aeroUSDCeUSD": "0x9216CD5cA133aBBd23cc6F873bB4a95A78032db0", "aeroUSDzUSDC": "0x8AAdfbea33146e28170F99D031B7747EAa87DDD4", - "aeroWETHAERO": "0x1bD9eAEB0eD1aB51dA1Ff8D437892488790bbde7", - "aeroMOGWETH": "0x6Ec09BD7d32F1023626AaEa1090e178d81C7701A" + "aeroWETHAERO": "0xaC23df4289e2FeaFb2851e63958C2AAF41DB4833", + "aeroMOGWETH": "0xfAa0cfc986041a3aF69207C6fCF35316D58fEA6a", + "aeroWETHcbBTC": "0x5ABe1A8b04A2428589bAeF9486d12688d482D061", + "aeroWETHWELL": "0x7df3541FFeDAA956aE6136E64253f3749b055Be6", + "aeroWETHDEGEN": "0xc8E72288f717Da55b7231365daE17AcD91b59705" }, "erc20s": { "meUSD": "0xbb819D845b573B5D7C538F5b85057160cfb5f313", "aeroUSDCeUSD": "0xDB5b8cead52f77De0f6B5255f73F348AAf2CBb8D", "AERO": "0x940181a94A35A4569E4529A3CDfB74e38FD98631", "aeroUSDzUSDC": "0x246Df11B856E9fD6120494F168475e1b41321c61", - "aeroWETHAERO": "0x3712DDCF9aE516dD01042948B76A76901a84CD36", - "aeroMOGWETH": "0xCcC18B21be01a37ebFa5C932eD09574752F88C15" + "aeroWETHAERO": "0x65f2c1b253a3E45670aDD259C9688Edf1A3b814d", + "aeroMOGWETH": "0xfaAC26b279338dF8cF56B11A572617f674A2F69C", + "aeroWETHcbBTC": "0x4BD08a771CdAbA5333CAc6F20322eD7d72b6cBfA", + "aeroWETHWELL": "0x1F599F8657CAA38Ee825e4E2d64F695749E2a161", + "aeroWETHDEGEN": "0xA762F790a31654D9AeF7DE550A473A0F5621E4F1" } } diff --git a/scripts/deploy.ts b/scripts/deploy.ts index 7bb6cdb3a..1d1199fe4 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -115,6 +115,9 @@ async function main() { 'phase2-assets/collaterals/deploy_aerodrome_weth_aero.ts', 'phase2-assets/collaterals/deploy_aerodrome_mog_weth.ts', 'phase2-assets/collaterals/deploy_aerodrome_usdz_usdc.ts', + 'phase2-assets/collaterals/deploy_aerodrome_weth_cbbtc.ts', + 'phase2-assets/collaterals/deploy_aerodrome_weth_well.ts', + 'phase2-assets/collaterals/deploy_aerodrome_weth_degen.ts', 'phase2-assets/collaterals/deploy_morphoeUSD.ts' ) } else if (chainId == '42161' || chainId == '421614') { diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_mog_weth.ts b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_mog_weth.ts index d01ec10af..bafaccd84 100644 --- a/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_mog_weth.ts +++ b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_mog_weth.ts @@ -65,7 +65,7 @@ async function main() { // Only for Base if (baseL2Chains.includes(hre.network.name)) { - const AerodromeStableCollateralFactory = await hre.ethers.getContractFactory( + const AerodromeVolatileCollateralFactory = await hre.ethers.getContractFactory( 'AerodromeVolatileCollateral' ) const AerodromeGaugeWrapperFactory = await ethers.getContractFactory('AerodromeGaugeWrapper') @@ -87,14 +87,14 @@ async function main() { `Deployed wrapper for Aerodrome Volatile MOG-WETH pool on ${hre.network.name} (${chainId}): ${wMogWeth.address} ` ) - const oracleError = combinedError(MOG_ORACLE_ERROR, ETH_ORACLE_ERROR) // 0.5% & 0.5% + const oracleError = combinedError(MOG_ORACLE_ERROR, ETH_ORACLE_ERROR) // 0.5% & 0.15% - collateral = await AerodromeStableCollateralFactory.connect( + collateral = await AerodromeVolatileCollateralFactory.connect( deployer ).deploy( { erc20: wMogWeth.address, - targetName: ethers.utils.formatBytes32String('50%ETH50%MOG'), // lexicographical order for tokens + targetName: ethers.utils.formatBytes32String('MOG_ETH_AERODROME_cpAMM'), priceTimeout: PRICE_TIMEOUT, chainlinkFeed: ONE_ADDRESS, // unused but cannot be zero oracleError: oracleError.toString(), // unused but cannot be zero diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_aero.ts b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_aero.ts index 302011790..010446fc9 100644 --- a/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_aero.ts +++ b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_aero.ts @@ -65,7 +65,7 @@ async function main() { // Only for Base if (baseL2Chains.includes(hre.network.name)) { - const AerodromeStableCollateralFactory = await hre.ethers.getContractFactory( + const AerodromeVolatileCollateralFactory = await hre.ethers.getContractFactory( 'AerodromeVolatileCollateral' ) const AerodromeGaugeWrapperFactory = await ethers.getContractFactory('AerodromeGaugeWrapper') @@ -89,12 +89,12 @@ async function main() { const oracleError = combinedError(AERO_ORACLE_ERROR, ETH_ORACLE_ERROR) // 0.5% & 0.15% - collateral = await AerodromeStableCollateralFactory.connect( + collateral = await AerodromeVolatileCollateralFactory.connect( deployer ).deploy( { erc20: wWethAero.address, - targetName: ethers.utils.formatBytes32String('50%AERO50%ETH'), // lexicographical order for tokens + targetName: ethers.utils.formatBytes32String('ETH_AERO_AERODROME_cpAMM'), priceTimeout: PRICE_TIMEOUT, chainlinkFeed: ONE_ADDRESS, // unused but cannot be zero oracleError: oracleError.toString(), // unused but cannot be zero diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_cbbtc.ts b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_cbbtc.ts new file mode 100644 index 000000000..e55b10562 --- /dev/null +++ b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_cbbtc.ts @@ -0,0 +1,140 @@ +import fs from 'fs' +import hre, { ethers } from 'hardhat' +import { getChainId } from '../../../../common/blockchain-utils' +import { baseL2Chains, networkConfig } from '../../../../common/configuration' +import { expect } from 'chai' +import { CollateralStatus, ONE_ADDRESS } from '../../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, + getDeploymentFilename, + fileExists, +} from '../../common' +import { + AerodromeVolatileCollateral, + AerodromeGaugeWrapper, + IAeroPool, +} from '../../../../typechain' +import { combinedError } from '../../utils' +import { + AerodromePoolType, + MAX_TRADE_VOL, + PRICE_TIMEOUT, + AERO_WETH_cbBTC_POOL, + AERO_WETH_cbBTC_GAUGE, + AERO, + cbBTC_USD_FEED, + cbBTC_ORACLE_TIMEOUT, + cbBTC_ORACLE_ERROR, + ETH_USD_FEED, + ETH_ORACLE_TIMEOUT, + ETH_ORACLE_ERROR, +} from '../../../../test/plugins/individual-collateral/aerodrome/constants' + +// Aerodrome volatile plugin: WETH-cbBTCvAMM + +async function main() { + // ==== Read Configuration ==== + const [deployer] = await hre.ethers.getSigners() + + const chainId = await getChainId(hre) + + console.log(`Deploying Collateral to network ${hre.network.name} (${chainId}) + with burner account: ${deployer.address}`) + + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + // Get phase1 deployment + const phase1File = getDeploymentFilename(chainId) + if (!fileExists(phase1File)) { + throw new Error(`${phase1File} doesn't exist yet. Run phase 1`) + } + // Check previous step completed + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + const assetCollDeployments = getDeploymentFile(assetCollDeploymentFilename) + + const deployedCollateral: string[] = [] + + /******** Deploy Aerodrome Volatile Pool for WETH-cbBTC **************************/ + + let collateral: AerodromeVolatileCollateral + let wWethcbBTC: AerodromeGaugeWrapper + + // Only for Base + if (baseL2Chains.includes(hre.network.name)) { + const AerodromeVolatileCollateralFactory = await hre.ethers.getContractFactory( + 'AerodromeVolatileCollateral' + ) + const AerodromeGaugeWrapperFactory = await ethers.getContractFactory('AerodromeGaugeWrapper') + + // Deploy gauge wrapper + const pool = await ethers.getContractAt('IAeroPool', AERO_WETH_cbBTC_POOL) + wWethcbBTC = ( + await AerodromeGaugeWrapperFactory.deploy( + pool.address, + 'w' + (await pool.name()), + 'w' + (await pool.symbol()), + AERO, + AERO_WETH_cbBTC_GAUGE + ) + ) + await wWethcbBTC.deployed() + + console.log( + `Deployed wrapper for Aerodrome Volatile WETH-cbBTC pool on ${hre.network.name} (${chainId}): ${wWethcbBTC.address} ` + ) + + const oracleError = combinedError(cbBTC_ORACLE_ERROR, ETH_ORACLE_ERROR) // 0.3% & 0.15% + + collateral = await AerodromeVolatileCollateralFactory.connect( + deployer + ).deploy( + { + erc20: wWethcbBTC.address, + targetName: ethers.utils.formatBytes32String('ETH_BTC_AERODROME_cpAMM'), + priceTimeout: PRICE_TIMEOUT, + chainlinkFeed: ONE_ADDRESS, // unused but cannot be zero + oracleError: oracleError.toString(), // unused but cannot be zero + oracleTimeout: ETH_ORACLE_TIMEOUT, // max of oracleTimeouts + maxTradeVolume: MAX_TRADE_VOL, + defaultThreshold: '0', + delayUntilDefault: '86400', // 24h + }, + { + pool: AERO_WETH_cbBTC_POOL, + poolType: AerodromePoolType.Volatile, + feeds: [[ETH_USD_FEED], [cbBTC_USD_FEED]], + oracleTimeouts: [[ETH_ORACLE_TIMEOUT], [cbBTC_ORACLE_TIMEOUT]], + oracleErrors: [[ETH_ORACLE_ERROR], [cbBTC_ORACLE_ERROR]], + } + ) + } else { + throw new Error(`Unsupported chainId: ${chainId}`) + } + + await collateral.deployed() + await (await collateral.refresh()).wait() + expect(await collateral.status()).to.equal(CollateralStatus.SOUND) + + console.log( + `Deployed Aerodrome Volatile Collateral for WETH-cbBTC to ${hre.network.name} (${chainId}): ${collateral.address}` + ) + + assetCollDeployments.collateral.aeroWETHcbBTC = collateral.address + assetCollDeployments.erc20s.aeroWETHcbBTC = wWethcbBTC.address + deployedCollateral.push(collateral.address.toString()) + + fs.writeFileSync(assetCollDeploymentFilename, JSON.stringify(assetCollDeployments, null, 2)) + + console.log(`Deployed collateral to ${hre.network.name} (${chainId}) + New deployments: ${deployedCollateral} + Deployment file: ${assetCollDeploymentFilename}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_degen.ts b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_degen.ts new file mode 100644 index 000000000..cb48b58ae --- /dev/null +++ b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_degen.ts @@ -0,0 +1,140 @@ +import fs from 'fs' +import hre, { ethers } from 'hardhat' +import { getChainId } from '../../../../common/blockchain-utils' +import { baseL2Chains, networkConfig } from '../../../../common/configuration' +import { expect } from 'chai' +import { CollateralStatus, ONE_ADDRESS } from '../../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, + getDeploymentFilename, + fileExists, +} from '../../common' +import { + AerodromeVolatileCollateral, + AerodromeGaugeWrapper, + IAeroPool, +} from '../../../../typechain' +import { combinedError } from '../../utils' +import { + AerodromePoolType, + MAX_TRADE_VOL, + PRICE_TIMEOUT, + AERO_WETH_DEGEN_POOL, + AERO_WETH_DEGEN_GAUGE, + AERO, + DEGEN_USD_FEED, + DEGEN_ORACLE_TIMEOUT, + DEGEN_ORACLE_ERROR, + ETH_USD_FEED, + ETH_ORACLE_TIMEOUT, + ETH_ORACLE_ERROR, +} from '../../../../test/plugins/individual-collateral/aerodrome/constants' + +// Aerodrome volatile plugin: WETH-DEGEN vAMM + +async function main() { + // ==== Read Configuration ==== + const [deployer] = await hre.ethers.getSigners() + + const chainId = await getChainId(hre) + + console.log(`Deploying Collateral to network ${hre.network.name} (${chainId}) + with burner account: ${deployer.address}`) + + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + // Get phase1 deployment + const phase1File = getDeploymentFilename(chainId) + if (!fileExists(phase1File)) { + throw new Error(`${phase1File} doesn't exist yet. Run phase 1`) + } + // Check previous step completed + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + const assetCollDeployments = getDeploymentFile(assetCollDeploymentFilename) + + const deployedCollateral: string[] = [] + + /******** Deploy Aerodrome Volatile Pool for WETH-DEGEN **************************/ + + let collateral: AerodromeVolatileCollateral + let wWethDEGEN: AerodromeGaugeWrapper + + // Only for Base + if (baseL2Chains.includes(hre.network.name)) { + const AerodromeVolatileCollateralFactory = await hre.ethers.getContractFactory( + 'AerodromeVolatileCollateral' + ) + const AerodromeGaugeWrapperFactory = await ethers.getContractFactory('AerodromeGaugeWrapper') + + // Deploy gauge wrapper + const pool = await ethers.getContractAt('IAeroPool', AERO_WETH_DEGEN_POOL) + wWethDEGEN = ( + await AerodromeGaugeWrapperFactory.deploy( + pool.address, + 'w' + (await pool.name()), + 'w' + (await pool.symbol()), + AERO, + AERO_WETH_DEGEN_GAUGE + ) + ) + await wWethDEGEN.deployed() + + console.log( + `Deployed wrapper for Aerodrome Volatile WETH-DEGEN pool on ${hre.network.name} (${chainId}): ${wWethDEGEN.address} ` + ) + + const oracleError = combinedError(DEGEN_ORACLE_ERROR, ETH_ORACLE_ERROR) // 0.5% & 0.15% + + collateral = await AerodromeVolatileCollateralFactory.connect( + deployer + ).deploy( + { + erc20: wWethDEGEN.address, + targetName: ethers.utils.formatBytes32String('ETH_DEGEN_AERODROME_cpAMM'), + priceTimeout: PRICE_TIMEOUT, + chainlinkFeed: ONE_ADDRESS, // unused but cannot be zero + oracleError: oracleError.toString(), // unused but cannot be zero + oracleTimeout: DEGEN_ORACLE_TIMEOUT, // max of oracleTimeouts + maxTradeVolume: MAX_TRADE_VOL, + defaultThreshold: '0', + delayUntilDefault: '86400', // 24h + }, + { + pool: AERO_WETH_DEGEN_POOL, + poolType: AerodromePoolType.Volatile, + feeds: [[ETH_USD_FEED], [DEGEN_USD_FEED]], + oracleTimeouts: [[ETH_ORACLE_TIMEOUT], [DEGEN_ORACLE_TIMEOUT]], + oracleErrors: [[ETH_ORACLE_ERROR], [DEGEN_ORACLE_ERROR]], + } + ) + } else { + throw new Error(`Unsupported chainId: ${chainId}`) + } + + await collateral.deployed() + await (await collateral.refresh()).wait() + expect(await collateral.status()).to.equal(CollateralStatus.SOUND) + + console.log( + `Deployed Aerodrome Volatile Collateral for WETH-DEGEN to ${hre.network.name} (${chainId}): ${collateral.address}` + ) + + assetCollDeployments.collateral.aeroWETHDEGEN = collateral.address + assetCollDeployments.erc20s.aeroWETHDEGEN = wWethDEGEN.address + deployedCollateral.push(collateral.address.toString()) + + fs.writeFileSync(assetCollDeploymentFilename, JSON.stringify(assetCollDeployments, null, 2)) + + console.log(`Deployed collateral to ${hre.network.name} (${chainId}) + New deployments: ${deployedCollateral} + Deployment file: ${assetCollDeploymentFilename}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_well.ts b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_well.ts new file mode 100644 index 000000000..624b0961f --- /dev/null +++ b/scripts/deployment/phase2-assets/collaterals/deploy_aerodrome_weth_well.ts @@ -0,0 +1,140 @@ +import fs from 'fs' +import hre, { ethers } from 'hardhat' +import { getChainId } from '../../../../common/blockchain-utils' +import { baseL2Chains, networkConfig } from '../../../../common/configuration' +import { expect } from 'chai' +import { CollateralStatus, ONE_ADDRESS } from '../../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, + getDeploymentFilename, + fileExists, +} from '../../common' +import { + AerodromeVolatileCollateral, + AerodromeGaugeWrapper, + IAeroPool, +} from '../../../../typechain' +import { combinedError } from '../../utils' +import { + AerodromePoolType, + MAX_TRADE_VOL, + PRICE_TIMEOUT, + AERO_WETH_WELL_POOL, + AERO_WETH_WELL_GAUGE, + AERO, + WELL_USD_FEED, + WELL_ORACLE_TIMEOUT, + WELL_ORACLE_ERROR, + ETH_USD_FEED, + ETH_ORACLE_TIMEOUT, + ETH_ORACLE_ERROR, +} from '../../../../test/plugins/individual-collateral/aerodrome/constants' + +// Aerodrome volatile plugin: WETH-WELL vAMM + +async function main() { + // ==== Read Configuration ==== + const [deployer] = await hre.ethers.getSigners() + + const chainId = await getChainId(hre) + + console.log(`Deploying Collateral to network ${hre.network.name} (${chainId}) + with burner account: ${deployer.address}`) + + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + // Get phase1 deployment + const phase1File = getDeploymentFilename(chainId) + if (!fileExists(phase1File)) { + throw new Error(`${phase1File} doesn't exist yet. Run phase 1`) + } + // Check previous step completed + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + const assetCollDeployments = getDeploymentFile(assetCollDeploymentFilename) + + const deployedCollateral: string[] = [] + + /******** Deploy Aerodrome Volatile Pool for WETH-WELL **************************/ + + let collateral: AerodromeVolatileCollateral + let wWethWELL: AerodromeGaugeWrapper + + // Only for Base + if (baseL2Chains.includes(hre.network.name)) { + const AerodromeVolatileCollateralFactory = await hre.ethers.getContractFactory( + 'AerodromeVolatileCollateral' + ) + const AerodromeGaugeWrapperFactory = await ethers.getContractFactory('AerodromeGaugeWrapper') + + // Deploy gauge wrapper + const pool = await ethers.getContractAt('IAeroPool', AERO_WETH_WELL_POOL) + wWethWELL = ( + await AerodromeGaugeWrapperFactory.deploy( + pool.address, + 'w' + (await pool.name()), + 'w' + (await pool.symbol()), + AERO, + AERO_WETH_WELL_GAUGE + ) + ) + await wWethWELL.deployed() + + console.log( + `Deployed wrapper for Aerodrome Volatile WETH-WELL pool on ${hre.network.name} (${chainId}): ${wWethWELL.address} ` + ) + + const oracleError = combinedError(WELL_ORACLE_ERROR, ETH_ORACLE_ERROR) // 0.5% & 0.15% + + collateral = await AerodromeVolatileCollateralFactory.connect( + deployer + ).deploy( + { + erc20: wWethWELL.address, + targetName: ethers.utils.formatBytes32String('ETH_WELL_AERODROME_cpAMM'), + priceTimeout: PRICE_TIMEOUT, + chainlinkFeed: ONE_ADDRESS, // unused but cannot be zero + oracleError: oracleError.toString(), // unused but cannot be zero + oracleTimeout: WELL_ORACLE_TIMEOUT, // max of oracleTimeouts + maxTradeVolume: MAX_TRADE_VOL, + defaultThreshold: '0', + delayUntilDefault: '86400', // 24h + }, + { + pool: AERO_WETH_WELL_POOL, + poolType: AerodromePoolType.Volatile, + feeds: [[ETH_USD_FEED], [WELL_USD_FEED]], + oracleTimeouts: [[ETH_ORACLE_TIMEOUT], [WELL_ORACLE_TIMEOUT]], + oracleErrors: [[ETH_ORACLE_ERROR], [WELL_ORACLE_ERROR]], + } + ) + } else { + throw new Error(`Unsupported chainId: ${chainId}`) + } + + await collateral.deployed() + await (await collateral.refresh()).wait() + expect(await collateral.status()).to.equal(CollateralStatus.SOUND) + + console.log( + `Deployed Aerodrome Volatile Collateral for WETH-WELL to ${hre.network.name} (${chainId}): ${collateral.address}` + ) + + assetCollDeployments.collateral.aeroWETHWELL = collateral.address + assetCollDeployments.erc20s.aeroWETHWELL = wWethWELL.address + deployedCollateral.push(collateral.address.toString()) + + fs.writeFileSync(assetCollDeploymentFilename, JSON.stringify(assetCollDeployments, null, 2)) + + console.log(`Deployed collateral to ${hre.network.name} (${chainId}) + New deployments: ${deployedCollateral} + Deployment file: ${assetCollDeploymentFilename}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/verification/collateral-plugins/verify_aerodrome_weth_cbbtc.ts b/scripts/verification/collateral-plugins/verify_aerodrome_weth_cbbtc.ts new file mode 100644 index 000000000..061714f4f --- /dev/null +++ b/scripts/verification/collateral-plugins/verify_aerodrome_weth_cbbtc.ts @@ -0,0 +1,100 @@ +import hre, { ethers } from 'hardhat' +import { getChainId } from '../../../common/blockchain-utils' +import { baseL2Chains, developmentChains, networkConfig } from '../../../common/configuration' +import { ONE_ADDRESS } from '../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, +} from '../../deployment/common' +import { verifyContract } from '../../deployment/utils' +import { combinedError } from '../../deployment/utils' +import { IAeroPool } from '@typechain/IAeroPool' +import { + AerodromePoolType, + MAX_TRADE_VOL, + PRICE_TIMEOUT, + AERO_WETH_cbBTC_POOL, + AERO_WETH_cbBTC_GAUGE, + AERO, + cbBTC_ORACLE_TIMEOUT, + cbBTC_USD_FEED, + cbBTC_ORACLE_ERROR, + ETH_USD_FEED, + ETH_ORACLE_TIMEOUT, + ETH_ORACLE_ERROR, +} from '../../../test/plugins/individual-collateral/aerodrome/constants' + +let deployments: IAssetCollDeployments + +async function main() { + // ********** Read config ********** + const chainId = await getChainId(hre) + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + if (developmentChains.includes(hre.network.name)) { + throw new Error(`Cannot verify contracts for development chain ${hre.network.name}`) + } + + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + deployments = getDeploymentFile(assetCollDeploymentFilename) + + // Only on base, aways use wrapper + if (baseL2Chains.includes(hre.network.name)) { + const aeroWETHcbBTCPoolCollateral = await ethers.getContractAt( + 'AerodromeVolatileCollateral', + deployments.collateral.aeroWETHcbBTC as string + ) + + /******** Verify Gauge Wrapper **************************/ + + const pool = await ethers.getContractAt('IAeroPool', AERO_WETH_cbBTC_POOL) + await verifyContract( + chainId, + await aeroWETHcbBTCPoolCollateral.erc20(), + [ + pool.address, + 'w' + (await pool.name()), + 'w' + (await pool.symbol()), + AERO, + AERO_WETH_cbBTC_GAUGE, + ], + 'contracts/plugins/assets/aerodrome/AerodromeGaugeWrapper.sol:AerodromeGaugeWrapper' + ) + + /******** Verify WETH-cbBTC plugin **************************/ + const oracleError = combinedError(cbBTC_ORACLE_ERROR, ETH_ORACLE_ERROR) // 0.3% & 0.15% + await verifyContract( + chainId, + deployments.collateral.aeroWETHcbBTC, + [ + { + erc20: await aeroWETHcbBTCPoolCollateral.erc20(), + targetName: await aeroWETHcbBTCPoolCollateral.targetName(), + priceTimeout: PRICE_TIMEOUT, + chainlinkFeed: ONE_ADDRESS, // unused but cannot be zero + oracleError: oracleError.toString(), + oracleTimeout: ETH_ORACLE_TIMEOUT, // max of oracleTimeouts + maxTradeVolume: MAX_TRADE_VOL, + defaultThreshold: '0', + delayUntilDefault: '86400', + }, + { + pool: AERO_WETH_cbBTC_POOL, + poolType: AerodromePoolType.Volatile, + feeds: [[ETH_USD_FEED], [cbBTC_USD_FEED]], + oracleTimeouts: [[ETH_ORACLE_TIMEOUT], [cbBTC_ORACLE_TIMEOUT]], + oracleErrors: [[ETH_ORACLE_ERROR], [cbBTC_ORACLE_ERROR]], + }, + ], + 'contracts/plugins/assets/aerodrome/AerodromeVolatileCollateral.sol:AerodromeVolatileCollateral' + ) + } +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/verification/collateral-plugins/verify_aerodrome_weth_degen.ts b/scripts/verification/collateral-plugins/verify_aerodrome_weth_degen.ts new file mode 100644 index 000000000..533ef4d1e --- /dev/null +++ b/scripts/verification/collateral-plugins/verify_aerodrome_weth_degen.ts @@ -0,0 +1,100 @@ +import hre, { ethers } from 'hardhat' +import { getChainId } from '../../../common/blockchain-utils' +import { baseL2Chains, developmentChains, networkConfig } from '../../../common/configuration' +import { ONE_ADDRESS } from '../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, +} from '../../deployment/common' +import { verifyContract } from '../../deployment/utils' +import { combinedError } from '../../deployment/utils' +import { IAeroPool } from '@typechain/IAeroPool' +import { + AerodromePoolType, + MAX_TRADE_VOL, + PRICE_TIMEOUT, + AERO_WETH_DEGEN_POOL, + AERO_WETH_DEGEN_GAUGE, + AERO, + DEGEN_ORACLE_TIMEOUT, + DEGEN_USD_FEED, + DEGEN_ORACLE_ERROR, + ETH_USD_FEED, + ETH_ORACLE_TIMEOUT, + ETH_ORACLE_ERROR, +} from '../../../test/plugins/individual-collateral/aerodrome/constants' + +let deployments: IAssetCollDeployments + +async function main() { + // ********** Read config ********** + const chainId = await getChainId(hre) + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + if (developmentChains.includes(hre.network.name)) { + throw new Error(`Cannot verify contracts for development chain ${hre.network.name}`) + } + + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + deployments = getDeploymentFile(assetCollDeploymentFilename) + + // Only on base, aways use wrapper + if (baseL2Chains.includes(hre.network.name)) { + const aeroWETHDEGENPoolCollateral = await ethers.getContractAt( + 'AerodromeVolatileCollateral', + deployments.collateral.aeroWETHDEGEN as string + ) + + /******** Verify Gauge Wrapper **************************/ + + const pool = await ethers.getContractAt('IAeroPool', AERO_WETH_DEGEN_POOL) + await verifyContract( + chainId, + await aeroWETHDEGENPoolCollateral.erc20(), + [ + pool.address, + 'w' + (await pool.name()), + 'w' + (await pool.symbol()), + AERO, + AERO_WETH_DEGEN_GAUGE, + ], + 'contracts/plugins/assets/aerodrome/AerodromeGaugeWrapper.sol:AerodromeGaugeWrapper' + ) + + /******** Verify WETH-DEGEN plugin **************************/ + const oracleError = combinedError(DEGEN_ORACLE_ERROR, ETH_ORACLE_ERROR) // 0.5% & 0.15% + await verifyContract( + chainId, + deployments.collateral.aeroWETHDEGEN, + [ + { + erc20: await aeroWETHDEGENPoolCollateral.erc20(), + targetName: await aeroWETHDEGENPoolCollateral.targetName(), + priceTimeout: PRICE_TIMEOUT, + chainlinkFeed: ONE_ADDRESS, // unused but cannot be zero + oracleError: oracleError.toString(), + oracleTimeout: DEGEN_ORACLE_TIMEOUT, // max of oracleTimeouts + maxTradeVolume: MAX_TRADE_VOL, + defaultThreshold: '0', + delayUntilDefault: '86400', + }, + { + pool: AERO_WETH_DEGEN_POOL, + poolType: AerodromePoolType.Volatile, + feeds: [[ETH_USD_FEED], [DEGEN_USD_FEED]], + oracleTimeouts: [[ETH_ORACLE_TIMEOUT], [DEGEN_ORACLE_TIMEOUT]], + oracleErrors: [[ETH_ORACLE_ERROR], [DEGEN_ORACLE_ERROR]], + }, + ], + 'contracts/plugins/assets/aerodrome/AerodromeVolatileCollateral.sol:AerodromeVolatileCollateral' + ) + } +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/verification/collateral-plugins/verify_aerodrome_weth_well.ts b/scripts/verification/collateral-plugins/verify_aerodrome_weth_well.ts new file mode 100644 index 000000000..bf61166ec --- /dev/null +++ b/scripts/verification/collateral-plugins/verify_aerodrome_weth_well.ts @@ -0,0 +1,100 @@ +import hre, { ethers } from 'hardhat' +import { getChainId } from '../../../common/blockchain-utils' +import { baseL2Chains, developmentChains, networkConfig } from '../../../common/configuration' +import { ONE_ADDRESS } from '../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, +} from '../../deployment/common' +import { verifyContract } from '../../deployment/utils' +import { combinedError } from '../../deployment/utils' +import { IAeroPool } from '@typechain/IAeroPool' +import { + AerodromePoolType, + MAX_TRADE_VOL, + PRICE_TIMEOUT, + AERO_WETH_WELL_POOL, + AERO_WETH_WELL_GAUGE, + AERO, + WELL_ORACLE_TIMEOUT, + WELL_USD_FEED, + WELL_ORACLE_ERROR, + ETH_USD_FEED, + ETH_ORACLE_TIMEOUT, + ETH_ORACLE_ERROR, +} from '../../../test/plugins/individual-collateral/aerodrome/constants' + +let deployments: IAssetCollDeployments + +async function main() { + // ********** Read config ********** + const chainId = await getChainId(hre) + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + if (developmentChains.includes(hre.network.name)) { + throw new Error(`Cannot verify contracts for development chain ${hre.network.name}`) + } + + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + deployments = getDeploymentFile(assetCollDeploymentFilename) + + // Only on base, aways use wrapper + if (baseL2Chains.includes(hre.network.name)) { + const aeroWETHWELLPoolCollateral = await ethers.getContractAt( + 'AerodromeVolatileCollateral', + deployments.collateral.aeroWETHWELL as string + ) + + /******** Verify Gauge Wrapper **************************/ + + const pool = await ethers.getContractAt('IAeroPool', AERO_WETH_WELL_POOL) + await verifyContract( + chainId, + await aeroWETHWELLPoolCollateral.erc20(), + [ + pool.address, + 'w' + (await pool.name()), + 'w' + (await pool.symbol()), + AERO, + AERO_WETH_WELL_GAUGE, + ], + 'contracts/plugins/assets/aerodrome/AerodromeGaugeWrapper.sol:AerodromeGaugeWrapper' + ) + + /******** Verify WETH-WELL plugin **************************/ + const oracleError = combinedError(WELL_ORACLE_ERROR, ETH_ORACLE_ERROR) // 0.5% & 0.15% + await verifyContract( + chainId, + deployments.collateral.aeroWETHWELL, + [ + { + erc20: await aeroWETHWELLPoolCollateral.erc20(), + targetName: await aeroWETHWELLPoolCollateral.targetName(), + priceTimeout: PRICE_TIMEOUT, + chainlinkFeed: ONE_ADDRESS, // unused but cannot be zero + oracleError: oracleError.toString(), + oracleTimeout: WELL_ORACLE_TIMEOUT, // max of oracleTimeouts + maxTradeVolume: MAX_TRADE_VOL, + defaultThreshold: '0', + delayUntilDefault: '86400', + }, + { + pool: AERO_WETH_WELL_POOL, + poolType: AerodromePoolType.Volatile, + feeds: [[ETH_USD_FEED], [WELL_USD_FEED]], + oracleTimeouts: [[ETH_ORACLE_TIMEOUT], [WELL_ORACLE_TIMEOUT]], + oracleErrors: [[ETH_ORACLE_ERROR], [WELL_ORACLE_ERROR]], + }, + ], + 'contracts/plugins/assets/aerodrome/AerodromeVolatileCollateral.sol:AerodromeVolatileCollateral' + ) + } +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/verify_etherscan.ts b/scripts/verify_etherscan.ts index a3eddd842..a8692249c 100644 --- a/scripts/verify_etherscan.ts +++ b/scripts/verify_etherscan.ts @@ -96,6 +96,9 @@ async function main() { 'collateral-plugins/verify_aerodrome_weth_aero.ts', 'collateral-plugins/verify_aerodrome_mog_weth.ts', 'collateral-plugins/verify_aerodrome_usdz_usdc.ts', + 'collateral-plugins/verify_aerodrome_weth_cbbtc.ts', + 'collateral-plugins/verify_aerodrome_weth_well.ts', + 'collateral-plugins/verify_aerodrome_weth_degen.ts', 'collateral-plugins/verify_morphoeUSD.ts' ) } else if (chainId == '42161' || chainId == '421614') { diff --git a/test/plugins/individual-collateral/aerodrome/AerodromeVolatileCollateral.test.ts b/test/plugins/individual-collateral/aerodrome/AerodromeVolatileCollateral.test.ts index e0ffb245e..2269132ea 100644 --- a/test/plugins/individual-collateral/aerodrome/AerodromeVolatileCollateral.test.ts +++ b/test/plugins/individual-collateral/aerodrome/AerodromeVolatileCollateral.test.ts @@ -39,6 +39,30 @@ import { AERO_WETH_AERO_POOL, AERO_WETH_AERO_GAUGE, AERO_WETH_AERO_HOLDER, + AERO_WETH_cbBTC_POOL, + AERO_WETH_cbBTC_GAUGE, + AERO_WETH_cbBTC_HOLDER, + AERO_WETH_WELL_POOL, + AERO_WETH_WELL_GAUGE, + AERO_WETH_WELL_HOLDER, + AERO_WETH_DEGEN_POOL, + AERO_WETH_DEGEN_GAUGE, + AERO_WETH_DEGEN_HOLDER, + cbBTC, + cbBTC_USD_FEED, + cbBTC_ORACLE_ERROR, + cbBTC_ORACLE_TIMEOUT, + cbBTC_HOLDER, + WELL, + WELL_USD_FEED, + WELL_ORACLE_ERROR, + WELL_ORACLE_TIMEOUT, + WELL_HOLDER, + DEGEN, + DEGEN_USD_FEED, + DEGEN_ORACLE_ERROR, + DEGEN_ORACLE_TIMEOUT, + DEGEN_HOLDER, ETH_USD_FEED, ETH_ORACLE_ERROR, ETH_ORACLE_TIMEOUT, @@ -138,6 +162,84 @@ const all: AeroVolatilePoolEnumeration[] = [ amountScaleDivisor: bn('1e2'), toleranceDivisor: bn('1e4'), }, + { + testName: 'Aerodrome - WETH/cbBTC Volatile', + pool: AERO_WETH_cbBTC_POOL, + gauge: AERO_WETH_cbBTC_GAUGE, + holder: AERO_WETH_cbBTC_HOLDER, + tokens: [ + { + token: WETH, + feeds: [ETH_USD_FEED], + oracleTimeouts: [ETH_ORACLE_TIMEOUT], + oracleErrors: [ETH_ORACLE_ERROR], + holder: WETH_HOLDER, + }, + { + token: cbBTC, + feeds: [cbBTC_USD_FEED], + oracleTimeouts: [cbBTC_ORACLE_TIMEOUT], + oracleErrors: [cbBTC_ORACLE_ERROR], + holder: cbBTC_HOLDER, + }, + ], + oracleTimeout: ETH_ORACLE_TIMEOUT, // max + oracleError: cbBTC_ORACLE_ERROR.add(ETH_ORACLE_ERROR), // combined + amountScaleDivisor: bn('1e6'), + toleranceDivisor: bn('1e4'), + }, + { + testName: 'Aerodrome - WETH/WELL Volatile', + pool: AERO_WETH_WELL_POOL, + gauge: AERO_WETH_WELL_GAUGE, + holder: AERO_WETH_WELL_HOLDER, + tokens: [ + { + token: WETH, + feeds: [ETH_USD_FEED], + oracleTimeouts: [ETH_ORACLE_TIMEOUT], + oracleErrors: [ETH_ORACLE_ERROR], + holder: WETH_HOLDER, + }, + { + token: WELL, + feeds: [WELL_USD_FEED], + oracleTimeouts: [WELL_ORACLE_TIMEOUT], + oracleErrors: [WELL_ORACLE_ERROR], + holder: WELL_HOLDER, + }, + ], + oracleTimeout: WELL_ORACLE_TIMEOUT, // max + oracleError: WELL_ORACLE_ERROR.add(ETH_ORACLE_ERROR), // combined + amountScaleDivisor: bn('1e2'), + toleranceDivisor: bn('1e4'), + }, + { + testName: 'Aerodrome - WETH/DEGN Volatile', + pool: AERO_WETH_DEGEN_POOL, + gauge: AERO_WETH_DEGEN_GAUGE, + holder: AERO_WETH_DEGEN_HOLDER, + tokens: [ + { + token: WETH, + feeds: [ETH_USD_FEED], + oracleTimeouts: [ETH_ORACLE_TIMEOUT], + oracleErrors: [ETH_ORACLE_ERROR], + holder: WETH_HOLDER, + }, + { + token: DEGEN, + feeds: [DEGEN_USD_FEED], + oracleTimeouts: [DEGEN_ORACLE_TIMEOUT], + oracleErrors: [DEGEN_ORACLE_ERROR], + holder: DEGEN_HOLDER, + }, + ], + oracleTimeout: DEGEN_ORACLE_TIMEOUT, // max + oracleError: DEGEN_ORACLE_ERROR.add(ETH_ORACLE_ERROR), // combined + amountScaleDivisor: bn('1e2'), + toleranceDivisor: bn('1e4'), + }, ] all.forEach((curr: AeroVolatilePoolEnumeration) => { diff --git a/test/plugins/individual-collateral/aerodrome/constants.ts b/test/plugins/individual-collateral/aerodrome/constants.ts index 1714de5f1..984cde0eb 100644 --- a/test/plugins/individual-collateral/aerodrome/constants.ts +++ b/test/plugins/individual-collateral/aerodrome/constants.ts @@ -7,7 +7,7 @@ export const forkNetwork = useEnv('FORK_NETWORK') ?? 'base' // Base Addresses export const AERO_USDC_eUSD_GAUGE = '0x793F22aB88dC91793E5Ce6ADbd7E733B0BD4733e' export const AERO_USDC_eUSD_POOL = '0x7A034374C89C463DD65D8C9BCfe63BcBCED41f4F' -export const AERO_USDC_eUSD_HOLDER = '0xB6C8ea53ABA64a4BdE857D3b25d9DEbD0B149a0a' // for gauge +export const AERO_USDC_eUSD_HOLDER = '0x5d823546463fD0Ac3b31DBA6AD38B56a39BFbf70' // for gauge export const AERO_WETH_AERO_GAUGE = '0x96a24aB830D4ec8b1F6f04Ceac104F1A3b211a01' export const AERO_WETH_AERO_POOL = '0x7f670f78B17dEC44d5Ef68a48740b6f8849cc2e6' @@ -21,6 +21,18 @@ export const AERO_USDz_USDC_GAUGE = '0xb7E4bBee04285F4B55d0A93b34E5dA95C3a7faf9' export const AERO_USDz_USDC_POOL = '0x6d0b9C9E92a3De30081563c3657B5258b3fFa38B' export const AERO_USDz_USDC_HOLDER = '0x4C3cB0D6273A27C68AB4B2F96DB211d8d75e98Da' +export const AERO_WETH_cbBTC_GAUGE = '0xAFdEBa12B6a870d6639d043030b4b49F9C7c62BB' +export const AERO_WETH_cbBTC_POOL = '0x2578365B3dfA7FfE60108e181EFb79FeDdec2319' +export const AERO_WETH_cbBTC_HOLDER = '0x106b9121d259fb46F1033BDBd29ad0C67650953C' + +export const AERO_WETH_WELL_GAUGE = '0x7b6964440b615aC1d31bc95681B133E112fB2684' +export const AERO_WETH_WELL_POOL = '0x89D0F320ac73dd7d9513FFC5bc58D1161452a657' +export const AERO_WETH_WELL_HOLDER = '0x5a6859C2f992B998837342d29911dD14E8DC2E1a' + +export const AERO_WETH_DEGEN_GAUGE = '0x86A1260AB9f758026Ce1a5830BdfF66DBcF736d5' +export const AERO_WETH_DEGEN_POOL = '0x2C4909355b0C036840819484c3A882A95659aBf3' +export const AERO_WETH_DEGEN_HOLDER = '0xC314990f1379fEe384Be9a74328C75Df8587aE77' + export const AERODROME_ROUTER = '0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43' // Tokens @@ -30,6 +42,9 @@ export const eUSD = networkConfig['8453'].tokens.eUSD! export const USDz = networkConfig['8453'].tokens.USDz! export const AERO = networkConfig['8453'].tokens.AERO! export const MOG = networkConfig['8453'].tokens.MOG! +export const cbBTC = networkConfig['8453'].tokens.cbBTC! +export const WELL = networkConfig['8453'].tokens.WELL! +export const DEGEN = networkConfig['8453'].tokens.DEGEN! // USDC export const USDC_USD_FEED = networkConfig['8453'].chainlinkFeeds.USDC! @@ -49,7 +64,7 @@ export const USDz_ORACLE_TIMEOUT = bn('86400') export const USDz_ORACLE_ERROR = fp('0.005') export const USDz_HOLDER = '0xA87c9808C0eBE20a1427B5C769623c77201f6f4D' -export const FORK_BLOCK = 21668000 //19980400 +export const FORK_BLOCK = 22854038 //19980400 // AERO export const AERO_ORACLE_ERROR = fp('0.005') // 0.5% @@ -69,12 +84,30 @@ export const MOG_ORACLE_TIMEOUT = bn('86400') // 24hr export const MOG_USD_FEED = networkConfig['8453'].chainlinkFeeds.MOG! export const MOG_HOLDER = '0xBaeD383EDE0e5d9d72430661f3285DAa77E9439F' +// cbBTC +export const cbBTC_ORACLE_ERROR = fp('0.003') // 0.3% +export const cbBTC_ORACLE_TIMEOUT = bn('1200') // 20 min +export const cbBTC_USD_FEED = networkConfig['8453'].chainlinkFeeds.cbBTC! +export const cbBTC_HOLDER = '0xF877ACaFA28c19b96727966690b2f44d35aD5976' + +// WELL +export const WELL_ORACLE_ERROR = fp('0.005') // 0.5% +export const WELL_ORACLE_TIMEOUT = bn('86400') // 24hr +export const WELL_USD_FEED = networkConfig['8453'].chainlinkFeeds.WELL! +export const WELL_HOLDER = '0xe66E3A37C3274Ac24FE8590f7D84A2427194DC17' + +// DEGEN +export const DEGEN_ORACLE_ERROR = fp('0.005') // 0.5% +export const DEGEN_ORACLE_TIMEOUT = bn('86400') // 24hr +export const DEGEN_USD_FEED = networkConfig['8453'].chainlinkFeeds.DEGEN! +export const DEGEN_HOLDER = '0x06A19654e0872Ba71c2261EA691Ecf8a0c677156' + // Common export const FIX_ONE = 1n * 10n ** 18n export const ORACLE_ERROR = fp('0.005') export const PRICE_TIMEOUT = bn('604800') // 1 week export const DEFAULT_THRESHOLD = fp('0.02') // 2% -export const DELAY_UNTIL_DEFAULT = bn('259200') // 72h CAREFUL THIS IS ONLY FOR RTOKEN POOLS +export const DELAY_UNTIL_DEFAULT = bn('259200') // 72h CAREFUL THIS IS ONLY FOR STABLE POOLS export const MAX_TRADE_VOL = fp('1e6') export enum AerodromePoolType { diff --git a/test/plugins/individual-collateral/aerodrome/helpers.ts b/test/plugins/individual-collateral/aerodrome/helpers.ts index abdf8ae9a..1edc8dfde 100644 --- a/test/plugins/individual-collateral/aerodrome/helpers.ts +++ b/test/plugins/individual-collateral/aerodrome/helpers.ts @@ -196,7 +196,7 @@ export const allStableTests: AeroStablePoolEnumeration[] = [ ], oracleTimeout: PRICE_TIMEOUT, // max oracleError: ORACLE_ERROR, // combined - amountScaleDivisor: bn('1e2'), + amountScaleDivisor: bn('1e3'), toleranceDivisor: bn('1e2'), fix: makeWUSDCeUSD, },