From 0462ed85ecb00136df6b2e25c321015c004d4c96 Mon Sep 17 00:00:00 2001 From: Mark Hinschberger Date: Mon, 2 Oct 2023 17:46:10 +0100 Subject: [PATCH] setup --- .../03_periphery_post/04_paraswap_adapters.ts | 7 +- hardhat.config.ts | 7 ++ helpers/constants.ts | 4 + helpers/hardhat-config-helpers.ts | 10 +++ helpers/market-config-helpers.ts | 5 ++ helpers/types.ts | 8 +- markets/aave/commons.ts | 5 ++ markets/aave/reservesConfigs.ts | 18 +++++ markets/base/index.ts | 72 ++++++++++++++++++ package.json | 9 ++- tasks/misc/deploy-paraswapAdapters.ts | 73 +++++++++++++++++++ 11 files changed, 214 insertions(+), 4 deletions(-) create mode 100644 markets/base/index.ts create mode 100644 tasks/misc/deploy-paraswapAdapters.ts diff --git a/deploy/03_periphery_post/04_paraswap_adapters.ts b/deploy/03_periphery_post/04_paraswap_adapters.ts index 04bc394..ab6eb46 100644 --- a/deploy/03_periphery_post/04_paraswap_adapters.ts +++ b/deploy/03_periphery_post/04_paraswap_adapters.ts @@ -19,7 +19,6 @@ const func: DeployFunction = async function ({ }: HardhatRuntimeEnvironment) { const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const network = ( process.env.FORK ? process.env.FORK : hre.network.name ) as eNetwork; @@ -54,6 +53,12 @@ const func: DeployFunction = async function ({ args: [addressesProvider, paraswapAugustusRegistry, poolAdmin], }); + await deploy("ParaSwapWithdrawSwapAdapter", { + from: deployer, + ...COMMON_DEPLOY_PARAMS, + args: [addressesProvider, paraswapAugustusRegistry, poolAdmin], + }); + return true; }; diff --git a/hardhat.config.ts b/hardhat.config.ts index 2b07782..c1c4e4a 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -15,6 +15,7 @@ import { eOptimismNetwork, ePolygonNetwork, eTenderly, + eBaseNetwork, } from "./helpers/types"; import { DEFAULT_NAMED_ACCOUNTS } from "./helpers/constants"; @@ -121,6 +122,11 @@ export default { eArbitrumNetwork.goerliNitro, 421613 ), + [eBaseNetwork.base]: getCommonNetworkConfig(eBaseNetwork.base, 8453), + [eBaseNetwork.baseGoerli]: getCommonNetworkConfig( + eBaseNetwork.baseGoerli, + 84531 + ), }, namedAccounts: { ...DEFAULT_NAMED_ACCOUNTS, @@ -191,6 +197,7 @@ export default { "@aave/periphery-v3/contracts/treasury/AaveEcosystemReserveController.sol", "@aave/periphery-v3/contracts/adapters/paraswap/ParaSwapLiquiditySwapAdapter.sol", "@aave/periphery-v3/contracts/adapters/paraswap/ParaSwapRepayAdapter.sol", + "@aave/periphery-v3/contracts/adapters/paraswap/ParaSwapWithdrawSwapAdapter.sol", "@aave/safety-module/contracts/stake/StakedAave.sol", "@aave/safety-module/contracts/stake/StakedAaveV2.sol", "@aave/safety-module/contracts/proposals/extend-stkaave-distribution/StakedTokenV2Rev3.sol", diff --git a/helpers/constants.ts b/helpers/constants.ts index c9cc0d0..91a52ff 100644 --- a/helpers/constants.ts +++ b/helpers/constants.ts @@ -2,6 +2,7 @@ import { parseEther, parseUnits } from "ethers/lib/utils"; import { eArbitrumNetwork, eAvalancheNetwork, + eBaseNetwork, eEthereumNetwork, eFantomNetwork, eHarmonyNetwork, @@ -75,6 +76,7 @@ export const MOCK_CHAINLINK_AGGREGATORS_PRICES: { [key: string]: string } = { AGEUR: parseUnits("1.126", 8).toString(), JEUR: parseUnits("1.126", 8).toString(), DPI: parseUnits("149", 8).toString(), + CBETH: parseUnits("4000", 8).toString(), }; export const chainlinkAggregatorProxy: Record = { @@ -137,6 +139,8 @@ export const POOL_ADMIN: Record = { [eOptimismNetwork.main]: "0xE50c8C619d05ff98b22Adf991F17602C774F785c", [ePolygonNetwork.polygon]: "0xdc9A35B16DB4e126cFeDC41322b3a36454B1F772", [eEthereumNetwork.main]: ETHEREUM_SHORT_EXECUTOR, + [eBaseNetwork.base]: "0xA9F30e6ED4098e9439B2ac8aEA2d3fc26BcEbb45", + [eBaseNetwork.baseGoerli]: "0xA9F30e6ED4098e9439B2ac8aEA2d3fc26BcEbb45", }; export const EMERGENCY_ADMIN: Record = { diff --git a/helpers/hardhat-config-helpers.ts b/helpers/hardhat-config-helpers.ts index b0bc841..b5be3c7 100644 --- a/helpers/hardhat-config-helpers.ts +++ b/helpers/hardhat-config-helpers.ts @@ -11,6 +11,7 @@ import { eAvalancheNetwork, eFantomNetwork, eOptimismNetwork, + eBaseNetwork, } from "./types"; require("dotenv").config(); @@ -47,6 +48,8 @@ export const getAlchemyKey = (net: eNetwork) => { return process.env.GOERLI_ALCHEMY_KEY || ALCHEMY_KEY; case eEthereumNetwork.sepolia: return process.env.SEPOLIA_ALCHEMY_KEY || ALCHEMY_KEY; + case eBaseNetwork.base: + return process.env.BASE_ALCHEMY_KEY || ALCHEMY_KEY; default: return ALCHEMY_KEY; } @@ -91,6 +94,10 @@ export const NETWORKS_RPC_URL: iParamsPerNetwork = { eEthereumNetwork.sepolia )}`, [eArbitrumNetwork.goerliNitro]: `https://goerli-rollup.arbitrum.io/rpc`, + [eBaseNetwork.baseGoerli]: `https://goerli.base.org`, + [eBaseNetwork.base]: `https://base-mainnet.g.alchemy.com/v2/${getAlchemyKey( + eBaseNetwork.base + )}`, }; export const LIVE_NETWORKS: iParamsPerNetwork = { @@ -101,12 +108,15 @@ export const LIVE_NETWORKS: iParamsPerNetwork = { [eAvalancheNetwork.avalanche]: true, [eFantomNetwork.main]: true, [eOptimismNetwork.main]: true, + [eBaseNetwork.base]: true, }; const GAS_PRICE_PER_NET: iParamsPerNetwork = { [eArbitrumNetwork.goerliNitro]: 100000001, + [eBaseNetwork.baseGoerli]: 8000000000, }; +console.log("FORK", FORK); export const buildForkConfig = (): | HardhatNetworkForkingUserConfig | undefined => { diff --git a/helpers/market-config-helpers.ts b/helpers/market-config-helpers.ts index 5394214..d684844 100644 --- a/helpers/market-config-helpers.ts +++ b/helpers/market-config-helpers.ts @@ -21,6 +21,7 @@ import FantomMarket from "../markets/fantom"; import PolygonMarket from "../markets/polygon"; import OptimisticConfig from "../markets/optimistic"; import ArbitrumConfig from "../markets/arbitrum"; +import BaseConfig from "../markets/base"; import { isValidAddress } from "./utilities/utils"; import { AaveProtocolDataProvider } from "../typechain"; import { @@ -49,6 +50,8 @@ export enum ConfigNames { Optimistic = "Optimistic", Arbitrum = "Arbitrum", Ethereum = "Ethereum", + Base = "Base", + baseGoerli = "base-goerli", } export const getParamPerNetwork = ( @@ -114,6 +117,8 @@ export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => { return ArbitrumConfig; case ConfigNames.Ethereum: return EthereumV3Config; + case ConfigNames.Base: + return BaseConfig; default: throw new Error( `Unsupported pool configuration: ${configName} is not one of the supported configs ${Object.values( diff --git a/helpers/types.ts b/helpers/types.ts index 363d86c..b0cfd80 100644 --- a/helpers/types.ts +++ b/helpers/types.ts @@ -17,7 +17,8 @@ export type eNetwork = | eHarmonyNetwork | eFantomNetwork | eOptimismNetwork - | eTenderlyNetwork; + | eTenderlyNetwork + | eBaseNetwork; type eTenderlyNetwork = "tenderly"; @@ -44,6 +45,11 @@ export enum eEthereumNetwork { sepolia = "sepolia", } +export enum eBaseNetwork { + base = "base", + baseGoerli = "base-goerli", +} + export enum ePolygonNetwork { polygon = "polygon", mumbai = "mumbai", diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts index 09c82b9..dd1f3c8 100644 --- a/markets/aave/commons.ts +++ b/markets/aave/commons.ts @@ -6,6 +6,7 @@ import { eOptimismNetwork, ePolygonNetwork, TransferStrategy, + eBaseNetwork, } from "./../../helpers/types"; import { ZERO_ADDRESS } from "../../helpers/constants"; import { @@ -158,6 +159,8 @@ export const CommonsConfig: ICommonConfiguration = { [eArbitrumNetwork.arbitrumTestnet]: true, [eOptimismNetwork.main]: true, [eOptimismNetwork.testnet]: true, + [eBaseNetwork.base]: true, + [eBaseNetwork.baseGoerli]: true, }, ParaswapRegistry: { [eEthereumNetwork.main]: "0xa68bEA62Dc4034A689AA0F58A76681433caCa663", @@ -165,6 +168,8 @@ export const CommonsConfig: ICommonConfiguration = { [eAvalancheNetwork.avalanche]: "0xfD1E5821F07F1aF812bB7F3102Bfd9fFb279513a", [eFantomNetwork.main]: "0x161383b5dAFc1cc05Ec058e5B0b0703BA175bdA6", [eArbitrumNetwork.arbitrum]: "0xdC6E2b14260F972ad4e5a31c68294Fba7E720701", + [eBaseNetwork.base]: "0x7e31b336f9e8ba52ba3c4ac861b033ba90900bb3", + [eBaseNetwork.baseGoerli]: "0x7e31b336f9e8ba52ba3c4ac861b033ba90900bb3", }, FlashLoanPremiums: { total: 0.0005e4, diff --git a/markets/aave/reservesConfigs.ts b/markets/aave/reservesConfigs.ts index b1e55cf..59141f9 100644 --- a/markets/aave/reservesConfigs.ts +++ b/markets/aave/reservesConfigs.ts @@ -78,6 +78,24 @@ export const strategyWETH: IReserveParams = { borrowableIsolation: false, }; +export const strategyCBETH: IReserveParams = { + strategy: rateStrategyVolatileOne, + baseLTVAsCollateral: "8000", + liquidationThreshold: "8250", + liquidationBonus: "10500", + liquidationProtocolFee: "1000", + borrowingEnabled: true, + stableBorrowRateEnabled: false, + flashLoanEnabled: true, + reserveDecimals: "18", + aTokenImpl: eContractid.AToken, + reserveFactor: "1000", + supplyCap: "0", + borrowCap: "0", + debtCeiling: "0", + borrowableIsolation: false, +}; + export const strategyLINK: IReserveParams = { strategy: rateStrategyVolatileOne, baseLTVAsCollateral: "7000", diff --git a/markets/base/index.ts b/markets/base/index.ts new file mode 100644 index 0000000..e8da482 --- /dev/null +++ b/markets/base/index.ts @@ -0,0 +1,72 @@ +import { eBaseNetwork, IAaveConfiguration } from "./../../helpers/types"; +import AaveMarket from "../aave"; +import { ZERO_ADDRESS } from "../../helpers"; +import { + strategyDAI, + strategyUSDC, + strategyLINK, + strategyWBTC, + strategyWETH, + strategyUSDT, + strategyAAVE, + strategyEURS, + strategyCBETH, +} from "../aave/reservesConfigs"; + +export const BaseConfig: IAaveConfiguration = { + ...AaveMarket, + MarketId: "Base Aave Market", + ATokenNamePrefix: "Base", + StableDebtTokenNamePrefix: "Base", + VariableDebtTokenNamePrefix: "Base", + SymbolPrefix: "Base", + ProviderId: 37, + ReservesConfig: { + DAI: strategyDAI, + LINK: strategyLINK, + USDC: strategyUSDC, + WBTC: strategyWBTC, + WETH: strategyWETH, + USDT: strategyUSDT, + AAVE: strategyAAVE, + EURS: strategyEURS, + CBETH: strategyCBETH, + }, + ReserveAssets: { + [eBaseNetwork.base]: { + USDC: "0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca", // usdbc + WETH: "0x4200000000000000000000000000000000000006", + CBETH: "0x2ae3f1ec7f1f5012cfeab0185bfc7aa3cf0dec22", + }, + [eBaseNetwork.baseGoerli]: { + DAI: ZERO_ADDRESS, + LINK: ZERO_ADDRESS, + USDC: ZERO_ADDRESS, + WBTC: ZERO_ADDRESS, + WETH: ZERO_ADDRESS, + USDT: ZERO_ADDRESS, + AAVE: ZERO_ADDRESS, + EURS: ZERO_ADDRESS, + CBETH: ZERO_ADDRESS, + }, + }, + EModes: { + StableEMode: { + id: "1", + ltv: "9700", + liquidationThreshold: "9750", + liquidationBonus: "10100", + label: "Stablecoins", + assets: ["USDC"], + }, + }, + ChainlinkAggregator: { + [eBaseNetwork.base]: { + USDC: "0x7e860098f58bbfc8648a4311b374b1d669a2bc6b", + WETH: "0x71041dddad3595f9ced3dccfbe3d1f4b0a16bb70", + CBETH: "0xd7818272b9e248357d13057aab0b417af31e817d", + }, + }, +}; + +export default BaseConfig; diff --git a/package.json b/package.json index 854b9b7..61b7659 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,15 @@ "devDependencies": { "@aave/aave-token": "^1.0.4", "@aave/core-v3": "^1.19.0", - "@aave/periphery-v3": "^2.4.1", + "@aave/periphery-v3": "^2.5.0", "@aave/safety-module": "^1.0.3", "@nomicfoundation/hardhat-chai-matchers": "^1.0.5", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", "@nomicfoundation/hardhat-toolbox": "^2.0.0", "@nomiclabs/hardhat-etherscan": "^3.1.0", "@openzeppelin/contracts": "^4.3.2", + "@typechain/ethers-v5": "^10.1.0", + "@typechain/hardhat": "^6.1.2", "@types/bluebird": "^3.5.36", "@types/chai": "^4.2.21", "@types/mkdirp": "^1.0.2", @@ -39,7 +42,7 @@ "chalk": "^4.1.2", "dotenv": "^10.0.0", "ethers": "^5.4.7", - "hardhat": "^2.12.4", + "hardhat": "^2.17.4", "hardhat-contract-sizer": "^2.0.3", "hardhat-dependency-compiler": "^1.1.2", "hardhat-deploy": "^0.10.6", @@ -49,6 +52,7 @@ "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", "tslint-plugin-prettier": "^2.3.0", + "typechain": "^8.1.0", "typescript": "^4.3.2" }, "license": "AGPLv3", @@ -81,6 +85,7 @@ "url": "git://github.com/aave/aave-v3-deploy" }, "dependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.0", "defender-relay-client": "^1.11.1" } } diff --git a/tasks/misc/deploy-paraswapAdapters.ts b/tasks/misc/deploy-paraswapAdapters.ts new file mode 100644 index 0000000..447cabe --- /dev/null +++ b/tasks/misc/deploy-paraswapAdapters.ts @@ -0,0 +1,73 @@ +import { task } from "hardhat/config"; +import { + POOL_ADMIN, + loadPoolConfig, + ConfigNames, + eNetwork, +} from "../../helpers"; +import { getParamPerNetwork } from "../../helpers/market-config-helpers"; +import { MARKET_NAME } from "../../helpers/env"; +import { ZERO_ADDRESS } from "../../helpers/constants"; + +task(`deploy-paraswap-adapters`, `Deploys the paraswap adapter contracts`) + .addParam("addressesProvider", "address network provider") + + .setAction(async ({ addressesProvider }, hre) => { + if (!hre.network.config.chainId) { + throw new Error("INVALID_CHAIN_ID"); + } + + const network = ( + process.env.FORK ? process.env.FORK : hre.network.name + ) as eNetwork; + + const { deployer } = await hre.getNamedAccounts(); + + const poolConfig = await loadPoolConfig(MARKET_NAME as ConfigNames); + + const paraswapAugustusRegistry = getParamPerNetwork( + poolConfig.ParaswapRegistry, + network + ); + + if (!paraswapAugustusRegistry) { + console.log( + "[WARNING] Skipping the deployment of the Paraswap Liquidity Swap and Repay adapters due missing 'ParaswapRegistry' address at pool configuration." + ); + return; + } + + const poolAdmin = POOL_ADMIN[network]; + + const paraSwapLiquiditySwapAdapter = await hre.ethers.deployContract( + "ParaSwapLiquiditySwapAdapter", + [addressesProvider, paraswapAugustusRegistry, poolAdmin] + ); + console.log("deploying paraswap repay adapter"); + + const paraSwapRepayAdapter = await hre.ethers.deployContract( + "ParaSwapRepayAdapter", + [addressesProvider, paraswapAugustusRegistry, poolAdmin] + ); + + console.log("deploying paraswap swap and withdraw adapter"); + + const paraSwapWithdrawSwapAdapter = await hre.ethers.deployContract( + "ParaSwapWithdrawSwapAdapter", + [addressesProvider, paraswapAugustusRegistry, poolAdmin] + ); + + console.log( + `paraSwapLiquiditySwapAdapter deployed at`, + paraSwapLiquiditySwapAdapter.address + ); + console.log( + `paraSwapRepayAdapter deployed at`, + paraSwapRepayAdapter.address + ); + + console.log( + "paraSwapWithdrawSwapAdapter", + paraSwapWithdrawSwapAdapter.address + ); + });