Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base Market Deployments #110

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions deployment-config/00_Default.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"initialDefaultAdmin": "0x94544835Cf97c631f101c5f538787fE14E2E04f6",
"protocol": "0x0000000000417626Ef34D62C4DC189b021603f2F",
"ilkAddress": "0xbf5495Efe5DB9ce00f80364C8B423567e58d2110"
}
"ilkAddress": "0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A"
}
2 changes: 1 addition & 1 deletion deployment-config/02_DeployInterestRateModule.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"adjustedAboveKinkSlope": "0",
"minimumAboveKinkSlope": "64011036758000000000"
},
"yieldOracleAddress": "0x437CC840e234C2127f54CD59B0B18aF59c586760"
"yieldOracleAddress": "0x05f5Fe49e6298169056C1F9B1ea8D8e12A59eE55"
}
15 changes: 7 additions & 8 deletions deployment-config/04_DeployIonPool.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{
"underlying": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"treasury": "0x0000000000417626Ef34D62C4DC189b021603f2F",
"underlying": "0x4200000000000000000000000000000000000006",
"treasury": "0x94544835Cf97c631f101c5f538787fE14E2E04f6",
"decimals": "18",
"name": "Ion ezETH WETH Token",
"symbol": "iezETH-WETH",
"whitelist": "0x7E317f99aA313669AaCDd8dB3927ff3aCB562dAD",
"interestRateModule": "0xCcfD0fDEE103B4b4e45B5D8934540070219A6653",
"ionImpl": "0x77ca0d4b78d8b4f3c71e20f8c8771c4cb7abe201",
"salt": "0x413a3e110b6efc009e045a000000000000000000000000000000000000000000"
"name": "Ion weETH WETH Token",
"symbol": "iweETH-WETH",
"whitelist": "0xE2aA4636448CDB61A25388B23BA10f9675A9b4d9",
"interestRateModule": "0x643e2674e38234b67DD8F1CE4a9e5F645870F6c1",
"salt": "0xa53bcb7572e19b03e4aae7000000000000000000000000000000000000000000"
}
3 changes: 2 additions & 1 deletion deployment-config/05_DeployInitialReserveAndSpotOracles.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"maxChange": "30000000000000000000000000",
"ltv": "930000000000000000000000000",
"maxTimeFromLastUpdate": "87000"
"maxTimeFromLastUpdate": "87000",
"gracePeriod": "3600"
}
6 changes: 3 additions & 3 deletions deployment-config/06_SetupCollateral.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ionPool": "0x00000000008a3A77bd91bC738Ed2Efaa262c3763",
"spotOracle": "0x08fEDD981732c2a0EceCd4c70a41eA3AC454A6FD",
"debtCeiling": "0",
"ionPool": "0x00000000000fA8e0FD26b4554d067CF1856De7F5",
"spotOracle": "0x80Cdf376cBd1D1c8729cd8f0D607388821f25D54",
"debtCeiling": "100000000000000000000000000000000000000000000000",
"dust": "4000000000000000000000000000000000000000000000"
}
2 changes: 1 addition & 1 deletion deployment-config/07_DeployGemJoin.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"ionPool": "0x00000000008a3A77bd91bC738Ed2Efaa262c3763"
"ionPool": "0x00000000000fA8e0FD26b4554d067CF1856De7F5"
}
6 changes: 3 additions & 3 deletions deployment-config/08_DeployHandlers.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"ionPool": "0x00000000008a3A77bd91bC738Ed2Efaa262c3763",
"gemJoin": "0xe3692b2E55Eb2494cA73610c3b027F53815CCD39",
"whitelist": "0x7E317f99aA313669AaCDd8dB3927ff3aCB562dAD"
"ionPool": "0x00000000000fA8e0FD26b4554d067CF1856De7F5",
"gemJoin": "0xE890506fe0B9589578a907DbA00250da14603bE6",
"whitelist": "0xE2aA4636448CDB61A25388B23BA10f9675A9b4d9"
}
6 changes: 3 additions & 3 deletions deployment-config/09_DeployLiquidation.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"liquidationThreshold": "960000000000000000000000000",
"maxDiscount": "200000000000000000000000000",
"reserveFactor": "10000000000000000000000000",
"ionPool": "0x00000000008a3A77bd91bC738Ed2Efaa262c3763",
"reserveOracle": "0x3239396B740cD6BBABb42196A03f7B77fA7102C9",
"salt": "0xb54f84bfabde3501ca221f000000000000000000000000000000000000000000"
"ionPool": "0x00000000000fA8e0FD26b4554d067CF1856De7F5",
"reserveOracle": "0x880DFc3E77ae507C37f7F42018B05D5B46d78d70",
"salt": "0x7dbc99ede0e74803aa149e000000000000000000000000000000000000000000"
}
12 changes: 6 additions & 6 deletions deployment-config/10_AdminTransfer.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"ionPool": "0x00000000008a3A77bd91bC738Ed2Efaa262c3763",
"yieldOracle": "0x437CC840e234C2127f54CD59B0B18aF59c586760",
"whitelist": "0x7E317f99aA313669AaCDd8dB3927ff3aCB562dAD",
"proxyAdmin": "91192b4d46d77d013bdee650ad38452ed1da0175",
"liquidation": "0x0000000000d8858E1A9B373582A691dB992C23CA",
"gemJoin": "0xe3692b2E55Eb2494cA73610c3b027F53815CCD39"
"ionPool": "0x00000000000fA8e0FD26b4554d067CF1856De7F5",
"yieldOracle": "0x05f5Fe49e6298169056C1F9B1ea8D8e12A59eE55",
"whitelist": "0xE2aA4636448CDB61A25388B23BA10f9675A9b4d9",
"proxyAdmin": "",
"liquidation": "0x00000000009229776762B5e6b865a06afeB4444c",
"gemJoin": "0xE890506fe0B9589578a907DbA00250da14603bE6"
}
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ remappings = ["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"forge-safe/=lib/forge-safe/src/"]
fs_permissions = [{ access = "read-write", path = "./"}]
optimizer = true
optimizer_runs = 300
optimizer_runs = 200
no_match_contract = "Echidna"
no_match_path = "script/**/*.sol"
gas_reports = ["IonHandler", "IonRegistry", "TransparentUpgradeableProxy", "IonPool", "WstEthHandler", "EthXHandler", "SwEthHandler", "GemJoin", "InterestRate", "Whitelist", "WeEthHandler"]
Expand Down
15 changes: 8 additions & 7 deletions script/deploy/04_DeployIonPool.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,21 @@ contract DeployIonPoolScript is DeployScript {
bytes32 salt = config.readBytes32(".salt");

function createX() public returns (IonPool ionImpl, IonPool ionPool) {
ionImpl = IonPool(config.readAddress(".ionImpl"));
// ionImpl = IonPool(config.readAddress(".ionImpl"));

_validateInterface(IERC20(underlying));
_validateInterface(interestRateModule);
_validateInterface(whitelist);

// ionImpl = IonPool();
_validateInterfaceIonPool(ionImpl);

// if (deployCreate2) {
// ionImpl = new IonPool{ salt: DEFAULT_SALT }();
// } else {
// ionImpl = new IonPool();
// }
if (deployCreate2) {
ionImpl = new IonPool{ salt: DEFAULT_SALT }();
} else {
ionImpl = new IonPool();
}

_validateInterfaceIonPool(ionImpl);

bytes memory initCode = type(TransparentUpgradeableProxy).creationCode;

Expand Down
18 changes: 12 additions & 6 deletions script/deploy/05_DeployInitialReserveAndSpotOracles.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ pragma solidity 0.8.21;

import { DeployScript } from "../Deploy.s.sol";
import { RAY } from "../../src/libraries/math/WadRayMath.sol";
import { EzEthWethReserveOracle } from "./../../src/oracles/reserve/lrt/EzEthWethReserveOracle.sol";
import { EzEthWethSpotOracle } from "./../../src/oracles/spot/lrt/EzEthWethSpotOracle.sol";
import { WeEthWethReserveOracle } from "./../../src/oracles/reserve/lrt/WeEthWethReserveOracle.sol";
import { WeEthWethSpotOracle } from "./../../src/oracles/spot/lrt/WeEthWethSpotOracle.sol";

import { stdJson as StdJson } from "forge-std/StdJson.sol";

Expand All @@ -15,6 +15,7 @@ contract DeployInitialReserveAndSpotOraclesScript is DeployScript {
string config = vm.readFile(configPath);

uint256 maxChange = config.readUint(".maxChange");
uint256 gracePeriod = config.readUint(".gracePeriod");
uint256 ltv = config.readUint(".ltv");

function run() public broadcast returns (address reserveOracle, address spotOracle) {
Expand All @@ -28,13 +29,18 @@ contract DeployInitialReserveAndSpotOraclesScript is DeployScript {
uint256 maxTimeFromLastUpdate = config.readUint(".maxTimeFromLastUpdate");

if (deployCreate2) {
reserveOracle = address(new EzEthWethReserveOracle{ salt: DEFAULT_SALT }(0, new address[](3), 0, maxChange));
reserveOracle = address(
new WeEthWethReserveOracle{ salt: DEFAULT_SALT }(
0, new address[](3), 0, maxChange, maxTimeFromLastUpdate, gracePeriod
)
);
spotOracle = address(
new EzEthWethSpotOracle{ salt: DEFAULT_SALT }(ltv, address(reserveOracle), maxTimeFromLastUpdate)
new WeEthWethSpotOracle{ salt: DEFAULT_SALT }(ltv, address(reserveOracle), maxTimeFromLastUpdate, gracePeriod)
);
} else {
reserveOracle = address(new EzEthWethReserveOracle(0, new address[](3), 0, maxChange));
spotOracle = address(new EzEthWethSpotOracle(ltv, address(reserveOracle), maxTimeFromLastUpdate));
reserveOracle =
address(new WeEthWethReserveOracle(0, new address[](3), 0, maxChange, maxTimeFromLastUpdate, gracePeriod));
spotOracle = address(new WeEthWethSpotOracle(ltv, address(reserveOracle), maxTimeFromLastUpdate, gracePeriod));
}
}
}
12 changes: 6 additions & 6 deletions script/deploy/08_DeployHandlers.s.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

import { MAINNET_WSTETH_WETH_UNISWAP, EZETH_WETH_BALANCER_POOL_ID } from "../../src/Constants.sol";
import { BASE_WEETH_WETH_BALANCER_POOL_ID, BASE_WSTETH_WETH_UNISWAP } from "../../src/Constants.sol";
import { DeployScript } from "../Deploy.s.sol";
import { IonPool } from "../../src/IonPool.sol";
import { GemJoin } from "../../src/join/GemJoin.sol";
import { Whitelist } from "../../src/Whitelist.sol";
import { IonHandlerBase } from "../../src/flash/IonHandlerBase.sol";
import { EzEthWethHandler } from "./../../src/flash/lrt/EzEthWethHandler.sol";
import { WeEthWethHandler } from "./../../src/flash/lrt/WeEthWethHandler.sol";
import { stdJson as StdJson } from "forge-std/StdJson.sol";

// NOTE: Different handlers will have different constructor parameters.
Expand All @@ -28,12 +28,12 @@ contract DeployHandlersScript is DeployScript {
_validateInterfaceIonPool(ionPool);

if (deployCreate2) {
handler = new EzEthWethHandler{ salt: DEFAULT_SALT }(
ILK_INDEX_ZERO, ionPool, gemJoin, whitelist, MAINNET_WSTETH_WETH_UNISWAP, EZETH_WETH_BALANCER_POOL_ID
handler = new WeEthWethHandler{ salt: DEFAULT_SALT }(
ILK_INDEX_ZERO, ionPool, gemJoin, whitelist, BASE_WSTETH_WETH_UNISWAP, BASE_WEETH_WETH_BALANCER_POOL_ID
);
} else {
handler = new EzEthWethHandler{ salt: DEFAULT_SALT }(
ILK_INDEX_ZERO, ionPool, gemJoin, whitelist, MAINNET_WSTETH_WETH_UNISWAP, EZETH_WETH_BALANCER_POOL_ID
handler = new WeEthWethHandler{ salt: DEFAULT_SALT }(
ILK_INDEX_ZERO, ionPool, gemJoin, whitelist, BASE_WSTETH_WETH_UNISWAP, BASE_WEETH_WETH_BALANCER_POOL_ID
);
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { ICreateX } from "./interfaces/ICreateX.sol";
import { IPMarketV3 } from "pendle-core-v2-public/interfaces/IPMarketV3.sol";

import { IUniswapV3Pool } from "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
import { IERC20 } from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";

uint8 constant REDSTONE_DECIMALS = 8;

Expand All @@ -53,6 +54,8 @@ IEtherFiLiquidityPool constant ETHER_FI_LIQUIDITY_POOL_ADDRESS =
IWeEth constant WEETH_ADDRESS = IWeEth(0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee);
IRedstonePriceFeed constant REDSTONE_WEETH_ETH_PRICE_FEED =
IRedstonePriceFeed(0x8751F736E94F6CD167e8C5B97E245680FbD9CC36);
IChainlink constant BASE_WEETH_ETH_PRICE_CHAINLINK = IChainlink(0xFC1415403EbB0c693f9a7844b92aD2Ff24775C65);
IChainlink constant BASE_WEETH_ETH_EXCHANGE_RATE_CHAINLINK = IChainlink(0x35e9D7001819Ea3B39Da906aE6b06A62cfe2c181);

jpick713 marked this conversation as resolved.
Show resolved Hide resolved
// rsETH
IRedstonePriceFeed constant REDSTONE_RSETH_ETH_PRICE_FEED =
Expand Down Expand Up @@ -97,3 +100,12 @@ IPMarketV3 constant PT_RSWETH_POOL = IPMarketV3(0x1729981345aa5CaCdc19eA9eeffea9

// CreateX
ICreateX constant CREATEX = ICreateX(0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed);

// --- BASE ---

// EtherFi
bytes32 constant BASE_WEETH_WETH_BALANCER_POOL_ID = 0xab99a3e856deb448ed99713dfce62f937e2d4d74000000000000000000000118;
IUniswapV3Pool constant BASE_WSTETH_WETH_UNISWAP = IUniswapV3Pool(0x20E068D76f9E90b90604500B84c7e19dCB923e7e);
IChainlink constant BASE_SEQUENCER_UPTIME_FEED = IChainlink(0xBCF85224fc0756B9Fa45aA7892530B47e10b6433);
IERC20 constant BASE_WEETH = IERC20(0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A);
IERC20 constant BASE_WETH = IERC20(0x4200000000000000000000000000000000000006);
19 changes: 9 additions & 10 deletions src/flash/UniswapFlashloanBalancerSwapHandler.sol

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be worth making weth an immutable value and passing the address in as a constructor arg?

I think it's a bit dangerous leaving this to be hardcoded when deploying on BASE vs other networks

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried looking into if Uniswap has a WETH() function too, and unfortunately in V3 it does not

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IonHandlerBase now takes in weth as a constructor arg to set it as an immutable.

Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,15 @@ abstract contract UniswapFlashloanBalancerSwapHandler is IUniswapV3FlashCallback
* swaps.
*/
constructor(IUniswapV3Pool _flashloanPool, bytes32 _balancerPoolId) {
address weth = address(WETH);
IERC20(weth).approve(address(VAULT), type(uint256).max);
BASE.approve(address(VAULT), type(uint256).max);
IERC20(address(LST_TOKEN)).approve(address(VAULT), type(uint256).max);

FLASHLOAN_POOL = _flashloanPool;
address token0 = IUniswapV3Pool(_flashloanPool).token0();
address token1 = IUniswapV3Pool(_flashloanPool).token1();

bool _wethIsToken0 = token0 == weth;
bool _wethIsToken1 = token1 == weth;
bool _wethIsToken0 = token0 == address(BASE);
bool _wethIsToken1 = token1 == address(BASE);

if (!_wethIsToken0 && !_wethIsToken1) revert WethNotInPoolPair(_flashloanPool);

Expand Down Expand Up @@ -123,7 +122,7 @@ abstract contract UniswapFlashloanBalancerSwapHandler is IUniswapV3FlashCallback
// the value from the flashloan.
uint256 wethIn = _simulateGivenOutBalancerSwap({
fundManagement: fundManagement,
assetIn: address(WETH),
assetIn: address(BASE),
assetOut: address(LST_TOKEN),
amountOut: amountToLeverage
});
Expand Down Expand Up @@ -257,7 +256,7 @@ abstract contract UniswapFlashloanBalancerSwapHandler is IUniswapV3FlashCallback
IVault.SingleSwap memory balancerSwap = IVault.SingleSwap({
poolId: bytes32(BALANCER_POOL_ID),
kind: IVault.SwapKind.GIVEN_OUT,
assetIn: IAsset(address(WETH)),
assetIn: IAsset(address(BASE)),
assetOut: IAsset(address(LST_TOKEN)),
amount: amountToLeverage,
userData: ""
Expand All @@ -275,15 +274,15 @@ abstract contract UniswapFlashloanBalancerSwapHandler is IUniswapV3FlashCallback
uint256 totalCollateral = flashCallbackData.initialDeposit + amountToLeverage;
_depositAndBorrow(user, address(this), totalCollateral, wethToRepay, AmountToBorrow.IS_MIN);

WETH.safeTransfer(msg.sender, wethToRepay);
BASE.safeTransfer(msg.sender, wethToRepay);
} else {
// When deleveraging
uint256 totalRepayment = flashCallbackData.wethFlashloaned + fee;

uint256 collateralIn = _simulateGivenOutBalancerSwap({
fundManagement: fundManagement,
assetIn: address(LST_TOKEN),
assetOut: address(WETH),
assetOut: address(BASE),
amountOut: totalRepayment
});

Expand All @@ -298,14 +297,14 @@ abstract contract UniswapFlashloanBalancerSwapHandler is IUniswapV3FlashCallback
poolId: bytes32(BALANCER_POOL_ID),
kind: IVault.SwapKind.GIVEN_OUT,
assetIn: IAsset(address(LST_TOKEN)),
assetOut: IAsset(address(WETH)),
assetOut: IAsset(address(BASE)),
amount: totalRepayment,
userData: ""
});

VAULT.swap(balancerSwap, fundManagement, type(uint256).max, block.timestamp + 1);

WETH.safeTransfer(msg.sender, totalRepayment);
BASE.safeTransfer(msg.sender, totalRepayment);
}
}

Expand Down
37 changes: 37 additions & 0 deletions src/flash/lrt/WeEthWethHandler.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

import { IonPool } from "../../IonPool.sol";
import { GemJoin } from "../../join/GemJoin.sol";
import { Whitelist } from "../../Whitelist.sol";
import { IonHandlerBase } from "../IonHandlerBase.sol";
import { UniswapFlashloanBalancerSwapHandler } from "./../UniswapFlashloanBalancerSwapHandler.sol";
import { IUniswapV3Pool } from "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";

/**
* @notice Handler for the weETH collateral in the weETH/WETH market.
*
* @custom:security-contact security@molecularlabs.io
*/
contract WeEthWethHandler is UniswapFlashloanBalancerSwapHandler {
/**
* @notice Creates a new `WeEthWethHandler` instance.
* @param _ilkIndex Ilk index of the pool.
* @param _ionPool address.
* @param _gemJoin address.
* @param _whitelist address.
* @param _wstEthUniswapPool address of the wstETH/WETH Uniswap pool
* @param _balancerPoolId Balancer pool ID for the weETH/WETH pool.
*/
constructor(
uint8 _ilkIndex,
IonPool _ionPool,
GemJoin _gemJoin,
Whitelist _whitelist,
IUniswapV3Pool _wstEthUniswapPool,
bytes32 _balancerPoolId
)
IonHandlerBase(_ilkIndex, _ionPool, _gemJoin, _whitelist)
UniswapFlashloanBalancerSwapHandler(_wstEthUniswapPool, _balancerPoolId)
{ }
}
Loading
Loading