Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deployment-config/00_Default.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"initialDefaultAdmin": "0x94544835Cf97c631f101c5f538787fE14E2E04f6",
"protocol": "0xE5a5F3A6C88B894710992e1C2626be0DEB99566E",
"ilkAddress": "0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A"
"ilkAddress": "0x2416092f143378750bb29b79eD961ab195CcEea5"
}
7 changes: 4 additions & 3 deletions deployment-config/04_DeployIonPool.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
"underlying": "0x4200000000000000000000000000000000000006",
"treasury": "0xE5a5F3A6C88B894710992e1C2626be0DEB99566E",
"decimals": "18",
"name": "Ion weETH WETH Token",
"symbol": "iweETH-WETH",
"name": "Ion ezETH WETH Token",
"symbol": "iezETH-WETH",
"whitelist": "0xf98248f0dA9D51d827A3C42d608acF65c77BD76A",
"interestRateModule": "0x7BC91582b10c3ce83be1918daE5136B59FC55e01",
"salt": "0xa53bcb7572e19b03e4aae7000000000000000000000000000000000000000000"
"salt": "0xeba688b6a0169602b0f4c5000000000000000000000000000000000000000000",
"ionImpl": "0xB1F7395E72B0045600c946afAB7e44cB35A6EB9B"
}
4 changes: 2 additions & 2 deletions deployment-config/06_SetupCollateral.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ionPool": "0x00000000000fA8e0FD26b4554d067CF1856De7F5",
"spotOracle": "0x5D83953248cbF1FF723978FbD3490D9a2385A52d",
"ionPool": "0x000000000054D04Bd84f465ae7aD3aC39072255D",
"spotOracle": "0x1B39e88465e097FDB5d4E4BEad3d88655786ac07",
"debtCeiling": "000000000000000000000000000000000000000000000000",
"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": "0x00000000000fA8e0FD26b4554d067CF1856De7F5"
"ionPool": "0x000000000054D04Bd84f465ae7aD3aC39072255D"
}
4 changes: 2 additions & 2 deletions deployment-config/08_DeployHandlers.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"ionPool": "0x00000000000fA8e0FD26b4554d067CF1856De7F5",
"gemJoin": "0xe21ae2d45dEDF8dEE2D854774a904d33b8700E78",
"ionPool": "0x000000000054D04Bd84f465ae7aD3aC39072255D",
"gemJoin": "0x177DAaA9aA0ab22E4B84f32B3A01d9dD57728253",
"whitelist": "0xf98248f0dA9D51d827A3C42d608acF65c77BD76A"
}
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": "0x00000000000fA8e0FD26b4554d067CF1856De7F5",
"reserveOracle": "0x39c66dEAA7BA7576ed1498C5A0601454740e386C",
"salt": "0x7dbc99ede0e74803aa149e000000000000000000000000000000000000000000"
"ionPool": "0x000000000054D04Bd84f465ae7aD3aC39072255D",
"reserveOracle": "0xcce76ed19a17380d1a5E90adD25317F70650D92b",
"salt": "0x2aa182b96665000197a6b5000000000000000000000000000000000000000000"
}
8 changes: 4 additions & 4 deletions deployment-config/10_AdminTransfer.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"ionPool": "0x00000000000fA8e0FD26b4554d067CF1856De7F5",
"ionPool": "0x000000000054D04Bd84f465ae7aD3aC39072255D",
"yieldOracle": "0x2CAe5eD3b35654499EE605cD66A9b14a0d053773",
"whitelist": "0xf98248f0dA9D51d827A3C42d608acF65c77BD76A",
"proxyAdmin": "0xe559662C42FF6460BE7c7f0C67aBA789Fde53861",
"liquidation": "0x00000000009229776762B5e6b865a06afeB4444c",
"gemJoin": "0xe21ae2d45dEDF8dEE2D854774a904d33b8700E78"
"proxyAdmin": "0xb475DcdD1C820b6B9c2f03a31C298d0722a1E27C",
"liquidation": "0x0000000000B0874413358bf8E80855f67CEE5C2a",
"gemJoin": "0x177DAaA9aA0ab22E4B84f32B3A01d9dD57728253"
}
2 changes: 1 addition & 1 deletion script/deploy-test/10_AdminTransfer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ contract DeployAdminTransferTest is DeployTestBase, AdminTransferScript {
assertLe(addressSchedule, block.timestamp, "address schedule");

// assertEq(yieldOracle.pendingOwner(), protocol, "yield oracle pending owner");
assertEq(whitelist.pendingOwner(), protocol, "whitelist pending owner");
// assertEq(whitelist.pendingOwner(), protocol, "whitelist pending owner");
assertEq(proxyAdmin.pendingOwner(), protocol, "proxy admin pending owner");
assertTrue(ionPool.hasRole(ionPool.GEM_JOIN_ROLE(), address(gemJoin)), "gem join role");
assertTrue(ionPool.hasRole(ionPool.LIQUIDATOR_ROLE(), address(liquidation)), "gem join role");
Expand Down
12 changes: 6 additions & 6 deletions script/deploy/04_DeployIonPool.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@ 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();

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);

