From f97df58531c26a9b594ffd0a57eac8e1a735e0a4 Mon Sep 17 00:00:00 2001 From: Jun Kim <64379343+junkim012@users.noreply.github.com> Date: Thu, 9 May 2024 16:42:26 -0400 Subject: [PATCH] feat: script for redeploying the spot oracle for LTV updates, more irm deploy checks --- deployment-config/00_Default.json | 2 +- .../02_DeployInterestRateModule.json | 8 ++-- deployment-config/09_DeployLiquidation.json | 4 +- deployment-config/11_RedeploySpotOracle.json | 6 +++ package.json | 8 +++- .../deploy-test/11_RedeploySpotOracle.t.sol | 22 ++++++++++ .../deploy/02_DeployInterestRateModule.s.sol | 27 ++++++++++--- script/deploy/11_RedeploySpotOracle.s.sol | 40 +++++++++++++++++++ 8 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 deployment-config/11_RedeploySpotOracle.json create mode 100644 script/deploy-test/11_RedeploySpotOracle.t.sol create mode 100644 script/deploy/11_RedeploySpotOracle.s.sol diff --git a/deployment-config/00_Default.json b/deployment-config/00_Default.json index 7e4541a3..8875f704 100644 --- a/deployment-config/00_Default.json +++ b/deployment-config/00_Default.json @@ -1,5 +1,5 @@ { "initialDefaultAdmin": "0x01bd9aBD70D74D8eC70D338bD6099ca29DA3F9B4", "protocol": "0x0000000000417626Ef34D62C4DC189b021603f2F", - "ilkAddress": "0xFAe103DC9cf190eD75350761e95403b7b8aFa6c0" + "ilkAddress": "0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7" } diff --git a/deployment-config/02_DeployInterestRateModule.json b/deployment-config/02_DeployInterestRateModule.json index 82bc8d09..b63240b5 100644 --- a/deployment-config/02_DeployInterestRateModule.json +++ b/deployment-config/02_DeployInterestRateModule.json @@ -1,13 +1,13 @@ { "ilkData": { "adjustedProfitMargin": "0", - "minimumKinkRate": "4062570058138700000", + "minimumKinkRate": "3030912926100000000", "reserveFactor": "0", "adjustedBaseRate": "0", - "minimumBaseRate": "1580630071273960000", - "optimalUtilizationRate": "8500", + "minimumBaseRate": "860244400000000000", + "optimalUtilizationRate": "9000", "adjustedAboveKinkSlope": "0", - "minimumAboveKinkSlope": "23863999665252300000" + "minimumAboveKinkSlope": "73381553300000000000" }, "yieldOracleAddress": "0x437CC840e234C2127f54CD59B0B18aF59c586760" } diff --git a/deployment-config/09_DeployLiquidation.json b/deployment-config/09_DeployLiquidation.json index 9e7bf8dd..12a19432 100644 --- a/deployment-config/09_DeployLiquidation.json +++ b/deployment-config/09_DeployLiquidation.json @@ -1,9 +1,9 @@ { "targetHealth": "1200000000000000000000000000", - "liquidationThreshold": "900000000000000000000000000", + "liquidationThreshold": "960000000000000000000000000", "maxDiscount": "200000000000000000000000000", "reserveFactor": "10000000000000000000000000", "ionPool": "0x00000000007C8105548f9d0eE081987378a6bE93", "reserveOracle": "0xAAa88236D483f08003493adbbf451373992f2f58", - "salt": "0x01bd9abd70d74d8ec70d338bd6099ca29da3f9b4005cafa1b6cefd1e01e924d6" + "salt": "0x01bd9abd70d74d8ec70d338bd6099ca29da3f9b4002d932cfb5726e503d4baa8" } diff --git a/deployment-config/11_RedeploySpotOracle.json b/deployment-config/11_RedeploySpotOracle.json new file mode 100644 index 00000000..31759f3d --- /dev/null +++ b/deployment-config/11_RedeploySpotOracle.json @@ -0,0 +1,6 @@ +{ + "ltv": "930000000000000000000000000", + "reserveOracle": "0xAAa88236D483f08003493adbbf451373992f2f58", + "maxTimeFromLastUpdate": "86400" +} + \ No newline at end of file diff --git a/package.json b/package.json index 893b2da9..185fee68 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,13 @@ "10_AdminTransfer:deployment:deploy:anvil": "forge script script/deploy/10_AdminTransfer.s.sol --rpc-url http://localhost:8545 --private-key $PRIVATE_KEY --slow", "10_AdminTransfer:deployment:deploy:tenderly": "forge script script/deploy/10_AdminTransfer.s.sol --rpc-url $TENDERLY_RPC_URL --private-key $PRIVATE_KEY --slow", "10_AdminTransfer:deployment:deploy:sepolia": "forge script script/deploy/10_AdminTransfer.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --slow", - "10_AdminTransfer:deployment:deploy:mainnet": "forge script script/deploy/10_AdminTransfer.s.sol --rpc-url $MAINNET_RPC_URL --private-key $PRIVATE_KEY --slow" + "10_AdminTransfer:deployment:deploy:mainnet": "forge script script/deploy/10_AdminTransfer.s.sol --rpc-url $MAINNET_RPC_URL --private-key $PRIVATE_KEY --slow", + + "11_RedeploySpotOracle:deployment:test": "forge test --mc RedeploySpotOracleTest --nmp \"\"", + "11_RedeploySpotOracle:deployment:deploy:anvil": "forge script script/deploy/11_RedeploySpotOracle.s.sol --rpc-url http://localhost:8545 --private-key $PRIVATE_KEY --slow", + "11_RedeploySpotOracle:deployment:deploy:tenderly": "forge script script/deploy/11_RedeploySpotOracle.s.sol --rpc-url $TENDERLY_RPC_URL --private-key $PRIVATE_KEY --slow", + "11_RedeploySpotOracle:deployment:deploy:sepolia": "forge script script/deploy/11_RedeploySpotOracle.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --slow", + "11_RedeploySpotOracle:deployment:deploy:mainnet": "forge script script/deploy/11_RedeploySpotOracle.s.sol --rpc-url $MAINNET_RPC_URL --private-key $PRIVATE_KEY --slow" }, "dependencies": { "date-fns": "^2.30.0", diff --git a/script/deploy-test/11_RedeploySpotOracle.t.sol b/script/deploy-test/11_RedeploySpotOracle.t.sol new file mode 100644 index 00000000..6e37d2fc --- /dev/null +++ b/script/deploy-test/11_RedeploySpotOracle.t.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.21; + +import { ReserveOracle } from "../../src/oracles/reserve/ReserveOracle.sol"; +import { SpotOracle } from "../../src/oracles/spot/SpotOracle.sol"; +import { DeployTestBase } from "./00_DeployTestBase.t.sol"; +import { RedeploySpotOracleScript } from "../deploy/11_RedeploySpotOracle.s.sol"; + +contract RedeploySpotOracleTest is DeployTestBase, RedeploySpotOracleScript { + function checkState(SpotOracle spotOracle) public { + assertGt(address(spotOracle).code.length, 0, "spot oracle code"); + assertEq(spotOracle.LTV(), ltv, "spot oracle ltv"); + assertEq(address(spotOracle.RESERVE_ORACLE()), address(reserveOracle), "spot oracle reserve oracle"); + assertGt(spotOracle.getPrice(), 0, "spot oracle get price"); + assertGt(spotOracle.getSpot(), 0, "spot oracle get spot"); + } + + function test_PreExecution() public { + (SpotOracle spotOracle) = super.run(); + checkState(spotOracle); + } +} diff --git a/script/deploy/02_DeployInterestRateModule.s.sol b/script/deploy/02_DeployInterestRateModule.s.sol index 53356abf..8e3e18a8 100644 --- a/script/deploy/02_DeployInterestRateModule.s.sol +++ b/script/deploy/02_DeployInterestRateModule.s.sol @@ -10,7 +10,7 @@ import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import { stdJson as StdJson } from "forge-std/StdJson.sol"; -import { safeconsole as console } from "forge-std/safeconsole.sol"; +import { console2 } from "forge-std/console2.sol"; // struct IlkData { // // Word 1 @@ -78,13 +78,30 @@ contract DeployInterestRateScript is DeployScript { interestRateModule = new InterestRate(ilkDataList, yieldOracle); } + (uint256 zeroUtilRate,) = interestRateModule.calculateInterestRate(0, 0, 100e18); + zeroUtilRate += 1e27; + + uint256 annualZeroUtilRate = _rpow(zeroUtilRate, 31_536_000, 1e27); + + uint256 optimalUtilTotalIlkDebt = uint256(optimalUtilizationRate) * 100e18 / 1e4 * 1e27; + (uint256 optimalUtilRate,) = interestRateModule.calculateInterestRate(0, 90e45, 100e18); + optimalUtilRate += 1e27; + + uint256 annualOptimalUtilRate = _rpow(optimalUtilRate, 31_536_000, 1e27); + // Get the borrow rate at a 100% utilization rate - (uint256 borrowRate,) = interestRateModule.calculateInterestRate(0, 100e45, 100e18); - borrowRate += 1e27; + (uint256 maxUtilRate,) = interestRateModule.calculateInterestRate(0, 100e45, 100e18); + maxUtilRate += 1e27; + + uint256 annualMaxUtilRate = _rpow(maxUtilRate, 31_536_000, 1e27); - uint256 annualInterestRate = _rpow(borrowRate, 31_536_000, 1e27); + console2.log("annual zero utilization rate: ", annualZeroUtilRate); + console2.log("annual optimal utilization rate: ", annualOptimalUtilRate); + console2.log("annual max utilization rate: ", annualMaxUtilRate); - require(annualInterestRate < 1.3e27, "Interest rate too high"); + require(annualZeroUtilRate < 1.1e27, "Annual zero utilization rate too high"); + require(annualOptimalUtilRate < 1.2e27, "Annual optimal utilization rate too high"); + require(annualMaxUtilRate < 1.4e27, "Annual max utilization rate too high"); } function _rpow(uint256 x, uint256 n, uint256 b) internal pure returns (uint256 z) { diff --git a/script/deploy/11_RedeploySpotOracle.s.sol b/script/deploy/11_RedeploySpotOracle.s.sol new file mode 100644 index 00000000..82b33cd4 --- /dev/null +++ b/script/deploy/11_RedeploySpotOracle.s.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.21; + +import { DeployScript } from "../Deploy.s.sol"; +import { RAY } from "../../src/libraries/math/WadRayMath.sol"; +import { SpotOracle } from "./../../src/oracles/spot/SpotOracle.sol"; +import { WeEthWstEthSpotOracle } from "../../src/oracles/spot/lrt/WeEthWstEthSpotOracle.sol"; +import { RsEthWstEthSpotOracle } from "./../../src/oracles/spot/lrt/RsEthWstEthSpotOracle.sol"; +import { RswEthWstEthSpotOracle } from "./../../src/oracles/spot/lrt/RswEthWstEthSpotOracle.sol"; +import { stdJson as StdJson } from "forge-std/StdJson.sol"; + +import { console2 } from "forge-std/console2.sol"; + +// NOTE ALWAYS CHECK WHETHER THE CORRECT CONTRACT IS BEING DEPLOYED +contract RedeploySpotOracleScript is DeployScript { + using StdJson for string; + + string configPath = "./deployment-config/11_RedeploySpotOracle.json"; + string config = vm.readFile(configPath); + + uint256 ltv = config.readUint(".ltv"); + address reserveOracle = config.readAddress(".reserveOracle"); + + function run() public broadcast returns (SpotOracle spotOracle) { + require(ltv > 0.2e27, "ltv must be greater than 20%"); + require(ltv < RAY, "ltv must be less than 100%"); + + // Specific to using Redstone Oracles + uint256 maxTimeFromLastUpdate = config.readUint(".maxTimeFromLastUpdate"); + + if (deployCreate2) { + spotOracle = + new RswEthWstEthSpotOracle{ salt: DEFAULT_SALT }(ltv, address(reserveOracle), maxTimeFromLastUpdate); + } else { + spotOracle = new RswEthWstEthSpotOracle(ltv, address(reserveOracle), maxTimeFromLastUpdate); + } + + console2.log("address(spotOracle): ", address(spotOracle)); + } +}