From c03225fbd1892f72d742c51a3597d63f171e610d Mon Sep 17 00:00:00 2001 From: Fermin 'Piscu' Carranza Date: Thu, 28 Mar 2024 10:02:52 -0400 Subject: [PATCH] GHO Borrow Rate Update (#271) * feat: update gho borrow rate * chore: add assets * chore: update block * Update GHOStewardsBorrowRateUpdate.md * chore: re run tests and update image --- ...3ba99310cd56d74318156592f9f533d1e81dde.svg | 1 + ...StewardsBorrowRateUpdate_20240324_after.md | 38 +++++++++ ...m_GHOStewardsBorrowRateUpdate_20240324.sol | 26 ++++++ ...GHOStewardsBorrowRateUpdate_20240324.t.sol | 45 ++++++++++ .../GHOStewardsBorrowRateUpdate.md | 35 ++++++++ ...GHOStewardsBorrowRateUpdate_20240324.s.sol | 79 ++++++++++++++++++ .../GhoInterestRateStrategy.sol | 82 +++++++++++++++++++ .../config.ts | 14 ++++ 8 files changed, 320 insertions(+) create mode 100644 .assets/233ba99310cd56d74318156592f9f533d1e81dde.svg create mode 100644 diffs/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324_before_AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324_after.md create mode 100644 src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.sol create mode 100644 src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.t.sol create mode 100644 src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate.md create mode 100644 src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate_20240324.s.sol create mode 100644 src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GhoInterestRateStrategy.sol create mode 100644 src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/config.ts diff --git a/.assets/233ba99310cd56d74318156592f9f533d1e81dde.svg b/.assets/233ba99310cd56d74318156592f9f533d1e81dde.svg new file mode 100644 index 000000000..78b4d158b --- /dev/null +++ b/.assets/233ba99310cd56d74318156592f9f533d1e81dde.svg @@ -0,0 +1 @@ + Borrow APR, variableBorrow APR, stable0%25%50%75%100%0%5%10%15%uOptimal 0%uOptimal 0% \ No newline at end of file diff --git a/diffs/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324_before_AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324_after.md b/diffs/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324_before_AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324_after.md new file mode 100644 index 000000000..36931eb13 --- /dev/null +++ b/diffs/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324_before_AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324_after.md @@ -0,0 +1,38 @@ +## Reserve changes + +### Reserves altered + +#### GHO ([0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f](https://etherscan.io/address/0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f)) + +| description | value before | value after | +| --- | --- | --- | +| interestRateStrategy | [0x2f6390Ef66B8564C715aF6834361621dda38d816](https://etherscan.io/address/0x2f6390Ef66B8564C715aF6834361621dda38d816) | [0x7123138CB4891E9dA927492ce29c8a2eC4aB433A](https://etherscan.io/address/0x7123138CB4891E9dA927492ce29c8a2eC4aB433A) | +| baseVariableBorrowRate | 7.92 % | 13 % | +| interestRate | ![before](/.assets/8f4bd9d9c75dc060033b9ce1f2681ecb81e1b33f.svg) | ![after](/.assets/233ba99310cd56d74318156592f9f533d1e81dde.svg) | + +## Raw diff + +```json +{ + "reserves": { + "0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f": { + "interestRateStrategy": { + "from": "0x2f6390Ef66B8564C715aF6834361621dda38d816", + "to": "0x7123138CB4891E9dA927492ce29c8a2eC4aB433A" + } + } + }, + "strategies": { + "0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f": { + "address": { + "from": "0x2f6390Ef66B8564C715aF6834361621dda38d816", + "to": "0x7123138CB4891E9dA927492ce29c8a2eC4aB433A" + }, + "baseVariableBorrowRate": { + "from": "79200000000000000000000000", + "to": "130000000000000000000000000" + } + } + } +} +``` \ No newline at end of file diff --git a/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.sol b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.sol new file mode 100644 index 000000000..2e77c733d --- /dev/null +++ b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; + +/** + * @title GHO Borrow Rate Update + * @author karpatkey_TokenLogic & ACI & ChaosLabs + * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0xc26346b891974968c6fa1745b2cfa869d2d0e5875e9fc2bd661167ae19314c6b + * - Discussion: https://governance.aave.com/t/arfc-gho-stewards-borrow-rate-update/16956 + */ +contract AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324 is IProposalGenericExecutor { + address internal immutable INTEREST_RATE_STRATEGY; + + constructor(address interestRateStrategy) { + INTEREST_RATE_STRATEGY = interestRateStrategy; + } + + function execute() external { + AaveV3Ethereum.POOL_CONFIGURATOR.setReserveInterestRateStrategyAddress( + AaveV3EthereumAssets.GHO_UNDERLYING, + INTEREST_RATE_STRATEGY + ); + } +} diff --git a/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.t.sol b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.t.sol new file mode 100644 index 000000000..46d07393a --- /dev/null +++ b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.t.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/GovV3Helpers.sol'; + +import {AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324} from './AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.sol'; +import {GhoInterestRateStrategy} from './GhoInterestRateStrategy.sol'; + +/** + * @dev Test for AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324 + * command: make test-contract filter=AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324 + */ +contract AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324_Test is ProtocolV3TestBase { + AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324 internal proposal; + GhoInterestRateStrategy internal strategy; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('mainnet'), 19511307); + strategy = GhoInterestRateStrategy( + GovV3Helpers.deployDeterministic(type(GhoInterestRateStrategy).creationCode) + ); + + proposal = AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324( + GovV3Helpers.deployDeterministic( + type(AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324).creationCode, + abi.encode( + GovV3Helpers.predictDeterministicAddress(type(GhoInterestRateStrategy).creationCode) + ) + ) + ); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest( + 'AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324', + AaveV3Ethereum.POOL, + address(proposal) + ); + } +} diff --git a/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate.md b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate.md new file mode 100644 index 000000000..5f5fa4843 --- /dev/null +++ b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate.md @@ -0,0 +1,35 @@ +--- +title: "GHO Stewards + Borrow Rate Update" +author: "karpatkey_TokenLogic ACI ChaosLabs" +discussions: "https://governance.aave.com/t/arfc-gho-stewards-borrow-rate-update/16956" +snapshot: "https://snapshot.org/#/aave.eth/proposal/0xc26346b891974968c6fa1745b2cfa869d2d0e5875e9fc2bd661167ae19314c6b" +--- + +## Simple Summary + +In response to recent market events, this AIP increases the GHO Borrow Rate to 13.00%. + +## Motivation + +In response to recent stable coin Borrow Rates increasing and Maker DAO's recently proposed changes, this AIP amends the current GHO Interest Rate strategy. + +This AIP is expected to enable GHO to continue growing whilst maintaining peg stability. Upon implementation the Borrow Rate arbitrage opportunity with be meaningfully reduced. + +## Specification + +| Description | Current (%) | Proposed (%) | +| -------------------------- | ----------- | ------------------ | +| Non Discounted Borrow Rate | 7.48% | 13.00% | +| stkAAVE Discount | 30.00% | 30.00% (no change) | +| Discounted Borrow Rate | 5.24% | 9.10% | + +## References + +- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.sol) +- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.t.sol) +- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0xc26346b891974968c6fa1745b2cfa869d2d0e5875e9fc2bd661167ae19314c6b) +- [Discussion](https://governance.aave.com/t/arfc-gho-stewards-borrow-rate-update/16956) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate_20240324.s.sol b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate_20240324.s.sol new file mode 100644 index 000000000..0f92acd71 --- /dev/null +++ b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate_20240324.s.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/GovV3Helpers.sol'; +import {EthereumScript} from 'aave-helpers/ScriptUtils.sol'; + +import {AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324} from './AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324.sol'; +import {GhoInterestRateStrategy} from './GhoInterestRateStrategy.sol'; + +/** + * @dev Deploy InterestRateStrategy + * deploy-command: make deploy-ledger contract=src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate_20240324.s.sol:DeployInterestRateStrategy chain=mainnet + * verify-command: npx catapulta-verify -b broadcast/GHOStewardsBorrowRateUpdate_20240324.s.sol/1/run-latest.json + */ +contract DeployInterestRateStrategy is EthereumScript { + function run() external broadcast { + // deploy ir + GovV3Helpers.deployDeterministic(type(GhoInterestRateStrategy).creationCode); + } +} + +/** + * @dev Deploy Ethereum + * deploy-command: make deploy-ledger contract=src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate_20240324.s.sol:DeployEthereum chain=mainnet + * verify-command: npx catapulta-verify -b broadcast/GHOStewardsBorrowRateUpdate_20240324.s.sol/1/run-latest.json + */ +contract DeployEthereum is EthereumScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324).creationCode, + abi.encode( + GovV3Helpers.predictDeterministicAddress(type(GhoInterestRateStrategy).creationCode) + ) + ); + + // compose action + IPayloadsControllerCore.ExecutionAction[] + memory actions = new IPayloadsControllerCore.ExecutionAction[](1); + actions[0] = GovV3Helpers.buildAction(payload0); + + // register action at payloadsController + GovV3Helpers.createPayload(actions); + } +} + +/** + * @dev Create Proposal + * command: make deploy-ledger contract=src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate_20240324.s.sol:CreateProposal chain=mainnet + */ +contract CreateProposal is EthereumScript { + function run() external { + address strategy = GovV3Helpers.predictDeterministicAddress( + type(GhoInterestRateStrategy).creationCode + ); + // create payloads + PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](1); + + // compose actions for validation + IPayloadsControllerCore.ExecutionAction[] + memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1); + actionsEthereum[0] = GovV3Helpers.buildAction( + type(AaveV3Ethereum_GHOStewardsBorrowRateUpdate_20240324).creationCode, + abi.encode(strategy) + ); + payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); + + // create proposal + vm.startBroadcast(); + GovV3Helpers.createProposal( + vm, + payloads, + GovV3Helpers.ipfsHashFile( + vm, + 'src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GHOStewardsBorrowRateUpdate.md' + ) + ); + } +} diff --git a/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GhoInterestRateStrategy.sol b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GhoInterestRateStrategy.sol new file mode 100644 index 000000000..0a1704a41 --- /dev/null +++ b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/GhoInterestRateStrategy.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import {DataTypes} from 'aave-v3-core/contracts/protocol/libraries/types/DataTypes.sol'; +import {IDefaultInterestRateStrategy} from 'aave-v3-core/contracts/interfaces/IDefaultInterestRateStrategy.sol'; +import {IReserveInterestRateStrategy} from 'aave-v3-core/contracts/interfaces/IReserveInterestRateStrategy.sol'; +import {IPoolAddressesProvider} from 'aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol'; +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; + +/** + * @title GhoInterestRateStrategy + * @author Aave + * @notice Implements the calculation of GHO interest rates, which defines a fixed variable borrow rate. + * @dev The variable borrow interest rate is fixed at deployment time. The rest of parameters are zeroed. + */ +contract GhoInterestRateStrategy is IDefaultInterestRateStrategy { + /// @inheritdoc IDefaultInterestRateStrategy + uint256 public constant OPTIMAL_USAGE_RATIO = 0; + + /// @inheritdoc IDefaultInterestRateStrategy + uint256 public constant OPTIMAL_STABLE_TO_TOTAL_DEBT_RATIO = 0; + + /// @inheritdoc IDefaultInterestRateStrategy + uint256 public constant MAX_EXCESS_USAGE_RATIO = 0; + + /// @inheritdoc IDefaultInterestRateStrategy + uint256 public constant MAX_EXCESS_STABLE_TO_TOTAL_DEBT_RATIO = 0; + + /// @inheritdoc IDefaultInterestRateStrategy + IPoolAddressesProvider public constant ADDRESSES_PROVIDER = + AaveV3Ethereum.POOL_ADDRESSES_PROVIDER; + + // Base variable borrow rate when usage rate = 0. Expressed in ray + uint256 internal immutable _baseVariableBorrowRate = 130000000000000000000000000; // 13.00% in ray format + + /// @inheritdoc IDefaultInterestRateStrategy + function getVariableRateSlope1() external pure returns (uint256) { + return 0; + } + + /// @inheritdoc IDefaultInterestRateStrategy + function getVariableRateSlope2() external pure returns (uint256) { + return 0; + } + + /// @inheritdoc IDefaultInterestRateStrategy + function getStableRateSlope1() external pure returns (uint256) { + return 0; + } + + /// @inheritdoc IDefaultInterestRateStrategy + function getStableRateSlope2() external pure returns (uint256) { + return 0; + } + + /// @inheritdoc IDefaultInterestRateStrategy + function getStableRateExcessOffset() external pure returns (uint256) { + return 0; + } + + /// @inheritdoc IDefaultInterestRateStrategy + function getBaseStableBorrowRate() public pure returns (uint256) { + return 0; + } + + /// @inheritdoc IDefaultInterestRateStrategy + function getBaseVariableBorrowRate() external view override returns (uint256) { + return _baseVariableBorrowRate; + } + + /// @inheritdoc IDefaultInterestRateStrategy + function getMaxVariableBorrowRate() external view override returns (uint256) { + return _baseVariableBorrowRate; + } + + /// @inheritdoc IReserveInterestRateStrategy + function calculateInterestRates( + DataTypes.CalculateInterestRatesParams memory + ) public view override returns (uint256, uint256, uint256) { + return (0, 0, _baseVariableBorrowRate); + } +} diff --git a/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/config.ts b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/config.ts new file mode 100644 index 000000000..ae3496853 --- /dev/null +++ b/src/20240324_AaveV3Ethereum_GHOStewardsBorrowRateUpdate/config.ts @@ -0,0 +1,14 @@ +import {ConfigFile} from '../../generator/types'; +export const config: ConfigFile = { + rootOptions: { + pools: ['AaveV3Ethereum'], + title: 'GHO Stewards + Borrow Rate Update', + shortName: 'GHOStewardsBorrowRateUpdate', + date: '20240324', + author: 'karpatkey_TokenLogic ACI ChaosLabs', + discussion: 'https://governance.aave.com/t/arfc-gho-stewards-borrow-rate-update/16956', + snapshot: + 'https://snapshot.org/#/aave.eth/proposal/0xc26346b891974968c6fa1745b2cfa869d2d0e5875e9fc2bd661167ae19314c6b', + }, + poolOptions: {AaveV3Ethereum: {configs: {}, cache: {blockNumber: 19508206}}}, +};