Expand Down
12 changes: 6 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 { WeEthWethReserveOracle } from "./../../src/oracles/reserve/lrt/WeEthWethReserveOracle.sol";
import { WeEthWethSpotOracle } from "./../../src/oracles/spot/lrt/WeEthWethSpotOracle.sol";
import { BaseEzEthWethReserveOracle } from "./../../src/oracles/reserve/lrt/base/BaseEzEthWethReserveOracle.sol";
import { BaseEzEthWethSpotOracle } from "./../../src/oracles/spot/lrt/base/BaseEzEthWethSpotOracle.sol";

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

Expand All @@ -30,21 +30,21 @@ contract DeployInitialReserveAndSpotOraclesScript is DeployScript {

if (deployCreate2) {
reserveOracle = address(
new WeEthWethReserveOracle{ salt: DEFAULT_SALT }(
new BaseEzEthWethReserveOracle{ salt: DEFAULT_SALT }(
0, new address[](3), 0, maxChange, maxTimeFromLastUpdate, gracePeriod
)
);
spotOracle = address(
new WeEthWethSpotOracle{ salt: DEFAULT_SALT }(
new BaseEzEthWethSpotOracle{ salt: DEFAULT_SALT }(
ltv, address(reserveOracle), maxTimeFromLastUpdate, gracePeriod
)
);
} else {
reserveOracle = address(
new WeEthWethReserveOracle(0, new address[](3), 0, maxChange, maxTimeFromLastUpdate, gracePeriod)
new BaseEzEthWethReserveOracle(0, new address[](3), 0, maxChange, maxTimeFromLastUpdate, gracePeriod)
);
spotOracle =
address(new WeEthWethSpotOracle(ltv, address(reserveOracle), maxTimeFromLastUpdate, gracePeriod));
address(new BaseEzEthWethSpotOracle(ltv, address(reserveOracle), maxTimeFromLastUpdate, gracePeriod));
}
}
}
24 changes: 6 additions & 18 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 { BASE_WETH, BASE_WEETH_WETH_BALANCER_POOL_ID, BASE_WSTETH_WETH_UNISWAP } from "../../src/Constants.sol";
import { BASE_WETH, BASE_EZETH_WETH_AERODROME } 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 { WeEthWethHandler } from "./../../src/flash/lrt/WeEthWethHandler.sol";
import { BaseEzEthWethHandler } from "./../../src/flash/lrt/base/BaseEzEthWethHandler.sol";
import { stdJson as StdJson } from "forge-std/StdJson.sol";

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

if (deployCreate2) {
handler = new WeEthWethHandler{ salt: DEFAULT_SALT }(
ILK_INDEX_ZERO,
ionPool,
gemJoin,
whitelist,
BASE_WSTETH_WETH_UNISWAP,
BASE_WEETH_WETH_BALANCER_POOL_ID,
BASE_WETH
handler = new BaseEzEthWethHandler{ salt: DEFAULT_SALT }(
ILK_INDEX_ZERO, ionPool, gemJoin, whitelist, BASE_EZETH_WETH_AERODROME, false, BASE_WETH
);
} else {
handler = new WeEthWethHandler{ salt: DEFAULT_SALT }(
ILK_INDEX_ZERO,
ionPool,
gemJoin,
whitelist,
BASE_WSTETH_WETH_UNISWAP,
BASE_WEETH_WETH_BALANCER_POOL_ID,
BASE_WETH
handler = new BaseEzEthWethHandler(
ILK_INDEX_ZERO, ionPool, gemJoin, whitelist, BASE_EZETH_WETH_AERODROME, false, BASE_WETH
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion script/deploy/10_AdminTransfer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ contract AdminTransferScript is DeployScript {

ionPool.beginDefaultAdminTransfer(protocol);
// yieldOracle.transferOwnership(protocol);
whitelist.transferOwnership(protocol);
// whitelist.transferOwnership(protocol);
proxyAdmin.transferOwnership(protocol);
}
}
6 changes: 6 additions & 0 deletions src/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,9 @@ IUniswapV3Pool constant BASE_WSTETH_WETH_UNISWAP = IUniswapV3Pool(0x20E068D76f9E
IChainlink constant BASE_SEQUENCER_UPTIME_FEED = IChainlink(0xBCF85224fc0756B9Fa45aA7892530B47e10b6433);
IERC20 constant BASE_WEETH = IERC20(0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A);
IWETH9 constant BASE_WETH = IWETH9(0x4200000000000000000000000000000000000006);

// Renzo
IERC20 constant BASE_EZETH = IERC20(0x2416092f143378750bb29b79eD961ab195CcEea5);
IUniswapV3Pool constant BASE_EZETH_WETH_AERODROME = IUniswapV3Pool(0xDC7EAd706795eDa3FEDa08Ad519d9452BAdF2C0d);
IChainlink constant BASE_EZETH_ETH_EXCHANGE_RATE_CHAINLINK = IChainlink(0xC4300B7CF0646F0Fe4C5B2ACFCCC4dCA1346f5d8);
IChainlink constant BASE_EZETH_ETH_PRICE_CHAINLINK = IChainlink(0x960BDD1dFD20d7c98fa482D793C3dedD73A113a3);
41 changes: 41 additions & 0 deletions src/flash/lrt/base/BaseEzEthWethHandler.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

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

/**
* @notice Handler for the ezETH collateral in the ezETH/WETH market on Base.
*
* @custom:security-contact security@molecularlabs.io
*/
contract BaseEzEthWethHandler is UniswapFlashswapHandler {
/**
* @notice Creates a new `EzEthWethHandler` instance.
* @param _ilkIndex Ilk index of the pool.
* @param _ionPool address.
* @param _gemJoin address.
* @param _whitelist address.
* @param _pool address of the ezETH/WETH Aerodrome pool.
* @param _wethIsToken0 Whether WETH is token0 or token1.
* @param _weth The WETH address of this chain.
*/
constructor(
uint8 _ilkIndex,
IonPool _ionPool,
GemJoin _gemJoin,
Whitelist _whitelist,
IUniswapV3Pool _pool,
bool _wethIsToken0,
IWETH9 _weth
)
IonHandlerBase(_ilkIndex, _ionPool, _gemJoin, _whitelist, _weth)
UniswapFlashswapHandler(_pool, _wethIsToken0)
{ }
}
71 changes: 71 additions & 0 deletions src/oracles/reserve/lrt/base/BaseEzEthWethReserveOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

import { WadRayMath } from "../../../../libraries/math/WadRayMath.sol";
import { ReserveOracle } from "../../ReserveOracle.sol";
import { BASE_EZETH_ETH_EXCHANGE_RATE_CHAINLINK, BASE_SEQUENCER_UPTIME_FEED } from "../../../../Constants.sol";
import { SafeCast } from "openzeppelin-contracts/contracts/utils/math/SafeCast.sol";

/**
* @notice Reserve Oracle for ezETH denominated in WETH.
*
* @custom:security-contact security@molecularlabs.io
*/
contract BaseEzEthWethReserveOracle is ReserveOracle {
using WadRayMath for uint256;
using SafeCast for int256;

error SequencerDown();
error GracePeriodNotOver();
error MaxTimeFromLastUpdateExceeded(uint256, uint256);

uint256 public immutable MAX_TIME_FROM_LAST_UPDATE; // seconds
uint256 public immutable GRACE_PERIOD;

/**
* @notice Creates a new `BaseEzEthWethReserveOracle` instance. Provides
* the amount of WETH equal to one ezETH (ETH / ezETH).
* @dev The value of ezETH denominated in WETH by Chainlink.
* @param _feeds List of alternative data sources for the WETH/ezETH exchange rate.
* @param _quorum The amount of alternative data sources to aggregate.
* @param _maxChange Maximum percent change between exchange rate updates. [RAY]
*/
constructor(
uint8 _ilkIndex,
address[] memory _feeds,
uint8 _quorum,
uint256 _maxChange,
uint256 _maxTimeFromLastUpdate,
uint256 _gracePeriod
)
ReserveOracle(_ilkIndex, _feeds, _quorum, _maxChange)
{
MAX_TIME_FROM_LAST_UPDATE = _maxTimeFromLastUpdate;
GRACE_PERIOD = _gracePeriod;
_initializeExchangeRate();
}

function _getProtocolExchangeRate() internal view override returns (uint256) {
(
/*uint80 roundID*/
,
int256 answer,
uint256 startedAt,
/*uint256 updatedAt*/
,
/*uint80 answeredInRound*/
) = BASE_SEQUENCER_UPTIME_FEED.latestRoundData();

if (answer == 1) revert SequencerDown();
if (block.timestamp - startedAt <= GRACE_PERIOD) revert GracePeriodNotOver();

(, int256 ethPerEzEth,, uint256 ethPerEzEthUpdatedAt,) =
BASE_EZETH_ETH_EXCHANGE_RATE_CHAINLINK.latestRoundData();

if (block.timestamp - ethPerEzEthUpdatedAt > MAX_TIME_FROM_LAST_UPDATE) {
revert MaxTimeFromLastUpdateExceeded(block.timestamp - ethPerEzEthUpdatedAt, MAX_TIME_FROM_LAST_UPDATE);
} else {
return ethPerEzEth.toUint256();
}
}
}
Loading