From 24a3f7d23e03aca479c43c3f5d8a26c06d2686e8 Mon Sep 17 00:00:00 2001 From: Parth Patel Date: Wed, 6 Dec 2023 03:34:57 +0530 Subject: [PATCH 01/58] Add proposal for Gho Incident Report 20231113 (#1) * chore: add payload and deploy script for update of GHO variable debt token * forge install: gho-core * chore: add gho-core to dependency * test: Add tests for update of gho variable token * test: Add tests for update of gho variable token * fix: add modifier in method of interface * fix: remove gho dependency from repo and fix test * fix: Remove unnecesary dependency * fix: Add latest details --------- Co-authored-by: miguelmtzinf --- remappings.txt | 2 +- ...veV3Ethereum_GhoIncidentReport_20231113.md | 28 +++++++++ ...3Ethereum_GhoIncidentReport_20231113.s.sol | 58 +++++++++++++++++++ ...eV3Ethereum_GhoIncidentReport_20231113.sol | 33 +++++++++++ ...3Ethereum_GhoIncidentReport_20231113.t.sol | 44 ++++++++++++++ 5 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md create mode 100644 src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol create mode 100644 src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.sol create mode 100644 src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol diff --git a/remappings.txt b/remappings.txt index b3b219556..620a76fc2 100644 --- a/remappings.txt +++ b/remappings.txt @@ -6,4 +6,4 @@ aave-v3-core/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-core/ aave-v3-periphery/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-periphery/ ds-test/=lib/aave-helpers/lib/forge-std/lib/ds-test/src/ forge-std/=lib/aave-helpers/lib/forge-std/src/ -solidity-utils/=lib/aave-helpers/lib/solidity-utils/src/ +solidity-utils/=lib/aave-helpers/lib/solidity-utils/src/ \ No newline at end of file diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md new file mode 100644 index 000000000..98d6ad0c4 --- /dev/null +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md @@ -0,0 +1,28 @@ +--- +title: "GHO update on Aave V3 Ethereum Pool for 13/11/2023 Report" +author: "Aave Labs @aave" +discussions: "https://governance.aave.com/t/arfc-gho-technical-incident-13-11-2023/15642" +--- + +## Simple Summary + +This proposal patches the GHO integration with the Aave V3 Pool, fixing an issue reported by Immunefi on November 13, 2023. The patch, developed by Aave Labs in collaboration with Certora, upholds the highest safety standards. + +## Motivation + +A resolution for the identified technical issue identified in the GHO integration with the Aave V3 Ethereum Pool. The patch guarantees a permanent solution without altering any of the existing GHO features within the Aave Pool. + +## Specification + +The proposal payload upgrades the implementation of GhoVariableDebtToken. + +## References + +- GhoVariableDebtToken implementation: [GhoVariableDebtToken](https://etherscan.io/address/0x20cb2f303ede313e2cc44549ad8653a5e8c0050e#code) +- Implementation: [Payload]() +- [Discussion](https://governance.aave.com/t/arfc-gho-technical-incident-13-11-2023/15642) + + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol new file mode 100644 index 000000000..89ea31bb9 --- /dev/null +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Ethereum_GhoIncidentReport_20231113} from './AaveV3Ethereum_GhoIncidentReport_20231113.sol'; +import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/GovV3Helpers.sol'; +import {EthereumScript} from 'aave-helpers/ScriptUtils.sol'; + +/** + * @dev Deploy AaveV3Ethereum_GhoIncidentReport_20231113 + * command: make deploy-ledger contract=src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol:DeployEthereum chain=mainnet + */ +contract DeployEthereum is EthereumScript { + address constant NEW_VGHO_IMPL = 0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e; + + function run() external broadcast { + // deploy payloads + AaveV3Ethereum_GhoIncidentReport_20231113 payload = new AaveV3Ethereum_GhoIncidentReport_20231113( + NEW_VGHO_IMPL + ); + + // compose action + IPayloadsControllerCore.ExecutionAction[] + memory actions = new IPayloadsControllerCore.ExecutionAction[](1); + actions[0] = GovV3Helpers.buildAction(address(payload)); + + // register action at payloadsController + GovV3Helpers.createPayload(actions); + } +} + +/** + * @dev Create Proposal + * command: make deploy-ledger contract=src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol:CreateProposal chain=mainnet + */ +contract CreateProposal is EthereumScript { + function run() external { + // create payloads + PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](1); + + // compose actions for validation + IPayloadsControllerCore.ExecutionAction[] + memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1); + //TODO: Replace this address with payload address + actionsEthereum[0] = GovV3Helpers.buildAction(0xfb1163CD80850CD107bB134C15E5dfDF284F63FE); + payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); + + // create proposal + vm.startBroadcast(); + GovV3Helpers.createProposal2_5( + vm, + payloads, + GovV3Helpers.ipfsHashFile( + vm, + 'src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md' + ) + ); + } +} diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.sol b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.sol new file mode 100644 index 000000000..b80e50a1d --- /dev/null +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ConfiguratorInputTypes} from 'aave-address-book/AaveV3.sol'; +import {IERC20} from 'forge-std/interfaces/IERC20.sol'; +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; + +/** + * @title GHO update on Aave V3 Ethereum Pool for 13/11/2023 Report + * @dev Upgrades the implementation of the GhoVariableDebtToken contract + * @author Aave Labs (@aave) + * - Discussion: https://governance.aave.com/t/arfc-gho-technical-incident-13-11-2023/15642 + */ +contract AaveV3Ethereum_GhoIncidentReport_20231113 { + address public immutable NEW_VGHO_IMPL; + + constructor(address newVGhoImpl) { + NEW_VGHO_IMPL = newVGhoImpl; + } + + function execute() external { + AaveV3Ethereum.POOL_CONFIGURATOR.updateVariableDebtToken( + ConfiguratorInputTypes.UpdateDebtTokenInput({ + asset: AaveV3EthereumAssets.GHO_UNDERLYING, + incentivesController: AaveV3Ethereum.DEFAULT_INCENTIVES_CONTROLLER, + name: IERC20(AaveV3EthereumAssets.GHO_V_TOKEN).name(), + symbol: IERC20(AaveV3EthereumAssets.GHO_V_TOKEN).symbol(), + implementation: NEW_VGHO_IMPL, + params: bytes('') + }) + ); + } +} diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol new file mode 100644 index 000000000..344b71a41 --- /dev/null +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import 'forge-std/Test.sol'; +import {AaveV3EthereumAssets, AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {AaveV3Ethereum_GhoIncidentReport_20231113} from './AaveV3Ethereum_GhoIncidentReport_20231113.sol'; + +interface IGhoVariableDebtTokenHelper { + function DEBT_TOKEN_REVISION() external view returns (uint256); +} + +/** + * @dev Test for AaveV3Ethereum_GhoIncidentReport_20231113 + * command: make test-contract filter=AaveV3Ethereum_GhoIncidentReport_20231113 + */ +contract AaveV3Ethereum_GhoIncidentReport_20231113_Test is ProtocolV3TestBase { + address constant NEW_VGHO_IMPL = 0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e; + + AaveV3Ethereum_GhoIncidentReport_20231113 internal proposal; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('mainnet'), 18722500); + proposal = new AaveV3Ethereum_GhoIncidentReport_20231113(NEW_VGHO_IMPL); + } + + function test_defaultProposalExecution() public { + defaultTest( + 'AaveV3Ethereum_GhoIncidentReport_20231113', + AaveV3Ethereum.POOL, + address(proposal) + ); + } + + function test_debtTokenRevisionUpdate() public { + assertTrue( + IGhoVariableDebtTokenHelper(AaveV3EthereumAssets.GHO_V_TOKEN).DEBT_TOKEN_REVISION() == 0x2 + ); + executePayload(vm, address(proposal)); + assertTrue( + IGhoVariableDebtTokenHelper(AaveV3EthereumAssets.GHO_V_TOKEN).DEBT_TOKEN_REVISION() == 0x3 + ); + } +} From 4aa6143b87b5e26d980cba5079de79f5210b7ccc Mon Sep 17 00:00:00 2001 From: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com> Date: Wed, 6 Dec 2023 11:13:37 +0100 Subject: [PATCH 02/58] fix: Make new impl constant (#3) --- .../AaveV3Ethereum_GhoIncidentReport_20231113.s.sol | 6 ++---- .../AaveV3Ethereum_GhoIncidentReport_20231113.sol | 6 +----- .../AaveV3Ethereum_GhoIncidentReport_20231113.t.sol | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol index 89ea31bb9..d197070fa 100644 --- a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol @@ -14,9 +14,7 @@ contract DeployEthereum is EthereumScript { function run() external broadcast { // deploy payloads - AaveV3Ethereum_GhoIncidentReport_20231113 payload = new AaveV3Ethereum_GhoIncidentReport_20231113( - NEW_VGHO_IMPL - ); + AaveV3Ethereum_GhoIncidentReport_20231113 payload = new AaveV3Ethereum_GhoIncidentReport_20231113(); // compose action IPayloadsControllerCore.ExecutionAction[] @@ -47,7 +45,7 @@ contract CreateProposal is EthereumScript { // create proposal vm.startBroadcast(); GovV3Helpers.createProposal2_5( - vm, + vm, payloads, GovV3Helpers.ipfsHashFile( vm, diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.sol b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.sol index b80e50a1d..08fc96cec 100644 --- a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.sol +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.sol @@ -12,11 +12,7 @@ import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethe * - Discussion: https://governance.aave.com/t/arfc-gho-technical-incident-13-11-2023/15642 */ contract AaveV3Ethereum_GhoIncidentReport_20231113 { - address public immutable NEW_VGHO_IMPL; - - constructor(address newVGhoImpl) { - NEW_VGHO_IMPL = newVGhoImpl; - } + address public constant NEW_VGHO_IMPL = 0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e; function execute() external { AaveV3Ethereum.POOL_CONFIGURATOR.updateVariableDebtToken( diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol index 344b71a41..f3286efb8 100644 --- a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol @@ -21,7 +21,7 @@ contract AaveV3Ethereum_GhoIncidentReport_20231113_Test is ProtocolV3TestBase { function setUp() public { vm.createSelectFork(vm.rpcUrl('mainnet'), 18722500); - proposal = new AaveV3Ethereum_GhoIncidentReport_20231113(NEW_VGHO_IMPL); + proposal = new AaveV3Ethereum_GhoIncidentReport_20231113(); } function test_defaultProposalExecution() public { From 27dd485e2f2fb5ceb42ba5c67f5e1cc95b0ae3ec Mon Sep 17 00:00:00 2001 From: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com> Date: Wed, 6 Dec 2023 11:17:54 +0100 Subject: [PATCH 03/58] fix: Amend AIP text (#4) * fix: Make new impl constant * fix: Fix AIP text --- .../AaveV3Ethereum_GhoIncidentReport_20231113.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md index 98d6ad0c4..21902514e 100644 --- a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md @@ -10,7 +10,7 @@ This proposal patches the GHO integration with the Aave V3 Pool, fixing an issue ## Motivation -A resolution for the identified technical issue identified in the GHO integration with the Aave V3 Ethereum Pool. The patch guarantees a permanent solution without altering any of the existing GHO features within the Aave Pool. +The proposed patch guarantees a permanent solution for the technical issue that was identified and reported by Immunefi with the GHO integration with the Aave V3 Ethereum Pool. The fix will be implemented without altering any of the existing GHO features within the Aave V3 Pool. ## Specification From 2f242a671075a02ca4b1d2e08556c67295fb1088 Mon Sep 17 00:00:00 2001 From: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:53:57 +0100 Subject: [PATCH 04/58] test: Tweak default tests with borrow cap update (#5) --- .../AaveV3Ethereum_GhoIncidentReport_20231113.t.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol index f3286efb8..dcbfb4659 100644 --- a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import {AaveV3EthereumAssets, AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {IPoolConfigurator} from 'aave-address-book/AaveV3.sol'; import {AaveV3Ethereum_GhoIncidentReport_20231113} from './AaveV3Ethereum_GhoIncidentReport_20231113.sol'; interface IGhoVariableDebtTokenHelper { @@ -25,6 +26,9 @@ contract AaveV3Ethereum_GhoIncidentReport_20231113_Test is ProtocolV3TestBase { } function test_defaultProposalExecution() public { + // increase GHO borrow cap so test borrows can succeed + vm.prank(AaveV3Ethereum.CAPS_PLUS_RISK_STEWARD); + AaveV3Ethereum.POOL_CONFIGURATOR.setBorrowCap(AaveV3Ethereum.GHO_TOKEN, 36_000_000); defaultTest( 'AaveV3Ethereum_GhoIncidentReport_20231113', AaveV3Ethereum.POOL, From 4812d01dc7f76975ffb20b80f30251f8f2a70924 Mon Sep 17 00:00:00 2001 From: Parth Patel Date: Fri, 8 Dec 2023 00:10:52 +0530 Subject: [PATCH 05/58] fix: lint issue (#6) --- .../AaveV3Ethereum_GhoIncidentReport_20231113.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md index 21902514e..21e9b39ec 100644 --- a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md @@ -22,7 +22,6 @@ The proposal payload upgrades the implementation of GhoVariableDebtToken. - Implementation: [Payload]() - [Discussion](https://governance.aave.com/t/arfc-gho-technical-incident-13-11-2023/15642) - ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 43a7687a4c629f11d1c3be19bbafb59b8d12d70e Mon Sep 17 00:00:00 2001 From: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com> Date: Thu, 7 Dec 2023 19:44:59 +0100 Subject: [PATCH 06/58] test: Add diffs from test running (#7) --- ...hereum_GhoIncidentReport_20231113_after.md | 25 +++++++++++++++++++ ...hereum_GhoIncidentReport_20231126_after.md | 25 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 diffs/AaveV3Ethereum_GhoIncidentReport_20231113_before_AaveV3Ethereum_GhoIncidentReport_20231113_after.md create mode 100644 diffs/AaveV3Ethereum_GhoIncidentReport_20231126_before_AaveV3Ethereum_GhoIncidentReport_20231126_after.md diff --git a/diffs/AaveV3Ethereum_GhoIncidentReport_20231113_before_AaveV3Ethereum_GhoIncidentReport_20231113_after.md b/diffs/AaveV3Ethereum_GhoIncidentReport_20231113_before_AaveV3Ethereum_GhoIncidentReport_20231113_after.md new file mode 100644 index 000000000..1088d0e5d --- /dev/null +++ b/diffs/AaveV3Ethereum_GhoIncidentReport_20231113_before_AaveV3Ethereum_GhoIncidentReport_20231113_after.md @@ -0,0 +1,25 @@ +## Reserve changes + +### Reserves altered + +#### GHO ([0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f](https://etherscan.io/address/0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f)) + +| description | value before | value after | +| --- | --- | --- | +| variableDebtTokenImpl | [0x7aa606b1B341fFEeAfAdbbE4A2992EFB35972775](https://etherscan.io/address/0x7aa606b1B341fFEeAfAdbbE4A2992EFB35972775) | [0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e](https://etherscan.io/address/0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e) | + + +## Raw diff + +```json +{ + "reserves": { + "0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f": { + "variableDebtTokenImpl": { + "from": "0x7aa606b1B341fFEeAfAdbbE4A2992EFB35972775", + "to": "0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e" + } + } + } +} +``` \ No newline at end of file diff --git a/diffs/AaveV3Ethereum_GhoIncidentReport_20231126_before_AaveV3Ethereum_GhoIncidentReport_20231126_after.md b/diffs/AaveV3Ethereum_GhoIncidentReport_20231126_before_AaveV3Ethereum_GhoIncidentReport_20231126_after.md new file mode 100644 index 000000000..1088d0e5d --- /dev/null +++ b/diffs/AaveV3Ethereum_GhoIncidentReport_20231126_before_AaveV3Ethereum_GhoIncidentReport_20231126_after.md @@ -0,0 +1,25 @@ +## Reserve changes + +### Reserves altered + +#### GHO ([0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f](https://etherscan.io/address/0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f)) + +| description | value before | value after | +| --- | --- | --- | +| variableDebtTokenImpl | [0x7aa606b1B341fFEeAfAdbbE4A2992EFB35972775](https://etherscan.io/address/0x7aa606b1B341fFEeAfAdbbE4A2992EFB35972775) | [0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e](https://etherscan.io/address/0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e) | + + +## Raw diff + +```json +{ + "reserves": { + "0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f": { + "variableDebtTokenImpl": { + "from": "0x7aa606b1B341fFEeAfAdbbE4A2992EFB35972775", + "to": "0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e" + } + } + } +} +``` \ No newline at end of file From 4c79bb9fd4120ff068eaa946cc01961d51b6a892 Mon Sep 17 00:00:00 2001 From: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com> Date: Thu, 7 Dec 2023 20:15:32 +0100 Subject: [PATCH 07/58] fix: Add payload address (#8) --- .../AaveV3Ethereum_GhoIncidentReport_20231113.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md index 21e9b39ec..2cf269d2a 100644 --- a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.md @@ -19,7 +19,7 @@ The proposal payload upgrades the implementation of GhoVariableDebtToken. ## References - GhoVariableDebtToken implementation: [GhoVariableDebtToken](https://etherscan.io/address/0x20cb2f303ede313e2cc44549ad8653a5e8c0050e#code) -- Implementation: [Payload]() +- Implementation: [Payload](https://etherscan.io/address/0xbc9ffee8d18d75a412474b92192257d3c18471ff#code) - [Discussion](https://governance.aave.com/t/arfc-gho-technical-incident-13-11-2023/15642) ## Copyright From 76cd4b62ea788ce12259adcc565128bcea4a1181 Mon Sep 17 00:00:00 2001 From: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com> Date: Thu, 7 Dec 2023 20:40:00 +0100 Subject: [PATCH 08/58] fix: Fix payload address in script (#9) --- .../AaveV3Ethereum_GhoIncidentReport_20231113.s.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol index d197070fa..4345823a2 100644 --- a/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol +++ b/src/20231207_AaveV3Ethereum_GhoIncidentReport_20231126/AaveV3Ethereum_GhoIncidentReport_20231113.s.sol @@ -38,8 +38,7 @@ contract CreateProposal is EthereumScript { // compose actions for validation IPayloadsControllerCore.ExecutionAction[] memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1); - //TODO: Replace this address with payload address - actionsEthereum[0] = GovV3Helpers.buildAction(0xfb1163CD80850CD107bB134C15E5dfDF284F63FE); + actionsEthereum[0] = GovV3Helpers.buildAction(0xbC9ffee8d18d75a412474B92192257d3c18471FF); payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); // create proposal From 120f5649187b1f70d39e37d3f4ca88416968aece Mon Sep 17 00:00:00 2001 From: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com> Date: Thu, 7 Dec 2023 20:53:41 +0100 Subject: [PATCH 09/58] fix: Remove unneeded diff file (#10) --- ...hereum_GhoIncidentReport_20231126_after.md | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 diffs/AaveV3Ethereum_GhoIncidentReport_20231126_before_AaveV3Ethereum_GhoIncidentReport_20231126_after.md diff --git a/diffs/AaveV3Ethereum_GhoIncidentReport_20231126_before_AaveV3Ethereum_GhoIncidentReport_20231126_after.md b/diffs/AaveV3Ethereum_GhoIncidentReport_20231126_before_AaveV3Ethereum_GhoIncidentReport_20231126_after.md deleted file mode 100644 index 1088d0e5d..000000000 --- a/diffs/AaveV3Ethereum_GhoIncidentReport_20231126_before_AaveV3Ethereum_GhoIncidentReport_20231126_after.md +++ /dev/null @@ -1,25 +0,0 @@ -## Reserve changes - -### Reserves altered - -#### GHO ([0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f](https://etherscan.io/address/0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f)) - -| description | value before | value after | -| --- | --- | --- | -| variableDebtTokenImpl | [0x7aa606b1B341fFEeAfAdbbE4A2992EFB35972775](https://etherscan.io/address/0x7aa606b1B341fFEeAfAdbbE4A2992EFB35972775) | [0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e](https://etherscan.io/address/0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e) | - - -## Raw diff - -```json -{ - "reserves": { - "0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f": { - "variableDebtTokenImpl": { - "from": "0x7aa606b1B341fFEeAfAdbbE4A2992EFB35972775", - "to": "0x20Cb2f303EDe313e2Cc44549Ad8653a5E8c0050e" - } - } - } -} -``` \ No newline at end of file From 35bddfab90cd0a2bcf9664c06529382ec87f795f Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 4 Nov 2024 20:08:13 -0800 Subject: [PATCH 10/58] feat: Initial proposal generation --- ...AaveV3Avalanche_GHOAvaxLaunch_20241104.sol | 15 ++++ ...veV3Avalanche_GHOAvaxLaunch_20241104.t.sol | 28 ++++++ .../AaveV3Ethereum_GHOAvaxLaunch_20241104.sol | 15 ++++ ...aveV3Ethereum_GHOAvaxLaunch_20241104.t.sol | 28 ++++++ .../GHOAvaxLaunch.md | 23 +++++ .../GHOAvaxLaunch_20241104.s.sol | 87 +++++++++++++++++++ src/20241104_Multi_GHOAvaxLaunch/config.ts | 19 ++++ 7 files changed, 215 insertions(+) create mode 100644 src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol create mode 100644 src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol create mode 100644 src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol create mode 100644 src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol create mode 100644 src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md create mode 100644 src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol create mode 100644 src/20241104_Multi_GHOAvaxLaunch/config.ts diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol new file mode 100644 index 000000000..6df9e1aff --- /dev/null +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +/** + * @title GHOAvaxLaunch + * @author Aave Labs + * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 + * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + */ +contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { + function execute() external { + // custom code goes here + } +} diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol new file mode 100644 index 000000000..e687640f9 --- /dev/null +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; + +import 'forge-std/Test.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {AaveV3Avalanche_GHOAvaxLaunch_20241104} from './AaveV3Avalanche_GHOAvaxLaunch_20241104.sol'; + +/** + * @dev Test for AaveV3Avalanche_GHOAvaxLaunch_20241104 + * command: FOUNDRY_PROFILE=avalanche forge test --match-path=src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol -vv + */ +contract AaveV3Avalanche_GHOAvaxLaunch_20241104_Test is ProtocolV3TestBase { + AaveV3Avalanche_GHOAvaxLaunch_20241104 internal proposal; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('avalanche'), 52673463); + proposal = new AaveV3Avalanche_GHOAvaxLaunch_20241104(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest('AaveV3Avalanche_GHOAvaxLaunch_20241104', AaveV3Avalanche.POOL, address(proposal)); + } +} diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol new file mode 100644 index 000000000..321c3c0e7 --- /dev/null +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +/** + * @title GHOAvaxLaunch + * @author Aave Labs + * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 + * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + */ +contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { + function execute() external { + // custom code goes here + } +} diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol new file mode 100644 index 000000000..029fbed59 --- /dev/null +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; + +import 'forge-std/Test.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {AaveV3Ethereum_GHOAvaxLaunch_20241104} from './AaveV3Ethereum_GHOAvaxLaunch_20241104.sol'; + +/** + * @dev Test for AaveV3Ethereum_GHOAvaxLaunch_20241104 + * command: FOUNDRY_PROFILE=mainnet forge test --match-path=src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol -vv + */ +contract AaveV3Ethereum_GHOAvaxLaunch_20241104_Test is ProtocolV3TestBase { + AaveV3Ethereum_GHOAvaxLaunch_20241104 internal proposal; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('mainnet'), 21118953); + proposal = new AaveV3Ethereum_GHOAvaxLaunch_20241104(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest('AaveV3Ethereum_GHOAvaxLaunch_20241104', AaveV3Ethereum.POOL, address(proposal)); + } +} diff --git a/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md b/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md new file mode 100644 index 000000000..9953cf858 --- /dev/null +++ b/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md @@ -0,0 +1,23 @@ +--- +title: "GHOAvaxLaunch" +author: "Aave Labs" +discussions: "https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339" +snapshot: "https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719" +--- + +## Simple Summary + +## Motivation + +## Specification + +## References + +- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol) +- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol) +- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719) +- [Discussion](https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol b/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol new file mode 100644 index 000000000..b2637d8da --- /dev/null +++ b/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/src/GovV3Helpers.sol'; +import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; +import {EthereumScript, AvalancheScript} from 'solidity-utils/contracts/utils/ScriptUtils.sol'; +import {AaveV3Ethereum_GHOAvaxLaunch_20241104} from './AaveV3Ethereum_GHOAvaxLaunch_20241104.sol'; +import {AaveV3Avalanche_GHOAvaxLaunch_20241104} from './AaveV3Avalanche_GHOAvaxLaunch_20241104.sol'; + +/** + * @dev Deploy Ethereum + * deploy-command: make deploy-ledger contract=src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol:DeployEthereum chain=mainnet + * verify-command: FOUNDRY_PROFILE=mainnet npx catapulta-verify -b broadcast/GHOAvaxLaunch_20241104.s.sol/1/run-latest.json + */ +contract DeployEthereum is EthereumScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Ethereum_GHOAvaxLaunch_20241104).creationCode + ); + + // compose action + IPayloadsControllerCore.ExecutionAction[] + memory actions = new IPayloadsControllerCore.ExecutionAction[](1); + actions[0] = GovV3Helpers.buildAction(payload0); + + // register action at payloadsController + GovV3Helpers.createPayload(actions); + } +} + +/** + * @dev Deploy Avalanche + * deploy-command: make deploy-ledger contract=src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol:DeployAvalanche chain=avalanche + * verify-command: FOUNDRY_PROFILE=avalanche npx catapulta-verify -b broadcast/GHOAvaxLaunch_20241104.s.sol/43114/run-latest.json + */ +contract DeployAvalanche is AvalancheScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Avalanche_GHOAvaxLaunch_20241104).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/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol:CreateProposal chain=mainnet + */ +contract CreateProposal is EthereumScript { + function run() external { + // create payloads + PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](2); + + // compose actions for validation + IPayloadsControllerCore.ExecutionAction[] + memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1); + actionsEthereum[0] = GovV3Helpers.buildAction( + type(AaveV3Ethereum_GHOAvaxLaunch_20241104).creationCode + ); + payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); + + IPayloadsControllerCore.ExecutionAction[] + memory actionsAvalanche = new IPayloadsControllerCore.ExecutionAction[](1); + actionsAvalanche[0] = GovV3Helpers.buildAction( + type(AaveV3Avalanche_GHOAvaxLaunch_20241104).creationCode + ); + payloads[1] = GovV3Helpers.buildAvalanchePayload(vm, actionsAvalanche); + + // create proposal + vm.startBroadcast(); + GovV3Helpers.createProposal( + vm, + payloads, + GovernanceV3Ethereum.VOTING_PORTAL_ETH_POL, + GovV3Helpers.ipfsHashFile(vm, 'src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md') + ); + } +} diff --git a/src/20241104_Multi_GHOAvaxLaunch/config.ts b/src/20241104_Multi_GHOAvaxLaunch/config.ts new file mode 100644 index 000000000..71e5327b5 --- /dev/null +++ b/src/20241104_Multi_GHOAvaxLaunch/config.ts @@ -0,0 +1,19 @@ +import {ConfigFile} from '../../generator/types'; +export const config: ConfigFile = { + rootOptions: { + title: 'GHOAvaxLaunch', + author: 'Aave Labs', + discussion: + 'https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339', + snapshot: + 'https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719', + pools: ['AaveV3Ethereum', 'AaveV3Avalanche'], + shortName: 'GHOAvaxLaunch', + date: '20241104', + votingNetwork: 'POLYGON', + }, + poolOptions: { + AaveV3Ethereum: {configs: {OTHERS: {}}, cache: {blockNumber: 21118953}}, + AaveV3Avalanche: {configs: {OTHERS: {}}, cache: {blockNumber: 52673463}}, + }, +}; From 4ad619ac217f6fa2b8444d80dcc85822a0cf8654 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 4 Nov 2024 20:26:22 -0800 Subject: [PATCH 11/58] chore: Add v1.5 token pool dep --- .gitmodules | 4 ++++ lib/ccip | 1 + 2 files changed, 5 insertions(+) create mode 160000 lib/ccip diff --git a/.gitmodules b/.gitmodules index f7316a1d6..74efc2a48 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "lib/aave-helpers"] path = lib/aave-helpers url = https://github.com/bgd-labs/aave-helpers +[submodule "lib/ccip"] + path = lib/ccip + url = https://github.com/aave/ccip.git + branch = feat/1_5_token_pool diff --git a/lib/ccip b/lib/ccip new file mode 160000 index 000000000..93b0f9333 --- /dev/null +++ b/lib/ccip @@ -0,0 +1 @@ +Subproject commit 93b0f9333c13a24743413ebcf8e7739fba055eae From eaddfca3e42d46b31b1a8714d9cb02d77e25e4f1 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 4 Nov 2024 21:09:34 -0800 Subject: [PATCH 12/58] feat: Ethereum proposal --- remappings.txt | 1 + .../AaveV3Ethereum_GHOAvaxLaunch_20241104.sol | 65 ++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/remappings.txt b/remappings.txt index 9fefc7eea..2d74e39c1 100644 --- a/remappings.txt +++ b/remappings.txt @@ -3,3 +3,4 @@ aave-helpers/=lib/aave-helpers/ aave-v3-origin/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src/ forge-std/=lib/aave-helpers/lib/forge-std/src/ solidity-utils/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/src +ccip/=lib/ccip/contracts/src/v0.8/ccip/ \ No newline at end of file diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol index 321c3c0e7..51cf7cf9a 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol @@ -2,14 +2,75 @@ pragma solidity ^0.8.0; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; +import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {UpgradeableLockReleaseTokenPool} from 'ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol'; +import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; + /** - * @title GHOAvaxLaunch + * @title GHO Avax Launch * @author Aave Labs * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + * @dev This payload consists of the following set of actions: + * 1. Deploy LockReleaseTokenPool + * 2. Accept ownership of CCIP TokenPool + * 3. Configure CCIP TokenPool */ contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { + address public constant CCIP_RMN_PROXY = 0x411dE17f12D1A34ecC7F45f49844626267c75e81; + address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + uint256 public constant CCIP_BRIDGE_LIMIT = 25_000_000e18; // 25M + uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; + function execute() external { - // custom code goes here + // 1. Deploy LockReleaseTokenPool + address tokenPool = _deployCcipTokenPool(); + + // 2. Accept TokenPool ownership + UpgradeableLockReleaseTokenPool(tokenPool).acceptOwnership(); + + // 3. Configure CCIP + _configureCcipTokenPool(tokenPool); + } + + function _deployCcipTokenPool() internal returns (address) { + address imple = address( + new UpgradeableLockReleaseTokenPool(MiscEthereum.GHO_TOKEN, CCIP_RMN_PROXY, false, true) + ); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address,uint256)', + GovernanceV3Ethereum.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + CCIP_ROUTER, // router + CCIP_BRIDGE_LIMIT // bridgeLimit + ); + return + address( + new TransparentUpgradeableProxy(imple, MiscEthereum.PROXY_ADMIN, tokenPoolInitParams) + ); + } + + function _configureCcipTokenPool(address tokenPool) internal { + UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( + 1 + ); + RateLimiter.Config memory rateConfig = RateLimiter.Config({ + isEnabled: false, + capacity: 0, + rate: 0 + }); + chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ + remoteChainSelector: CCIP_AVAX_CHAIN_SELECTOR, + allowed: true, + remotePoolAddress: abi.encode(address(0)), // TODO: Set after deployment? + remoteTokenAddress: abi.encode(address(0)), // TODO: Set after deployment? + outboundRateLimiterConfig: rateConfig, + inboundRateLimiterConfig: rateConfig + }); + UpgradeableLockReleaseTokenPool(tokenPool).applyChainUpdates(chainUpdates); } } From 19ebd6015440a89c62606ac47eeb320676c33566 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 4 Nov 2024 21:34:12 -0800 Subject: [PATCH 13/58] feat: Arbitrum proposal --- .gitmodules | 3 + lib/gho-core | 1 + remappings.txt | 3 +- ...AaveV3Avalanche_GHOAvaxLaunch_20241104.sol | 103 +++++++++++++++++- 4 files changed, 107 insertions(+), 3 deletions(-) create mode 160000 lib/gho-core diff --git a/.gitmodules b/.gitmodules index 74efc2a48..cf2009570 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ path = lib/ccip url = https://github.com/aave/ccip.git branch = feat/1_5_token_pool +[submodule "lib/gho-core"] + path = lib/gho-core + url = https://github.com/aave/gho-core.git diff --git a/lib/gho-core b/lib/gho-core new file mode 160000 index 000000000..0a6fbd4d4 --- /dev/null +++ b/lib/gho-core @@ -0,0 +1 @@ +Subproject commit 0a6fbd4d4167f6e0e777aec0ae12bf4f18b4b0a8 diff --git a/remappings.txt b/remappings.txt index 2d74e39c1..8e4662a5e 100644 --- a/remappings.txt +++ b/remappings.txt @@ -3,4 +3,5 @@ aave-helpers/=lib/aave-helpers/ aave-v3-origin/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src/ forge-std/=lib/aave-helpers/lib/forge-std/src/ solidity-utils/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/lib/solidity-utils/src -ccip/=lib/ccip/contracts/src/v0.8/ccip/ \ No newline at end of file +ccip/=lib/ccip/contracts/src/v0.8/ccip/ +gho-core/=lib/gho-core/src/contracts/ \ No newline at end of file diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol index 6df9e1aff..86b5065b1 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol @@ -2,14 +2,113 @@ pragma solidity ^0.8.0; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; +import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; +import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; + +library Utils { + address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; + address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M + uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; + + function deployGhoToken() internal returns (address) { + address imple = address(new UpgradeableGhoToken()); + + bytes memory ghoTokenInitParams = abi.encodeWithSignature( + 'initialize(address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1 // owner + ); + return + address( + new TransparentUpgradeableProxy(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) + ); + } + + function deployCcipTokenPool(address ghoToken) external returns (address) { + address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, CCIP_RMN_PROXY, false)); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + CCIP_ROUTER // router + ); + return + address( + new TransparentUpgradeableProxy( + imple, // logic + MiscAvalanche.PROXY_ADMIN, // proxy admin + tokenPoolInitParams // data + ) + ); + } +} + /** - * @title GHOAvaxLaunch + * @title GHO Avax Launch * @author Aave Labs * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + * @dev This payload consists of the following set of actions: + * 1. Deploy GHO + * 2. Deploy BurnMintTokenPool + * 3. Accept ownership of CCIP TokenPool + * 4. Configure CCIP TokenPool + * 5. Add CCIP TokenPool as GHO Facilitator */ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { function execute() external { - // custom code goes here + // 1. Deploy GHO + address ghoToken = Utils.deployGhoToken(); + + // 2. Deploy BurnMintTokenPool + address tokenPool = Utils.deployCcipTokenPool(ghoToken); + + // 3. Accept TokenPool ownership + UpgradeableBurnMintTokenPool(tokenPool).acceptOwnership(); + + // 4. Configure CCIP TokenPool + _configureCcipTokenPool(tokenPool); + + // 5. Add CCIP TokenPool as GHO Facilitator + IGhoToken(ghoToken).grantRole( + IGhoToken(ghoToken).FACILITATOR_MANAGER_ROLE(), + GovernanceV3Avalanche.EXECUTOR_LVL_1 + ); + IGhoToken(ghoToken).grantRole( + IGhoToken(ghoToken).BUCKET_MANAGER_ROLE(), + GovernanceV3Avalanche.EXECUTOR_LVL_1 + ); + IGhoToken(ghoToken).addFacilitator( + tokenPool, + 'CCIP TokenPool', + uint128(Utils.CCIP_BUCKET_CAPACITY) + ); + } + + function _configureCcipTokenPool(address tokenPool) internal { + UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( + 1 + ); + RateLimiter.Config memory rateConfig = RateLimiter.Config({ + isEnabled: false, + capacity: 0, + rate: 0 + }); + chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ + remoteChainSelector: Utils.CCIP_ETH_CHAIN_SELECTOR, + allowed: true, + remotePoolAddress: abi.encode(address(0)), // TODO: Set after deployment? + remoteTokenAddress: abi.encode(address(0)), // TODO: Set after deployment? + outboundRateLimiterConfig: rateConfig, + inboundRateLimiterConfig: rateConfig + }); + UpgradeableBurnMintTokenPool(tokenPool).applyChainUpdates(chainUpdates); } } From 4d3b3a3710bd5e4bc13b6fe89d67d10ca7dc7cc5 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 6 Nov 2024 18:41:04 -0800 Subject: [PATCH 14/58] feat: Enable Arbitrum lane, add todos --- ...AaveV3Avalanche_GHOAvaxLaunch_20241104.sol | 42 +++++++++++++++---- .../AaveV3Ethereum_GHOAvaxLaunch_20241104.sol | 28 +++++++++---- src/20241104_Multi_GHOAvaxLaunch/config.ts | 2 +- 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol index 86b5065b1..c33838020 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol @@ -16,6 +16,7 @@ library Utils { address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; + uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; function deployGhoToken() internal returns (address) { address imple = address(new UpgradeableGhoToken()); @@ -59,8 +60,12 @@ library Utils { * 1. Deploy GHO * 2. Deploy BurnMintTokenPool * 3. Accept ownership of CCIP TokenPool - * 4. Configure CCIP TokenPool - * 5. Add CCIP TokenPool as GHO Facilitator + * 4. Configure CCIP TokenPool for Ethereum + * 5. Configure CCIP TokenPool for Arbitrum + * 6. Add CCIP TokenPool as GHO Facilitator + * 7. Accept administrator role from Chainlink token manager + * 8. List GHO on Avax in separate payload - because there is a delay to activate lane + * 9. Supply GHO to the Aave protocol */ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { function execute() external { @@ -73,10 +78,15 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { // 3. Accept TokenPool ownership UpgradeableBurnMintTokenPool(tokenPool).acceptOwnership(); - // 4. Configure CCIP TokenPool - _configureCcipTokenPool(tokenPool); + // 4. Configure CCIP TokenPool for Ethereum + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, Utils.CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); - // 5. Add CCIP TokenPool as GHO Facilitator + // 5. Configure CCIP TokenPool for Arbitrum + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, Utils.CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); + + // 6. Add CCIP TokenPool as GHO Facilitator IGhoToken(ghoToken).grantRole( IGhoToken(ghoToken).FACILITATOR_MANAGER_ROLE(), GovernanceV3Avalanche.EXECUTOR_LVL_1 @@ -90,9 +100,23 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { 'CCIP TokenPool', uint128(Utils.CCIP_BUCKET_CAPACITY) ); + + // 7. Accept administrator role from Chainlink token manager + // TODO + + // 8. List GHO on Avax in separate payload + // TODO + + // 9. Supply GHO to the Aave protocol + // TODO } - function _configureCcipTokenPool(address tokenPool) internal { + function _configureCcipTokenPool( + address tokenPool, + uint64 chainSelector, + address remotePool, + address remoteToken + ) internal { UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( 1 ); @@ -102,10 +126,10 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { rate: 0 }); chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ - remoteChainSelector: Utils.CCIP_ETH_CHAIN_SELECTOR, + remoteChainSelector: chainSelector, allowed: true, - remotePoolAddress: abi.encode(address(0)), // TODO: Set after deployment? - remoteTokenAddress: abi.encode(address(0)), // TODO: Set after deployment? + remotePoolAddress: abi.encode(remotePool), + remoteTokenAddress: abi.encode(remoteToken), outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol index 51cf7cf9a..04e2a6345 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol @@ -17,12 +17,14 @@ import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; * @dev This payload consists of the following set of actions: * 1. Deploy LockReleaseTokenPool * 2. Accept ownership of CCIP TokenPool - * 3. Configure CCIP TokenPool + * 3. Configure CCIP TokenPool for Arbitrum + * 4. Configure CCIP TokenPool for Avalanche */ contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0x411dE17f12D1A34ecC7F45f49844626267c75e81; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; uint256 public constant CCIP_BRIDGE_LIMIT = 25_000_000e18; // 25M + uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; function execute() external { @@ -32,8 +34,15 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { // 2. Accept TokenPool ownership UpgradeableLockReleaseTokenPool(tokenPool).acceptOwnership(); - // 3. Configure CCIP - _configureCcipTokenPool(tokenPool); + // 3. Configure CCIP for Arbitrum + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); + + // 4. Configure CCIP for Avalanche + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); + + // TODO: Migrate funds? } function _deployCcipTokenPool() internal returns (address) { @@ -54,7 +63,12 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { ); } - function _configureCcipTokenPool(address tokenPool) internal { + function _configureCcipTokenPool( + address tokenPool, + uint64 chainSelector, + address remotePool, + address remoteToken + ) internal { UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( 1 ); @@ -64,10 +78,10 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { rate: 0 }); chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ - remoteChainSelector: CCIP_AVAX_CHAIN_SELECTOR, + remoteChainSelector: chainSelector, allowed: true, - remotePoolAddress: abi.encode(address(0)), // TODO: Set after deployment? - remoteTokenAddress: abi.encode(address(0)), // TODO: Set after deployment? + remotePoolAddress: abi.encode(remotePool), + remoteTokenAddress: abi.encode(remoteToken), outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); diff --git a/src/20241104_Multi_GHOAvaxLaunch/config.ts b/src/20241104_Multi_GHOAvaxLaunch/config.ts index 71e5327b5..c9897424a 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/config.ts +++ b/src/20241104_Multi_GHOAvaxLaunch/config.ts @@ -1,7 +1,7 @@ import {ConfigFile} from '../../generator/types'; export const config: ConfigFile = { rootOptions: { - title: 'GHOAvaxLaunch', + title: 'GHO Avax Launch', author: 'Aave Labs', discussion: 'https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339', From b17cfa41370d47ebee550e1e74001cac8ba29f6e Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 6 Nov 2024 19:05:39 -0800 Subject: [PATCH 15/58] feat: Accept token administrator role --- foundry.toml | 2 +- ...AaveV3Avalanche_GHOAvaxLaunch_20241104.sol | 19 +++++++++++++------ .../AaveV3Ethereum_GHOAvaxLaunch_20241104.sol | 11 +++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/foundry.toml b/foundry.toml index 42e201d77..ee6bd7f5c 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,7 +2,7 @@ src = 'src' test = 'tests' script = 'scripts' -solc = '0.8.20' +solc = '0.8.24' out = 'out' bytecode_hash = 'none' libs = ['lib'] diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol index c33838020..e699d5e8b 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol @@ -8,12 +8,15 @@ import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent- import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; library Utils { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + // TODO: Wait for token admin registry to be deployed, and get proper address + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; @@ -62,10 +65,11 @@ library Utils { * 3. Accept ownership of CCIP TokenPool * 4. Configure CCIP TokenPool for Ethereum * 5. Configure CCIP TokenPool for Arbitrum - * 6. Add CCIP TokenPool as GHO Facilitator - * 7. Accept administrator role from Chainlink token manager - * 8. List GHO on Avax in separate payload - because there is a delay to activate lane - * 9. Supply GHO to the Aave protocol + * 6. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) + * 7. Accept administrator role from Chainlink token admin registry + * 8. Link token to pool on Chainlink token admin registry + * 9. List GHO on Avax in separate payload - because there is a delay to activate lane + * 10. Supply GHO to the Aave protocol */ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { function execute() external { @@ -102,12 +106,15 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { ); // 7. Accept administrator role from Chainlink token manager + TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(ghoToken); + + // 8. Link token to pool on Chainlink token admin registry // TODO - // 8. List GHO on Avax in separate payload + // 9. List GHO on Avax in separate payload // TODO - // 9. Supply GHO to the Aave protocol + // 10. Supply GHO to the Aave protocol // TODO } diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol index 04e2a6345..a651525e3 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol @@ -8,6 +8,7 @@ import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent- import {UpgradeableLockReleaseTokenPool} from 'ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol'; import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; /** * @title GHO Avax Launch @@ -19,10 +20,14 @@ import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; * 2. Accept ownership of CCIP TokenPool * 3. Configure CCIP TokenPool for Arbitrum * 4. Configure CCIP TokenPool for Avalanche + * 5. Accept administrator role from Chainlink token manager + * 6. Link token to pool on Chainlink token admin registry */ contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0x411dE17f12D1A34ecC7F45f49844626267c75e81; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + // TODO: Wait for token admin registry to be deployed, and get proper address + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; uint256 public constant CCIP_BRIDGE_LIMIT = 25_000_000e18; // 25M uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; @@ -42,6 +47,12 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { // TODO: Set remote pool and token addresses after deployment? _configureCcipTokenPool(tokenPool, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); + // 5. Accept Administrator role from Chainlink token manager + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(MiscEthereum.GHO_TOKEN); + + // 6. Link token to pool on Chainlink token admin registry + // TODO + // TODO: Migrate funds? } From 6211627f4e1ef175ebd49e4e027b836e7508e4b0 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 6 Nov 2024 19:08:44 -0800 Subject: [PATCH 16/58] feat: Link token to pool --- .../AaveV3Avalanche_GHOAvaxLaunch_20241104.sol | 2 +- .../AaveV3Ethereum_GHOAvaxLaunch_20241104.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol index e699d5e8b..8857e5fb8 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol @@ -109,7 +109,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(ghoToken); // 8. Link token to pool on Chainlink token admin registry - // TODO + TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).setPool(ghoToken, tokenPool); // 9. List GHO on Avax in separate payload // TODO diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol index a651525e3..57a90d4f3 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol @@ -51,7 +51,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(MiscEthereum.GHO_TOKEN); // 6. Link token to pool on Chainlink token admin registry - // TODO + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(MiscEthereum.GHO_TOKEN, tokenPool); // TODO: Migrate funds? } From e8e791bfde99cb0ab5ee2fe014ace207ef67dca7 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 6 Nov 2024 19:58:54 -0800 Subject: [PATCH 17/58] feat: List gho on avax --- ...AaveV3Avalanche_GHOAvaxLaunch_20241104.sol | 67 ++++++++++++++++--- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol index 8857e5fb8..a375d794f 100644 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol +++ b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol @@ -1,7 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import {AaveV3Avalanche, AaveV3AvalancheEModes} from 'aave-address-book/AaveV3Avalanche.sol'; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadAvalanche.sol'; +import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol'; +import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; +import {IV3RateStrategyFactory} from 'lib/gho-core/lib/aave-stk-v1-5/lib/aave-helpers/src/v3-config-engine/IV3RateStrategyFactory.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; @@ -11,6 +16,8 @@ import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; library Utils { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; @@ -68,8 +75,6 @@ library Utils { * 6. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) * 7. Accept administrator role from Chainlink token admin registry * 8. Link token to pool on Chainlink token admin registry - * 9. List GHO on Avax in separate payload - because there is a delay to activate lane - * 10. Supply GHO to the Aave protocol */ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { function execute() external { @@ -110,12 +115,6 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { // 8. Link token to pool on Chainlink token admin registry TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).setPool(ghoToken, tokenPool); - - // 9. List GHO on Avax in separate payload - // TODO - - // 10. Supply GHO to the Aave protocol - // TODO } function _configureCcipTokenPool( @@ -143,3 +142,55 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { UpgradeableBurnMintTokenPool(tokenPool).applyChainUpdates(chainUpdates); } } + +// TODO: Determine appropriate procedure to have these 2 as separate payload, same AIP +/* + * @dev This payload consists of the following set of actions: + * 1. List GHO on Avax in separate payload - because there is a delay to activate lane + * 2. Supply GHO to the Aave protocol + */ +contract GhoAvaxListing is AaveV3PayloadAvalanche { + using SafeERC20 for IERC20; + + uint256 constant GHO_SEED_AMOUNT = 1_000_000e18; // TODO: Determine appropriate seed amount + address ghoToken; + + constructor(address ghoToken) { + ghoToken = ghoToken; + } + + function newListings() public view override returns (IAaveV3ConfigEngine.Listing[] memory) { + IAaveV3ConfigEngine.Listing[] memory listings = new IAaveV3ConfigEngine.Listing[](1); + + listings[0] = IAaveV3ConfigEngine.Listing({ + asset: ghoToken, + assetSymbol: 'GHO', + priceFeed: 0xB05984aD83C20b3ADE7bf97a9a0Cb539DDE28DBb, // TODO: Correct price feed + enabledToBorrow: EngineFlags.ENABLED, + borrowableInIsolation: EngineFlags.DISABLED, + withSiloedBorrowing: EngineFlags.DISABLED, + flashloanable: EngineFlags.ENABLED, + ltv: 0, + liqThreshold: 0, + liqBonus: 0, + reserveFactor: 10_00, + supplyCap: 5_000_000, + borrowCap: 4_500_000, + debtCeiling: 0, + liqProtocolFee: 0, + rateStrategyParams: IAaveV3ConfigEngine.InterestRateInputData({ + optimalUsageRatio: _bpsToRay(90_00), + baseVariableBorrowRate: _bpsToRay(0), + variableRateSlope1: _bpsToRay(12_00), + variableRateSlope2: _bpsToRay(65_00) + }) + }); + + return listings; + } + + function _postExecute() internal override { + IERC20(ghoToken).forceApprove(address(AaveV3Avalanche.POOL), GHO_SEED_AMOUNT); + AaveV3Avalanche.POOL.supply(ghoToken, GHO_SEED_AMOUNT, address(0), 0); + } +} From be994cc798fd960422bca892c5526e33813e61e6 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 6 Nov 2024 20:38:35 -0800 Subject: [PATCH 18/58] feat: Generate aip files --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 15 +++ ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 28 +++++ ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 15 +++ ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 28 +++++ .../AaveV3Ethereum_GHOAvaxLaunch_20241106.sol | 15 +++ ...aveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 28 +++++ .../GHOAvaxLaunch.md | 23 ++++ .../GHOAvaxLaunch_20241106.s.sol | 117 ++++++++++++++++++ src/20241106_Multi_GHOAvaxLaunch/config.ts | 20 +++ 9 files changed, 289 insertions(+) create mode 100644 src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol create mode 100644 src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol create mode 100644 src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol create mode 100644 src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol create mode 100644 src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol create mode 100644 src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol create mode 100644 src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md create mode 100644 src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241106.s.sol create mode 100644 src/20241106_Multi_GHOAvaxLaunch/config.ts diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol new file mode 100644 index 000000000..10e65beb5 --- /dev/null +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +/** + * @title GHOAvaxLaunch + * @author Aave Labs + * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 + * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + */ +contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { + function execute() external { + // custom code goes here + } +} diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol new file mode 100644 index 000000000..8708a8174 --- /dev/null +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; + +import 'forge-std/Test.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; + +/** + * @dev Test for AaveV3Arbitrum_GHOAvaxLaunch_20241106 + * command: FOUNDRY_PROFILE=arbitrum forge test --match-path=src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol -vv + */ +contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { + AaveV3Arbitrum_GHOAvaxLaunch_20241106 internal proposal; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('arbitrum'), 271862002); + proposal = new AaveV3Arbitrum_GHOAvaxLaunch_20241106(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest('AaveV3Arbitrum_GHOAvaxLaunch_20241106', AaveV3Arbitrum.POOL, address(proposal)); + } +} diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol new file mode 100644 index 000000000..31bbabb08 --- /dev/null +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +/** + * @title GHOAvaxLaunch + * @author Aave Labs + * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 + * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + */ +contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { + function execute() external { + // custom code goes here + } +} diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol new file mode 100644 index 000000000..690dab7c3 --- /dev/null +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; + +import 'forge-std/Test.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; + +/** + * @dev Test for AaveV3Avalanche_GHOAvaxLaunch_20241106 + * command: FOUNDRY_PROFILE=avalanche forge test --match-path=src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol -vv + */ +contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { + AaveV3Avalanche_GHOAvaxLaunch_20241106 internal proposal; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('avalanche'), 52758592); + proposal = new AaveV3Avalanche_GHOAvaxLaunch_20241106(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest('AaveV3Avalanche_GHOAvaxLaunch_20241106', AaveV3Avalanche.POOL, address(proposal)); + } +} diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol new file mode 100644 index 000000000..6ecaef5c0 --- /dev/null +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +/** + * @title GHOAvaxLaunch + * @author Aave Labs + * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 + * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + */ +contract AaveV3Ethereum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { + function execute() external { + // custom code goes here + } +} diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol new file mode 100644 index 000000000..3e48e9836 --- /dev/null +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; + +import 'forge-std/Test.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {AaveV3Ethereum_GHOAvaxLaunch_20241106} from './AaveV3Ethereum_GHOAvaxLaunch_20241106.sol'; + +/** + * @dev Test for AaveV3Ethereum_GHOAvaxLaunch_20241106 + * command: FOUNDRY_PROFILE=mainnet forge test --match-path=src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol -vv + */ +contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { + AaveV3Ethereum_GHOAvaxLaunch_20241106 internal proposal; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('mainnet'), 21133428); + proposal = new AaveV3Ethereum_GHOAvaxLaunch_20241106(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest('AaveV3Ethereum_GHOAvaxLaunch_20241106', AaveV3Ethereum.POOL, address(proposal)); + } +} diff --git a/src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md b/src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md new file mode 100644 index 000000000..bde189fcc --- /dev/null +++ b/src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md @@ -0,0 +1,23 @@ +--- +title: "GHOAvaxLaunch" +author: "Aave Labs" +discussions: "https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339" +snapshot: "https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719" +--- + +## Simple Summary + +## Motivation + +## Specification + +## References + +- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol), [AaveV3Arbitrum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol) +- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol), [AaveV3Arbitrum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol) +- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719) +- [Discussion](https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241106.s.sol b/src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241106.s.sol new file mode 100644 index 000000000..f28d3b3db --- /dev/null +++ b/src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241106.s.sol @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/src/GovV3Helpers.sol'; +import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; +import {EthereumScript, AvalancheScript, ArbitrumScript} from 'solidity-utils/contracts/utils/ScriptUtils.sol'; +import {AaveV3Ethereum_GHOAvaxLaunch_20241106} from './AaveV3Ethereum_GHOAvaxLaunch_20241106.sol'; +import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; +import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; + +/** + * @dev Deploy Ethereum + * deploy-command: make deploy-ledger contract=src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241106.s.sol:DeployEthereum chain=mainnet + * verify-command: FOUNDRY_PROFILE=mainnet npx catapulta-verify -b broadcast/GHOAvaxLaunch_20241106.s.sol/1/run-latest.json + */ +contract DeployEthereum is EthereumScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Ethereum_GHOAvaxLaunch_20241106).creationCode + ); + + // compose action + IPayloadsControllerCore.ExecutionAction[] + memory actions = new IPayloadsControllerCore.ExecutionAction[](1); + actions[0] = GovV3Helpers.buildAction(payload0); + + // register action at payloadsController + GovV3Helpers.createPayload(actions); + } +} + +/** + * @dev Deploy Avalanche + * deploy-command: make deploy-ledger contract=src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241106.s.sol:DeployAvalanche chain=avalanche + * verify-command: FOUNDRY_PROFILE=avalanche npx catapulta-verify -b broadcast/GHOAvaxLaunch_20241106.s.sol/43114/run-latest.json + */ +contract DeployAvalanche is AvalancheScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Avalanche_GHOAvaxLaunch_20241106).creationCode + ); + + // compose action + IPayloadsControllerCore.ExecutionAction[] + memory actions = new IPayloadsControllerCore.ExecutionAction[](1); + actions[0] = GovV3Helpers.buildAction(payload0); + + // register action at payloadsController + GovV3Helpers.createPayload(actions); + } +} + +/** + * @dev Deploy Arbitrum + * deploy-command: make deploy-ledger contract=src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241106.s.sol:DeployArbitrum chain=arbitrum + * verify-command: FOUNDRY_PROFILE=arbitrum npx catapulta-verify -b broadcast/GHOAvaxLaunch_20241106.s.sol/42161/run-latest.json + */ +contract DeployArbitrum is ArbitrumScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Arbitrum_GHOAvaxLaunch_20241106).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/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241106.s.sol:CreateProposal chain=mainnet + */ +contract CreateProposal is EthereumScript { + function run() external { + // create payloads + PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](3); + + // compose actions for validation + IPayloadsControllerCore.ExecutionAction[] + memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1); + actionsEthereum[0] = GovV3Helpers.buildAction( + type(AaveV3Ethereum_GHOAvaxLaunch_20241106).creationCode + ); + payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); + + IPayloadsControllerCore.ExecutionAction[] + memory actionsAvalanche = new IPayloadsControllerCore.ExecutionAction[](1); + actionsAvalanche[0] = GovV3Helpers.buildAction( + type(AaveV3Avalanche_GHOAvaxLaunch_20241106).creationCode + ); + payloads[1] = GovV3Helpers.buildAvalanchePayload(vm, actionsAvalanche); + + IPayloadsControllerCore.ExecutionAction[] + memory actionsArbitrum = new IPayloadsControllerCore.ExecutionAction[](1); + actionsArbitrum[0] = GovV3Helpers.buildAction( + type(AaveV3Arbitrum_GHOAvaxLaunch_20241106).creationCode + ); + payloads[2] = GovV3Helpers.buildArbitrumPayload(vm, actionsArbitrum); + + // create proposal + vm.startBroadcast(); + GovV3Helpers.createProposal( + vm, + payloads, + GovernanceV3Ethereum.VOTING_PORTAL_ETH_POL, + GovV3Helpers.ipfsHashFile(vm, 'src/20241106_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md') + ); + } +} diff --git a/src/20241106_Multi_GHOAvaxLaunch/config.ts b/src/20241106_Multi_GHOAvaxLaunch/config.ts new file mode 100644 index 000000000..6b2c8640b --- /dev/null +++ b/src/20241106_Multi_GHOAvaxLaunch/config.ts @@ -0,0 +1,20 @@ +import {ConfigFile} from '../../generator/types'; +export const config: ConfigFile = { + rootOptions: { + title: 'GHOAvaxLaunch', + author: 'Aave Labs', + discussion: + 'https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339', + snapshot: + 'https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719', + pools: ['AaveV3Ethereum', 'AaveV3Avalanche', 'AaveV3Arbitrum'], + shortName: 'GHOAvaxLaunch', + date: '20241106', + votingNetwork: 'POLYGON', + }, + poolOptions: { + AaveV3Ethereum: {configs: {OTHERS: {}}, cache: {blockNumber: 21133428}}, + AaveV3Avalanche: {configs: {OTHERS: {}}, cache: {blockNumber: 52758592}}, + AaveV3Arbitrum: {configs: {OTHERS: {}}, cache: {blockNumber: 271862002}}, + }, +}; From 54c4789f999fd3647f7a0fbecf75397d2c45569d Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 6 Nov 2024 20:45:08 -0800 Subject: [PATCH 19/58] chore: Add v1.5 token pool dep --- .gitmodules | 4 ++++ lib/ccip | 1 + 2 files changed, 5 insertions(+) create mode 160000 lib/ccip diff --git a/.gitmodules b/.gitmodules index f7316a1d6..74efc2a48 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "lib/aave-helpers"] path = lib/aave-helpers url = https://github.com/bgd-labs/aave-helpers +[submodule "lib/ccip"] + path = lib/ccip + url = https://github.com/aave/ccip.git + branch = feat/1_5_token_pool diff --git a/lib/ccip b/lib/ccip new file mode 160000 index 000000000..93b0f9333 --- /dev/null +++ b/lib/ccip @@ -0,0 +1 @@ +Subproject commit 93b0f9333c13a24743413ebcf8e7739fba055eae From 7e4c7fd381f73a59e358258cfbf7ee16d69f1a61 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 6 Nov 2024 20:58:40 -0800 Subject: [PATCH 20/58] chore: Move existing proposals into new template --- ...AaveV3Avalanche_GHOAvaxLaunch_20241104.sol | 196 ------------------ ...veV3Avalanche_GHOAvaxLaunch_20241104.t.sol | 28 --- .../AaveV3Ethereum_GHOAvaxLaunch_20241104.sol | 101 --------- ...aveV3Ethereum_GHOAvaxLaunch_20241104.t.sol | 28 --- .../GHOAvaxLaunch.md | 23 -- .../GHOAvaxLaunch_20241104.s.sol | 87 -------- src/20241104_Multi_GHOAvaxLaunch/config.ts | 19 -- ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 185 ++++++++++++++++- .../AaveV3Ethereum_GHOAvaxLaunch_20241106.sol | 90 +++++++- src/20241106_Multi_GHOAvaxLaunch/config.ts | 2 +- 10 files changed, 272 insertions(+), 487 deletions(-) delete mode 100644 src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol delete mode 100644 src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol delete mode 100644 src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol delete mode 100644 src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol delete mode 100644 src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md delete mode 100644 src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol delete mode 100644 src/20241104_Multi_GHOAvaxLaunch/config.ts diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol deleted file mode 100644 index a375d794f..000000000 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol +++ /dev/null @@ -1,196 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {AaveV3Avalanche, AaveV3AvalancheEModes} from 'aave-address-book/AaveV3Avalanche.sol'; -import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; -import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadAvalanche.sol'; -import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol'; -import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; -import {IV3RateStrategyFactory} from 'lib/gho-core/lib/aave-stk-v1-5/lib/aave-helpers/src/v3-config-engine/IV3RateStrategyFactory.sol'; -import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; -import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; -import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; -import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; -import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; -import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; -import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; -import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; -import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; -import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; - -library Utils { - address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; - address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; - // TODO: Wait for token admin registry to be deployed, and get proper address - address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; - uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M - uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; - uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; - - function deployGhoToken() internal returns (address) { - address imple = address(new UpgradeableGhoToken()); - - bytes memory ghoTokenInitParams = abi.encodeWithSignature( - 'initialize(address)', - GovernanceV3Avalanche.EXECUTOR_LVL_1 // owner - ); - return - address( - new TransparentUpgradeableProxy(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) - ); - } - - function deployCcipTokenPool(address ghoToken) external returns (address) { - address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, CCIP_RMN_PROXY, false)); - - bytes memory tokenPoolInitParams = abi.encodeWithSignature( - 'initialize(address,address[],address)', - GovernanceV3Avalanche.EXECUTOR_LVL_1, // owner - new address[](0), // allowList - CCIP_ROUTER // router - ); - return - address( - new TransparentUpgradeableProxy( - imple, // logic - MiscAvalanche.PROXY_ADMIN, // proxy admin - tokenPoolInitParams // data - ) - ); - } -} - -/** - * @title GHO Avax Launch - * @author Aave Labs - * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 - * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 - * @dev This payload consists of the following set of actions: - * 1. Deploy GHO - * 2. Deploy BurnMintTokenPool - * 3. Accept ownership of CCIP TokenPool - * 4. Configure CCIP TokenPool for Ethereum - * 5. Configure CCIP TokenPool for Arbitrum - * 6. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) - * 7. Accept administrator role from Chainlink token admin registry - * 8. Link token to pool on Chainlink token admin registry - */ -contract AaveV3Avalanche_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { - function execute() external { - // 1. Deploy GHO - address ghoToken = Utils.deployGhoToken(); - - // 2. Deploy BurnMintTokenPool - address tokenPool = Utils.deployCcipTokenPool(ghoToken); - - // 3. Accept TokenPool ownership - UpgradeableBurnMintTokenPool(tokenPool).acceptOwnership(); - - // 4. Configure CCIP TokenPool for Ethereum - // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, Utils.CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); - - // 5. Configure CCIP TokenPool for Arbitrum - // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, Utils.CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); - - // 6. Add CCIP TokenPool as GHO Facilitator - IGhoToken(ghoToken).grantRole( - IGhoToken(ghoToken).FACILITATOR_MANAGER_ROLE(), - GovernanceV3Avalanche.EXECUTOR_LVL_1 - ); - IGhoToken(ghoToken).grantRole( - IGhoToken(ghoToken).BUCKET_MANAGER_ROLE(), - GovernanceV3Avalanche.EXECUTOR_LVL_1 - ); - IGhoToken(ghoToken).addFacilitator( - tokenPool, - 'CCIP TokenPool', - uint128(Utils.CCIP_BUCKET_CAPACITY) - ); - - // 7. Accept administrator role from Chainlink token manager - TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(ghoToken); - - // 8. Link token to pool on Chainlink token admin registry - TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).setPool(ghoToken, tokenPool); - } - - function _configureCcipTokenPool( - address tokenPool, - uint64 chainSelector, - address remotePool, - address remoteToken - ) internal { - UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( - 1 - ); - RateLimiter.Config memory rateConfig = RateLimiter.Config({ - isEnabled: false, - capacity: 0, - rate: 0 - }); - chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ - remoteChainSelector: chainSelector, - allowed: true, - remotePoolAddress: abi.encode(remotePool), - remoteTokenAddress: abi.encode(remoteToken), - outboundRateLimiterConfig: rateConfig, - inboundRateLimiterConfig: rateConfig - }); - UpgradeableBurnMintTokenPool(tokenPool).applyChainUpdates(chainUpdates); - } -} - -// TODO: Determine appropriate procedure to have these 2 as separate payload, same AIP -/* - * @dev This payload consists of the following set of actions: - * 1. List GHO on Avax in separate payload - because there is a delay to activate lane - * 2. Supply GHO to the Aave protocol - */ -contract GhoAvaxListing is AaveV3PayloadAvalanche { - using SafeERC20 for IERC20; - - uint256 constant GHO_SEED_AMOUNT = 1_000_000e18; // TODO: Determine appropriate seed amount - address ghoToken; - - constructor(address ghoToken) { - ghoToken = ghoToken; - } - - function newListings() public view override returns (IAaveV3ConfigEngine.Listing[] memory) { - IAaveV3ConfigEngine.Listing[] memory listings = new IAaveV3ConfigEngine.Listing[](1); - - listings[0] = IAaveV3ConfigEngine.Listing({ - asset: ghoToken, - assetSymbol: 'GHO', - priceFeed: 0xB05984aD83C20b3ADE7bf97a9a0Cb539DDE28DBb, // TODO: Correct price feed - enabledToBorrow: EngineFlags.ENABLED, - borrowableInIsolation: EngineFlags.DISABLED, - withSiloedBorrowing: EngineFlags.DISABLED, - flashloanable: EngineFlags.ENABLED, - ltv: 0, - liqThreshold: 0, - liqBonus: 0, - reserveFactor: 10_00, - supplyCap: 5_000_000, - borrowCap: 4_500_000, - debtCeiling: 0, - liqProtocolFee: 0, - rateStrategyParams: IAaveV3ConfigEngine.InterestRateInputData({ - optimalUsageRatio: _bpsToRay(90_00), - baseVariableBorrowRate: _bpsToRay(0), - variableRateSlope1: _bpsToRay(12_00), - variableRateSlope2: _bpsToRay(65_00) - }) - }); - - return listings; - } - - function _postExecute() internal override { - IERC20(ghoToken).forceApprove(address(AaveV3Avalanche.POOL), GHO_SEED_AMOUNT); - AaveV3Avalanche.POOL.supply(ghoToken, GHO_SEED_AMOUNT, address(0), 0); - } -} diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol deleted file mode 100644 index e687640f9..000000000 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; - -import 'forge-std/Test.sol'; -import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; -import {AaveV3Avalanche_GHOAvaxLaunch_20241104} from './AaveV3Avalanche_GHOAvaxLaunch_20241104.sol'; - -/** - * @dev Test for AaveV3Avalanche_GHOAvaxLaunch_20241104 - * command: FOUNDRY_PROFILE=avalanche forge test --match-path=src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol -vv - */ -contract AaveV3Avalanche_GHOAvaxLaunch_20241104_Test is ProtocolV3TestBase { - AaveV3Avalanche_GHOAvaxLaunch_20241104 internal proposal; - - function setUp() public { - vm.createSelectFork(vm.rpcUrl('avalanche'), 52673463); - proposal = new AaveV3Avalanche_GHOAvaxLaunch_20241104(); - } - - /** - * @dev executes the generic test suite including e2e and config snapshots - */ - function test_defaultProposalExecution() public { - defaultTest('AaveV3Avalanche_GHOAvaxLaunch_20241104', AaveV3Avalanche.POOL, address(proposal)); - } -} diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol deleted file mode 100644 index 57a90d4f3..000000000 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; -import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; -import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; -import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; -import {UpgradeableLockReleaseTokenPool} from 'ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol'; -import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; -import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; -import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; - -/** - * @title GHO Avax Launch - * @author Aave Labs - * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 - * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 - * @dev This payload consists of the following set of actions: - * 1. Deploy LockReleaseTokenPool - * 2. Accept ownership of CCIP TokenPool - * 3. Configure CCIP TokenPool for Arbitrum - * 4. Configure CCIP TokenPool for Avalanche - * 5. Accept administrator role from Chainlink token manager - * 6. Link token to pool on Chainlink token admin registry - */ -contract AaveV3Ethereum_GHOAvaxLaunch_20241104 is IProposalGenericExecutor { - address public constant CCIP_RMN_PROXY = 0x411dE17f12D1A34ecC7F45f49844626267c75e81; - address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; - // TODO: Wait for token admin registry to be deployed, and get proper address - address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; - uint256 public constant CCIP_BRIDGE_LIMIT = 25_000_000e18; // 25M - uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; - uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; - - function execute() external { - // 1. Deploy LockReleaseTokenPool - address tokenPool = _deployCcipTokenPool(); - - // 2. Accept TokenPool ownership - UpgradeableLockReleaseTokenPool(tokenPool).acceptOwnership(); - - // 3. Configure CCIP for Arbitrum - // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); - - // 4. Configure CCIP for Avalanche - // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); - - // 5. Accept Administrator role from Chainlink token manager - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(MiscEthereum.GHO_TOKEN); - - // 6. Link token to pool on Chainlink token admin registry - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(MiscEthereum.GHO_TOKEN, tokenPool); - - // TODO: Migrate funds? - } - - function _deployCcipTokenPool() internal returns (address) { - address imple = address( - new UpgradeableLockReleaseTokenPool(MiscEthereum.GHO_TOKEN, CCIP_RMN_PROXY, false, true) - ); - - bytes memory tokenPoolInitParams = abi.encodeWithSignature( - 'initialize(address,address[],address,uint256)', - GovernanceV3Ethereum.EXECUTOR_LVL_1, // owner - new address[](0), // allowList - CCIP_ROUTER, // router - CCIP_BRIDGE_LIMIT // bridgeLimit - ); - return - address( - new TransparentUpgradeableProxy(imple, MiscEthereum.PROXY_ADMIN, tokenPoolInitParams) - ); - } - - function _configureCcipTokenPool( - address tokenPool, - uint64 chainSelector, - address remotePool, - address remoteToken - ) internal { - UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( - 1 - ); - RateLimiter.Config memory rateConfig = RateLimiter.Config({ - isEnabled: false, - capacity: 0, - rate: 0 - }); - chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ - remoteChainSelector: chainSelector, - allowed: true, - remotePoolAddress: abi.encode(remotePool), - remoteTokenAddress: abi.encode(remoteToken), - outboundRateLimiterConfig: rateConfig, - inboundRateLimiterConfig: rateConfig - }); - UpgradeableLockReleaseTokenPool(tokenPool).applyChainUpdates(chainUpdates); - } -} diff --git a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol b/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol deleted file mode 100644 index 029fbed59..000000000 --- a/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; - -import 'forge-std/Test.sol'; -import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; -import {AaveV3Ethereum_GHOAvaxLaunch_20241104} from './AaveV3Ethereum_GHOAvaxLaunch_20241104.sol'; - -/** - * @dev Test for AaveV3Ethereum_GHOAvaxLaunch_20241104 - * command: FOUNDRY_PROFILE=mainnet forge test --match-path=src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol -vv - */ -contract AaveV3Ethereum_GHOAvaxLaunch_20241104_Test is ProtocolV3TestBase { - AaveV3Ethereum_GHOAvaxLaunch_20241104 internal proposal; - - function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 21118953); - proposal = new AaveV3Ethereum_GHOAvaxLaunch_20241104(); - } - - /** - * @dev executes the generic test suite including e2e and config snapshots - */ - function test_defaultProposalExecution() public { - defaultTest('AaveV3Ethereum_GHOAvaxLaunch_20241104', AaveV3Ethereum.POOL, address(proposal)); - } -} diff --git a/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md b/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md deleted file mode 100644 index 9953cf858..000000000 --- a/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: "GHOAvaxLaunch" -author: "Aave Labs" -discussions: "https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339" -snapshot: "https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719" ---- - -## Simple Summary - -## Motivation - -## Specification - -## References - -- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.sol) -- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241104_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241104.t.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20241104_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241104.t.sol) -- [Snapshot](https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719) -- [Discussion](https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339) - -## Copyright - -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol b/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol deleted file mode 100644 index b2637d8da..000000000 --- a/src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/src/GovV3Helpers.sol'; -import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; -import {EthereumScript, AvalancheScript} from 'solidity-utils/contracts/utils/ScriptUtils.sol'; -import {AaveV3Ethereum_GHOAvaxLaunch_20241104} from './AaveV3Ethereum_GHOAvaxLaunch_20241104.sol'; -import {AaveV3Avalanche_GHOAvaxLaunch_20241104} from './AaveV3Avalanche_GHOAvaxLaunch_20241104.sol'; - -/** - * @dev Deploy Ethereum - * deploy-command: make deploy-ledger contract=src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol:DeployEthereum chain=mainnet - * verify-command: FOUNDRY_PROFILE=mainnet npx catapulta-verify -b broadcast/GHOAvaxLaunch_20241104.s.sol/1/run-latest.json - */ -contract DeployEthereum is EthereumScript { - function run() external broadcast { - // deploy payloads - address payload0 = GovV3Helpers.deployDeterministic( - type(AaveV3Ethereum_GHOAvaxLaunch_20241104).creationCode - ); - - // compose action - IPayloadsControllerCore.ExecutionAction[] - memory actions = new IPayloadsControllerCore.ExecutionAction[](1); - actions[0] = GovV3Helpers.buildAction(payload0); - - // register action at payloadsController - GovV3Helpers.createPayload(actions); - } -} - -/** - * @dev Deploy Avalanche - * deploy-command: make deploy-ledger contract=src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol:DeployAvalanche chain=avalanche - * verify-command: FOUNDRY_PROFILE=avalanche npx catapulta-verify -b broadcast/GHOAvaxLaunch_20241104.s.sol/43114/run-latest.json - */ -contract DeployAvalanche is AvalancheScript { - function run() external broadcast { - // deploy payloads - address payload0 = GovV3Helpers.deployDeterministic( - type(AaveV3Avalanche_GHOAvaxLaunch_20241104).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/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch_20241104.s.sol:CreateProposal chain=mainnet - */ -contract CreateProposal is EthereumScript { - function run() external { - // create payloads - PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](2); - - // compose actions for validation - IPayloadsControllerCore.ExecutionAction[] - memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1); - actionsEthereum[0] = GovV3Helpers.buildAction( - type(AaveV3Ethereum_GHOAvaxLaunch_20241104).creationCode - ); - payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); - - IPayloadsControllerCore.ExecutionAction[] - memory actionsAvalanche = new IPayloadsControllerCore.ExecutionAction[](1); - actionsAvalanche[0] = GovV3Helpers.buildAction( - type(AaveV3Avalanche_GHOAvaxLaunch_20241104).creationCode - ); - payloads[1] = GovV3Helpers.buildAvalanchePayload(vm, actionsAvalanche); - - // create proposal - vm.startBroadcast(); - GovV3Helpers.createProposal( - vm, - payloads, - GovernanceV3Ethereum.VOTING_PORTAL_ETH_POL, - GovV3Helpers.ipfsHashFile(vm, 'src/20241104_Multi_GHOAvaxLaunch/GHOAvaxLaunch.md') - ); - } -} diff --git a/src/20241104_Multi_GHOAvaxLaunch/config.ts b/src/20241104_Multi_GHOAvaxLaunch/config.ts deleted file mode 100644 index c9897424a..000000000 --- a/src/20241104_Multi_GHOAvaxLaunch/config.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {ConfigFile} from '../../generator/types'; -export const config: ConfigFile = { - rootOptions: { - title: 'GHO Avax Launch', - author: 'Aave Labs', - discussion: - 'https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339', - snapshot: - 'https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719', - pools: ['AaveV3Ethereum', 'AaveV3Avalanche'], - shortName: 'GHOAvaxLaunch', - date: '20241104', - votingNetwork: 'POLYGON', - }, - poolOptions: { - AaveV3Ethereum: {configs: {OTHERS: {}}, cache: {blockNumber: 21118953}}, - AaveV3Avalanche: {configs: {OTHERS: {}}, cache: {blockNumber: 52673463}}, - }, -}; diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 31bbabb08..21d73ca11 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -1,15 +1,196 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import {AaveV3Avalanche, AaveV3AvalancheEModes} from 'aave-address-book/AaveV3Avalanche.sol'; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadAvalanche.sol'; +import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol'; +import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; +import {IV3RateStrategyFactory} from 'lib/gho-core/lib/aave-stk-v1-5/lib/aave-helpers/src/v3-config-engine/IV3RateStrategyFactory.sol'; +import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; +import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; +import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; +import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; + +library Utils { + address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; + address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + // TODO: Wait for token admin registry to be deployed, and get proper address + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M + uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; + uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; + + function deployGhoToken() internal returns (address) { + address imple = address(new UpgradeableGhoToken()); + + bytes memory ghoTokenInitParams = abi.encodeWithSignature( + 'initialize(address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1 // owner + ); + return + address( + new TransparentUpgradeableProxy(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) + ); + } + + function deployCcipTokenPool(address ghoToken) external returns (address) { + address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, CCIP_RMN_PROXY, false)); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + CCIP_ROUTER // router + ); + return + address( + new TransparentUpgradeableProxy( + imple, // logic + MiscAvalanche.PROXY_ADMIN, // proxy admin + tokenPoolInitParams // data + ) + ); + } +} + /** - * @title GHOAvaxLaunch + * @title GHO Avax Launch * @author Aave Labs * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + * @dev This payload consists of the following set of actions: + * 1. Deploy GHO + * 2. Deploy BurnMintTokenPool + * 3. Accept ownership of CCIP TokenPool + * 4. Configure CCIP TokenPool for Ethereum + * 5. Configure CCIP TokenPool for Arbitrum + * 6. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) + * 7. Accept administrator role from Chainlink token admin registry + * 8. Link token to pool on Chainlink token admin registry */ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { function execute() external { - // custom code goes here + // 1. Deploy GHO + address ghoToken = Utils.deployGhoToken(); + + // 2. Deploy BurnMintTokenPool + address tokenPool = Utils.deployCcipTokenPool(ghoToken); + + // 3. Accept TokenPool ownership + UpgradeableBurnMintTokenPool(tokenPool).acceptOwnership(); + + // 4. Configure CCIP TokenPool for Ethereum + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, Utils.CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); + + // 5. Configure CCIP TokenPool for Arbitrum + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, Utils.CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); + + // 6. Add CCIP TokenPool as GHO Facilitator + IGhoToken(ghoToken).grantRole( + IGhoToken(ghoToken).FACILITATOR_MANAGER_ROLE(), + GovernanceV3Avalanche.EXECUTOR_LVL_1 + ); + IGhoToken(ghoToken).grantRole( + IGhoToken(ghoToken).BUCKET_MANAGER_ROLE(), + GovernanceV3Avalanche.EXECUTOR_LVL_1 + ); + IGhoToken(ghoToken).addFacilitator( + tokenPool, + 'CCIP TokenPool', + uint128(Utils.CCIP_BUCKET_CAPACITY) + ); + + // 7. Accept administrator role from Chainlink token manager + TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(ghoToken); + + // 8. Link token to pool on Chainlink token admin registry + TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).setPool(ghoToken, tokenPool); + } + + function _configureCcipTokenPool( + address tokenPool, + uint64 chainSelector, + address remotePool, + address remoteToken + ) internal { + UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( + 1 + ); + RateLimiter.Config memory rateConfig = RateLimiter.Config({ + isEnabled: false, + capacity: 0, + rate: 0 + }); + chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + allowed: true, + remotePoolAddress: abi.encode(remotePool), + remoteTokenAddress: abi.encode(remoteToken), + outboundRateLimiterConfig: rateConfig, + inboundRateLimiterConfig: rateConfig + }); + UpgradeableBurnMintTokenPool(tokenPool).applyChainUpdates(chainUpdates); + } +} + +// TODO: Determine appropriate procedure to have these 2 as separate payload, same AIP +/* + * @dev This payload consists of the following set of actions: + * 1. List GHO on Avax in separate payload - because there is a delay to activate lane + * 2. Supply GHO to the Aave protocol + */ +contract GhoAvaxListing is AaveV3PayloadAvalanche { + using SafeERC20 for IERC20; + + uint256 constant GHO_SEED_AMOUNT = 1_000_000e18; // TODO: Determine appropriate seed amount + address ghoToken; + + constructor(address ghoToken) { + ghoToken = ghoToken; + } + + function newListings() public view override returns (IAaveV3ConfigEngine.Listing[] memory) { + IAaveV3ConfigEngine.Listing[] memory listings = new IAaveV3ConfigEngine.Listing[](1); + + listings[0] = IAaveV3ConfigEngine.Listing({ + asset: ghoToken, + assetSymbol: 'GHO', + priceFeed: 0xB05984aD83C20b3ADE7bf97a9a0Cb539DDE28DBb, // TODO: Correct price feed + enabledToBorrow: EngineFlags.ENABLED, + borrowableInIsolation: EngineFlags.DISABLED, + withSiloedBorrowing: EngineFlags.DISABLED, + flashloanable: EngineFlags.ENABLED, + ltv: 0, + liqThreshold: 0, + liqBonus: 0, + reserveFactor: 10_00, + supplyCap: 5_000_000, + borrowCap: 4_500_000, + debtCeiling: 0, + liqProtocolFee: 0, + rateStrategyParams: IAaveV3ConfigEngine.InterestRateInputData({ + optimalUsageRatio: _bpsToRay(90_00), + baseVariableBorrowRate: _bpsToRay(0), + variableRateSlope1: _bpsToRay(12_00), + variableRateSlope2: _bpsToRay(65_00) + }) + }); + + return listings; + } + + function _postExecute() internal override { + IERC20(ghoToken).forceApprove(address(AaveV3Avalanche.POOL), GHO_SEED_AMOUNT); + AaveV3Avalanche.POOL.supply(ghoToken, GHO_SEED_AMOUNT, address(0), 0); } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol index 6ecaef5c0..f740bfac2 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol @@ -2,14 +2,100 @@ pragma solidity ^0.8.0; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; +import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {UpgradeableLockReleaseTokenPool} from 'ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol'; +import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; + /** - * @title GHOAvaxLaunch + * @title GHO Avax Launch * @author Aave Labs * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + * @dev This payload consists of the following set of actions: + * 1. Deploy LockReleaseTokenPool + * 2. Accept ownership of CCIP TokenPool + * 3. Configure CCIP TokenPool for Arbitrum + * 4. Configure CCIP TokenPool for Avalanche + * 5. Accept administrator role from Chainlink token manager + * 6. Link token to pool on Chainlink token admin registry */ contract AaveV3Ethereum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { + address public constant CCIP_RMN_PROXY = 0x411dE17f12D1A34ecC7F45f49844626267c75e81; + address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + // TODO: Wait for token admin registry to be deployed, and get proper address + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + uint256 public constant CCIP_BRIDGE_LIMIT = 25_000_000e18; // 25M + uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; + uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; + function execute() external { - // custom code goes here + // 1. Deploy LockReleaseTokenPool + address tokenPool = _deployCcipTokenPool(); + + // 2. Accept TokenPool ownership + UpgradeableLockReleaseTokenPool(tokenPool).acceptOwnership(); + + // 3. Configure CCIP for Arbitrum + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); + + // 4. Configure CCIP for Avalanche + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); + + // 5. Accept Administrator role from Chainlink token manager + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(MiscEthereum.GHO_TOKEN); + + // 6. Link token to pool on Chainlink token admin registry + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(MiscEthereum.GHO_TOKEN, tokenPool); + + // TODO: Migrate funds? + } + + function _deployCcipTokenPool() internal returns (address) { + address imple = address( + new UpgradeableLockReleaseTokenPool(MiscEthereum.GHO_TOKEN, CCIP_RMN_PROXY, false, true) + ); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address,uint256)', + GovernanceV3Ethereum.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + CCIP_ROUTER, // router + CCIP_BRIDGE_LIMIT // bridgeLimit + ); + return + address( + new TransparentUpgradeableProxy(imple, MiscEthereum.PROXY_ADMIN, tokenPoolInitParams) + ); + } + + function _configureCcipTokenPool( + address tokenPool, + uint64 chainSelector, + address remotePool, + address remoteToken + ) internal { + UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( + 1 + ); + RateLimiter.Config memory rateConfig = RateLimiter.Config({ + isEnabled: false, + capacity: 0, + rate: 0 + }); + chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + allowed: true, + remotePoolAddress: abi.encode(remotePool), + remoteTokenAddress: abi.encode(remoteToken), + outboundRateLimiterConfig: rateConfig, + inboundRateLimiterConfig: rateConfig + }); + UpgradeableLockReleaseTokenPool(tokenPool).applyChainUpdates(chainUpdates); } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/config.ts b/src/20241106_Multi_GHOAvaxLaunch/config.ts index 6b2c8640b..efff73fff 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/config.ts +++ b/src/20241106_Multi_GHOAvaxLaunch/config.ts @@ -1,7 +1,7 @@ import {ConfigFile} from '../../generator/types'; export const config: ConfigFile = { rootOptions: { - title: 'GHOAvaxLaunch', + title: 'GHO Avax Launch', author: 'Aave Labs', discussion: 'https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339', From c0dfe64dca51593c353b905c74f6c6c75b925adb Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 6 Nov 2024 21:27:53 -0800 Subject: [PATCH 21/58] feat: Arbitrum proposal --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 114 +++++++++++++++++- ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 20 +-- 2 files changed, 123 insertions(+), 11 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index 10e65beb5..77e9b4350 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -1,15 +1,127 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +import {AaveV3Arbitrum, AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; +import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; +import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; + +library Utils { + address public constant CCIP_RMN_PROXY = 0xC311a21e6fEf769344EB1515588B9d535662a145; + address public constant CCIP_ROUTER = 0x141fa059441E0ca23ce184B6A78bafD2A517DdE8; + // TODO: Wait for token admin registry to be deployed, and get proper address + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + uint256 public constant CCIP_BUCKET_CAPACITY = 1_000_000e18; // 1M + uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; + uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; + + function deployCcipTokenPool() external returns (address) { + address imple = address( + new UpgradeableBurnMintTokenPool(AaveV3ArbitrumAssets.GHO_UNDERLYING, CCIP_RMN_PROXY, false) + ); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address)', + GovernanceV3Arbitrum.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + CCIP_ROUTER // router + ); + return + address( + new TransparentUpgradeableProxy( + imple, // logic + MiscArbitrum.PROXY_ADMIN, // proxy admin + tokenPoolInitParams // data + ) + ); + } +} + /** * @title GHOAvaxLaunch * @author Aave Labs * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 + * @dev This payload consists of the following set of actions: + * 1. Deploy BurnMintTokenPool + * 2. Accept ownership of CCIP TokenPool + * 3. Configure CCIP TokenPool for Ethereum + * 4. Configure CCIP TokenPool for Avalanche + * 5. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) + * 6. Accept administrator role from Chainlink token admin registry + * 7. Link token to pool on Chainlink token admin registry */ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { function execute() external { - // custom code goes here + // 1. Deploy BurnMintTokenPool + address tokenPool = Utils.deployCcipTokenPool(); + + // 2. Accept TokenPool ownership + UpgradeableBurnMintTokenPool(tokenPool).acceptOwnership(); + + // 3. Configure CCIP TokenPool for Ethereum + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, Utils.CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); + + // 4. Configure CCIP TokenPool for Avalanche + // TODO: Set remote pool and token addresses after deployment? + _configureCcipTokenPool(tokenPool, Utils.CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); + + // 5. Add CCIP TokenPool as GHO Facilitator + IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).grantRole( + IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).FACILITATOR_MANAGER_ROLE(), + GovernanceV3Arbitrum.EXECUTOR_LVL_1 + ); + IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).grantRole( + IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).BUCKET_MANAGER_ROLE(), + GovernanceV3Arbitrum.EXECUTOR_LVL_1 + ); + IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).addFacilitator( + tokenPool, + 'CCIP TokenPool', + uint128(Utils.CCIP_BUCKET_CAPACITY) + ); + + // 6. Accept administrator role from Chainlink token manager + TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole( + AaveV3ArbitrumAssets.GHO_UNDERLYING + ); + + // 7. Link token to pool on Chainlink token admin registry + TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).setPool( + AaveV3ArbitrumAssets.GHO_UNDERLYING, + tokenPool + ); + } + + function _configureCcipTokenPool( + address tokenPool, + uint64 chainSelector, + address remotePool, + address remoteToken + ) internal { + UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( + 1 + ); + RateLimiter.Config memory rateConfig = RateLimiter.Config({ + isEnabled: false, + capacity: 0, + rate: 0 + }); + chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ + remoteChainSelector: chainSelector, + allowed: true, + remotePoolAddress: abi.encode(remotePool), + remoteTokenAddress: abi.encode(remoteToken), + outboundRateLimiterConfig: rateConfig, + inboundRateLimiterConfig: rateConfig + }); + UpgradeableBurnMintTokenPool(tokenPool).applyChainUpdates(chainUpdates); } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 21d73ca11..aab9e5c1f 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -1,23 +1,23 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {AaveV3Avalanche, AaveV3AvalancheEModes} from 'aave-address-book/AaveV3Avalanche.sol'; -import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; -import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadAvalanche.sol'; -import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol'; -import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; -import {IV3RateStrategyFactory} from 'lib/gho-core/lib/aave-stk-v1-5/lib/aave-helpers/src/v3-config-engine/IV3RateStrategyFactory.sol'; -import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; -import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; +import {IV3RateStrategyFactory} from 'lib/gho-core/lib/aave-stk-v1-5/lib/aave-helpers/src/v3-config-engine/IV3RateStrategyFactory.sol'; +import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; +import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadAvalanche.sol'; +import {AaveV3Avalanche, AaveV3AvalancheEModes} from 'aave-address-book/AaveV3Avalanche.sol'; +import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; +import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; +import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol'; +import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; -import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; library Utils { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; From 5e07b5a1496a8713d544819b1cdf632500e883ee Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 7 Nov 2024 20:19:37 -0800 Subject: [PATCH 22/58] fix: Remove intermediary utils contract --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 72 ++++++------ ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 105 ++++++++---------- 2 files changed, 84 insertions(+), 93 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index 77e9b4350..d506ea2e0 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -12,37 +12,6 @@ import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; -library Utils { - address public constant CCIP_RMN_PROXY = 0xC311a21e6fEf769344EB1515588B9d535662a145; - address public constant CCIP_ROUTER = 0x141fa059441E0ca23ce184B6A78bafD2A517DdE8; - // TODO: Wait for token admin registry to be deployed, and get proper address - address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; - uint256 public constant CCIP_BUCKET_CAPACITY = 1_000_000e18; // 1M - uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; - uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; - - function deployCcipTokenPool() external returns (address) { - address imple = address( - new UpgradeableBurnMintTokenPool(AaveV3ArbitrumAssets.GHO_UNDERLYING, CCIP_RMN_PROXY, false) - ); - - bytes memory tokenPoolInitParams = abi.encodeWithSignature( - 'initialize(address,address[],address)', - GovernanceV3Arbitrum.EXECUTOR_LVL_1, // owner - new address[](0), // allowList - CCIP_ROUTER // router - ); - return - address( - new TransparentUpgradeableProxy( - imple, // logic - MiscArbitrum.PROXY_ADMIN, // proxy admin - tokenPoolInitParams // data - ) - ); - } -} - /** * @title GHOAvaxLaunch * @author Aave Labs @@ -58,20 +27,28 @@ library Utils { * 7. Link token to pool on Chainlink token admin registry */ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { + address public constant CCIP_RMN_PROXY = 0xC311a21e6fEf769344EB1515588B9d535662a145; + address public constant CCIP_ROUTER = 0x141fa059441E0ca23ce184B6A78bafD2A517DdE8; + // TODO: Wait for token admin registry to be deployed, and get proper address + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + uint256 public constant CCIP_BUCKET_CAPACITY = 1_000_000e18; // 1M + uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; + uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; + function execute() external { // 1. Deploy BurnMintTokenPool - address tokenPool = Utils.deployCcipTokenPool(); + address tokenPool = _deployCcipTokenPool(); // 2. Accept TokenPool ownership UpgradeableBurnMintTokenPool(tokenPool).acceptOwnership(); // 3. Configure CCIP TokenPool for Ethereum // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, Utils.CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(tokenPool, CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); // 4. Configure CCIP TokenPool for Avalanche // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, Utils.CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(tokenPool, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); // 5. Add CCIP TokenPool as GHO Facilitator IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).grantRole( @@ -85,21 +62,42 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).addFacilitator( tokenPool, 'CCIP TokenPool', - uint128(Utils.CCIP_BUCKET_CAPACITY) + uint128(CCIP_BUCKET_CAPACITY) ); // 6. Accept administrator role from Chainlink token manager - TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole( + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole( AaveV3ArbitrumAssets.GHO_UNDERLYING ); // 7. Link token to pool on Chainlink token admin registry - TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).setPool( + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool( AaveV3ArbitrumAssets.GHO_UNDERLYING, tokenPool ); } + function _deployCcipTokenPool() internal returns (address) { + address imple = address( + new UpgradeableBurnMintTokenPool(AaveV3ArbitrumAssets.GHO_UNDERLYING, CCIP_RMN_PROXY, false) + ); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address)', + GovernanceV3Arbitrum.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + CCIP_ROUTER // router + ); + return + address( + new TransparentUpgradeableProxy( + imple, // logic + MiscArbitrum.PROXY_ADMIN, // proxy admin + tokenPoolInitParams // data + ) + ); + } + function _configureCcipTokenPool( address tokenPool, uint64 chainSelector, diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index aab9e5c1f..afa7243db 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -8,7 +8,6 @@ import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTo import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; -import {IV3RateStrategyFactory} from 'lib/gho-core/lib/aave-stk-v1-5/lib/aave-helpers/src/v3-config-engine/IV3RateStrategyFactory.sol'; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadAvalanche.sol'; import {AaveV3Avalanche, AaveV3AvalancheEModes} from 'aave-address-book/AaveV3Avalanche.sol'; @@ -19,48 +18,6 @@ import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; -library Utils { - address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; - address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; - // TODO: Wait for token admin registry to be deployed, and get proper address - address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; - uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M - uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; - uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; - - function deployGhoToken() internal returns (address) { - address imple = address(new UpgradeableGhoToken()); - - bytes memory ghoTokenInitParams = abi.encodeWithSignature( - 'initialize(address)', - GovernanceV3Avalanche.EXECUTOR_LVL_1 // owner - ); - return - address( - new TransparentUpgradeableProxy(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) - ); - } - - function deployCcipTokenPool(address ghoToken) external returns (address) { - address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, CCIP_RMN_PROXY, false)); - - bytes memory tokenPoolInitParams = abi.encodeWithSignature( - 'initialize(address,address[],address)', - GovernanceV3Avalanche.EXECUTOR_LVL_1, // owner - new address[](0), // allowList - CCIP_ROUTER // router - ); - return - address( - new TransparentUpgradeableProxy( - imple, // logic - MiscAvalanche.PROXY_ADMIN, // proxy admin - tokenPoolInitParams // data - ) - ); - } -} - /** * @title GHO Avax Launch * @author Aave Labs @@ -77,23 +34,31 @@ library Utils { * 8. Link token to pool on Chainlink token admin registry */ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { + address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; + address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + // TODO: Wait for token admin registry to be deployed, and get proper address + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M + uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; + uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; + function execute() external { // 1. Deploy GHO - address ghoToken = Utils.deployGhoToken(); + address ghoToken = _deployGhoToken(); // 2. Deploy BurnMintTokenPool - address tokenPool = Utils.deployCcipTokenPool(ghoToken); + address tokenPool = _deployCcipTokenPool(ghoToken); // 3. Accept TokenPool ownership UpgradeableBurnMintTokenPool(tokenPool).acceptOwnership(); // 4. Configure CCIP TokenPool for Ethereum // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, Utils.CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(tokenPool, CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); // 5. Configure CCIP TokenPool for Arbitrum // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, Utils.CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(tokenPool, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); // 6. Add CCIP TokenPool as GHO Facilitator IGhoToken(ghoToken).grantRole( @@ -104,17 +69,45 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { IGhoToken(ghoToken).BUCKET_MANAGER_ROLE(), GovernanceV3Avalanche.EXECUTOR_LVL_1 ); - IGhoToken(ghoToken).addFacilitator( - tokenPool, - 'CCIP TokenPool', - uint128(Utils.CCIP_BUCKET_CAPACITY) - ); + IGhoToken(ghoToken).addFacilitator(tokenPool, 'CCIP TokenPool', uint128(CCIP_BUCKET_CAPACITY)); // 7. Accept administrator role from Chainlink token manager - TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(ghoToken); + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(ghoToken); // 8. Link token to pool on Chainlink token admin registry - TokenAdminRegistry(Utils.CCIP_TOKEN_ADMIN_REGISTRY).setPool(ghoToken, tokenPool); + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(ghoToken, tokenPool); + } + + function _deployGhoToken() internal returns (address) { + address imple = address(new UpgradeableGhoToken()); + + bytes memory ghoTokenInitParams = abi.encodeWithSignature( + 'initialize(address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1 // owner + ); + return + address( + new TransparentUpgradeableProxy(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) + ); + } + + function _deployCcipTokenPool(address ghoToken) internal returns (address) { + address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, CCIP_RMN_PROXY, false)); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + CCIP_ROUTER // router + ); + return + address( + new TransparentUpgradeableProxy( + imple, // logic + MiscAvalanche.PROXY_ADMIN, // proxy admin + tokenPoolInitParams // data + ) + ); } function _configureCcipTokenPool( @@ -152,8 +145,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { contract GhoAvaxListing is AaveV3PayloadAvalanche { using SafeERC20 for IERC20; - uint256 constant GHO_SEED_AMOUNT = 1_000_000e18; // TODO: Determine appropriate seed amount - address ghoToken; + uint256 public constant GHO_SEED_AMOUNT = 1_000_000e18; // TODO: Determine appropriate seed amount + address public ghoToken; constructor(address ghoToken) { ghoToken = ghoToken; From 70bcdeeb5cbcac37f47077069ddd08951852379b Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 7 Nov 2024 22:19:25 -0800 Subject: [PATCH 23/58] fix: Assume pool deployed --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 65 ++++++----------- ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 71 +++++++------------ .../AaveV3Ethereum_GHOAvaxLaunch_20241106.sol | 56 +++++---------- 3 files changed, 63 insertions(+), 129 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index d506ea2e0..9bddb4249 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -1,15 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; -import {AaveV3Arbitrum, AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; -import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; /** @@ -18,39 +16,37 @@ import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 * @dev This payload consists of the following set of actions: - * 1. Deploy BurnMintTokenPool - * 2. Accept ownership of CCIP TokenPool - * 3. Configure CCIP TokenPool for Ethereum - * 4. Configure CCIP TokenPool for Avalanche - * 5. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) - * 6. Accept administrator role from Chainlink token admin registry - * 7. Link token to pool on Chainlink token admin registry + * 1. Accept ownership of CCIP TokenPool + * 2. Configure CCIP TokenPool for Ethereum + * 3. Configure CCIP TokenPool for Avalanche + * 4. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) + * 5. Accept administrator role from Chainlink token admin registry + * 6. Link token to pool on Chainlink token admin registry */ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xC311a21e6fEf769344EB1515588B9d535662a145; address public constant CCIP_ROUTER = 0x141fa059441E0ca23ce184B6A78bafD2A517DdE8; // TODO: Wait for token admin registry to be deployed, and get proper address address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + // TODO: Wait until new token pool is deployed on Arbitrum, then use corresponding address + address public constant CCIP_TOKEN_POOL = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; uint256 public constant CCIP_BUCKET_CAPACITY = 1_000_000e18; // 1M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; function execute() external { - // 1. Deploy BurnMintTokenPool - address tokenPool = _deployCcipTokenPool(); + // 1. Accept TokenPool ownership + UpgradeableBurnMintTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); - // 2. Accept TokenPool ownership - UpgradeableBurnMintTokenPool(tokenPool).acceptOwnership(); - - // 3. Configure CCIP TokenPool for Ethereum + // 2. Configure CCIP TokenPool for Ethereum // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); - // 4. Configure CCIP TokenPool for Avalanche + // 3. Configure CCIP TokenPool for Avalanche // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); - // 5. Add CCIP TokenPool as GHO Facilitator + // 4. Add CCIP TokenPool as GHO Facilitator IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).grantRole( IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).FACILITATOR_MANAGER_ROLE(), GovernanceV3Arbitrum.EXECUTOR_LVL_1 @@ -60,42 +56,21 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { GovernanceV3Arbitrum.EXECUTOR_LVL_1 ); IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).addFacilitator( - tokenPool, + CCIP_TOKEN_POOL, 'CCIP TokenPool', uint128(CCIP_BUCKET_CAPACITY) ); - // 6. Accept administrator role from Chainlink token manager + // 5. Accept administrator role from Chainlink token manager TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole( AaveV3ArbitrumAssets.GHO_UNDERLYING ); - // 7. Link token to pool on Chainlink token admin registry + // 6. Link token to pool on Chainlink token admin registry TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool( AaveV3ArbitrumAssets.GHO_UNDERLYING, - tokenPool - ); - } - - function _deployCcipTokenPool() internal returns (address) { - address imple = address( - new UpgradeableBurnMintTokenPool(AaveV3ArbitrumAssets.GHO_UNDERLYING, CCIP_RMN_PROXY, false) - ); - - bytes memory tokenPoolInitParams = abi.encodeWithSignature( - 'initialize(address,address[],address)', - GovernanceV3Arbitrum.EXECUTOR_LVL_1, // owner - new address[](0), // allowList - CCIP_ROUTER // router + CCIP_TOKEN_POOL ); - return - address( - new TransparentUpgradeableProxy( - imple, // logic - MiscArbitrum.PROXY_ADMIN, // proxy admin - tokenPoolInitParams // data - ) - ); } function _configureCcipTokenPool( diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index afa7243db..f23758aa4 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -10,7 +10,7 @@ import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadAvalanche.sol'; -import {AaveV3Avalanche, AaveV3AvalancheEModes} from 'aave-address-book/AaveV3Avalanche.sol'; +import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol'; @@ -25,19 +25,20 @@ import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 * @dev This payload consists of the following set of actions: * 1. Deploy GHO - * 2. Deploy BurnMintTokenPool - * 3. Accept ownership of CCIP TokenPool - * 4. Configure CCIP TokenPool for Ethereum - * 5. Configure CCIP TokenPool for Arbitrum - * 6. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) - * 7. Accept administrator role from Chainlink token admin registry - * 8. Link token to pool on Chainlink token admin registry + * 2. Accept ownership of CCIP TokenPool + * 3. Configure CCIP TokenPool for Ethereum + * 4. Configure CCIP TokenPool for Arbitrum + * 5. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) + * 6. Accept administrator role from Chainlink token admin registry + * 7. Link token to pool on Chainlink token admin registry */ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; // TODO: Wait for token admin registry to be deployed, and get proper address address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + // TODO: Wait until new token pool is deployed on Avalanche, then use corresponding address + address public constant CCIP_TOKEN_POOL = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; @@ -46,21 +47,18 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { // 1. Deploy GHO address ghoToken = _deployGhoToken(); - // 2. Deploy BurnMintTokenPool - address tokenPool = _deployCcipTokenPool(ghoToken); + // 2. Accept TokenPool ownership + UpgradeableBurnMintTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); - // 3. Accept TokenPool ownership - UpgradeableBurnMintTokenPool(tokenPool).acceptOwnership(); - - // 4. Configure CCIP TokenPool for Ethereum + // 3. Configure CCIP TokenPool for Ethereum // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); - // 5. Configure CCIP TokenPool for Arbitrum + // 4. Configure CCIP TokenPool for Arbitrum // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); - // 6. Add CCIP TokenPool as GHO Facilitator + // 5. Add CCIP TokenPool as GHO Facilitator IGhoToken(ghoToken).grantRole( IGhoToken(ghoToken).FACILITATOR_MANAGER_ROLE(), GovernanceV3Avalanche.EXECUTOR_LVL_1 @@ -69,13 +67,17 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { IGhoToken(ghoToken).BUCKET_MANAGER_ROLE(), GovernanceV3Avalanche.EXECUTOR_LVL_1 ); - IGhoToken(ghoToken).addFacilitator(tokenPool, 'CCIP TokenPool', uint128(CCIP_BUCKET_CAPACITY)); + IGhoToken(ghoToken).addFacilitator( + CCIP_TOKEN_POOL, + 'CCIP TokenPool', + uint128(CCIP_BUCKET_CAPACITY) + ); - // 7. Accept administrator role from Chainlink token manager + // 6. Accept administrator role from Chainlink token manager TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(ghoToken); - // 8. Link token to pool on Chainlink token admin registry - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(ghoToken, tokenPool); + // 7. Link token to pool on Chainlink token admin registry + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(ghoToken, CCIP_TOKEN_POOL); } function _deployGhoToken() internal returns (address) { @@ -91,25 +93,6 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { ); } - function _deployCcipTokenPool(address ghoToken) internal returns (address) { - address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, CCIP_RMN_PROXY, false)); - - bytes memory tokenPoolInitParams = abi.encodeWithSignature( - 'initialize(address,address[],address)', - GovernanceV3Avalanche.EXECUTOR_LVL_1, // owner - new address[](0), // allowList - CCIP_ROUTER // router - ); - return - address( - new TransparentUpgradeableProxy( - imple, // logic - MiscAvalanche.PROXY_ADMIN, // proxy admin - tokenPoolInitParams // data - ) - ); - } - function _configureCcipTokenPool( address tokenPool, uint64 chainSelector, @@ -145,11 +128,11 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { contract GhoAvaxListing is AaveV3PayloadAvalanche { using SafeERC20 for IERC20; - uint256 public constant GHO_SEED_AMOUNT = 1_000_000e18; // TODO: Determine appropriate seed amount + uint256 public constant GHO_SEED_AMOUNT = 1_000_000e18; address public ghoToken; - constructor(address ghoToken) { - ghoToken = ghoToken; + constructor(address gho) { + ghoToken = gho; } function newListings() public view override returns (IAaveV3ConfigEngine.Listing[] memory) { diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol index f740bfac2..64869ed8d 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol @@ -2,9 +2,7 @@ pragma solidity ^0.8.0; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; -import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; -import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; import {UpgradeableLockReleaseTokenPool} from 'ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol'; import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; @@ -16,62 +14,40 @@ import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 * @dev This payload consists of the following set of actions: - * 1. Deploy LockReleaseTokenPool - * 2. Accept ownership of CCIP TokenPool - * 3. Configure CCIP TokenPool for Arbitrum - * 4. Configure CCIP TokenPool for Avalanche - * 5. Accept administrator role from Chainlink token manager - * 6. Link token to pool on Chainlink token admin registry + * 1. Accept ownership of CCIP TokenPool + * 2. Configure CCIP TokenPool for Arbitrum + * 3. Configure CCIP TokenPool for Avalanche + * 4. Accept administrator role from Chainlink token manager + * 5. Link token to pool on Chainlink token admin registry */ contract AaveV3Ethereum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0x411dE17f12D1A34ecC7F45f49844626267c75e81; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; // TODO: Wait for token admin registry to be deployed, and get proper address address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + // TODO: Wait until new token pool is deployed on Ethereum, then use corresponding address + address public constant CCIP_TOKEN_POOL = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; uint256 public constant CCIP_BRIDGE_LIMIT = 25_000_000e18; // 25M uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; function execute() external { - // 1. Deploy LockReleaseTokenPool - address tokenPool = _deployCcipTokenPool(); + // 1. Accept TokenPool ownership + UpgradeableLockReleaseTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); - // 2. Accept TokenPool ownership - UpgradeableLockReleaseTokenPool(tokenPool).acceptOwnership(); - - // 3. Configure CCIP for Arbitrum + // 2. Configure CCIP for Arbitrum // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); - // 4. Configure CCIP for Avalanche + // 3. Configure CCIP for Avalanche // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(tokenPool, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); - // 5. Accept Administrator role from Chainlink token manager + // 4. Accept Administrator role from Chainlink token manager TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(MiscEthereum.GHO_TOKEN); - // 6. Link token to pool on Chainlink token admin registry - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(MiscEthereum.GHO_TOKEN, tokenPool); - - // TODO: Migrate funds? - } - - function _deployCcipTokenPool() internal returns (address) { - address imple = address( - new UpgradeableLockReleaseTokenPool(MiscEthereum.GHO_TOKEN, CCIP_RMN_PROXY, false, true) - ); - - bytes memory tokenPoolInitParams = abi.encodeWithSignature( - 'initialize(address,address[],address,uint256)', - GovernanceV3Ethereum.EXECUTOR_LVL_1, // owner - new address[](0), // allowList - CCIP_ROUTER, // router - CCIP_BRIDGE_LIMIT // bridgeLimit - ); - return - address( - new TransparentUpgradeableProxy(imple, MiscEthereum.PROXY_ADMIN, tokenPoolInitParams) - ); + // 5. Link token to pool on Chainlink token admin registry + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(MiscEthereum.GHO_TOKEN, CCIP_TOKEN_POOL); } function _configureCcipTokenPool( From f2ae525d25336d69f04f062177c7a7cddaec1c47 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 25 Nov 2024 21:34:14 +0700 Subject: [PATCH 24/58] fix: Add token admin registry addresses --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 3 +-- .../AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 3 +-- .../AaveV3Ethereum_GHOAvaxLaunch_20241106.sol | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index 9bddb4249..ea2f23282 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -26,8 +26,7 @@ import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xC311a21e6fEf769344EB1515588B9d535662a145; address public constant CCIP_ROUTER = 0x141fa059441E0ca23ce184B6A78bafD2A517DdE8; - // TODO: Wait for token admin registry to be deployed, and get proper address - address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; // TODO: Wait until new token pool is deployed on Arbitrum, then use corresponding address address public constant CCIP_TOKEN_POOL = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; uint256 public constant CCIP_BUCKET_CAPACITY = 1_000_000e18; // 1M diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index f23758aa4..43e85290b 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -35,8 +35,7 @@ import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; - // TODO: Wait for token admin registry to be deployed, and get proper address - address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; // TODO: Wait until new token pool is deployed on Avalanche, then use corresponding address address public constant CCIP_TOKEN_POOL = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol index 64869ed8d..72e9b4841 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol @@ -23,8 +23,7 @@ import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol contract AaveV3Ethereum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0x411dE17f12D1A34ecC7F45f49844626267c75e81; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; - // TODO: Wait for token admin registry to be deployed, and get proper address - address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xb22764f98dD05c789929716D677382Df22C05Cb6; // TODO: Wait until new token pool is deployed on Ethereum, then use corresponding address address public constant CCIP_TOKEN_POOL = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; uint256 public constant CCIP_BRIDGE_LIMIT = 25_000_000e18; // 25M From 2075537bb23d245cdcc3861b8cb1ff56a17d6cd3 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Tue, 26 Nov 2024 12:53:55 +0700 Subject: [PATCH 25/58] test: Fix default proposal test --- ...3Avalanche_GHOAvaxLaunch_20241106_after.md | 15 +++++ ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 21 +++--- ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 66 ++++++++++++++++++- 3 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 diffs/AaveV3Avalanche_GHOAvaxLaunch_20241106_before_AaveV3Avalanche_GHOAvaxLaunch_20241106_after.md diff --git a/diffs/AaveV3Avalanche_GHOAvaxLaunch_20241106_before_AaveV3Avalanche_GHOAvaxLaunch_20241106_after.md b/diffs/AaveV3Avalanche_GHOAvaxLaunch_20241106_before_AaveV3Avalanche_GHOAvaxLaunch_20241106_after.md new file mode 100644 index 000000000..5e354a32d --- /dev/null +++ b/diffs/AaveV3Avalanche_GHOAvaxLaunch_20241106_before_AaveV3Avalanche_GHOAvaxLaunch_20241106_after.md @@ -0,0 +1,15 @@ +## Emodes changed + +### EMode: Stablecoins(id: 1) + + + +### EMode: AVAX correlated(id: 2) + + + +## Raw diff + +```json +{} +``` \ No newline at end of file diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 43e85290b..373e6c49a 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -36,15 +36,18 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; + // TODO: Remove this and deploy in contract once we Chainlink sets executor as pending Admin + address public constant GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; // TODO: Wait until new token pool is deployed on Avalanche, then use corresponding address - address public constant CCIP_TOKEN_POOL = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + address public constant CCIP_TOKEN_POOL = 0xF62849F9A0B5Bf2913b396098F7c7019b51A820a; uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; function execute() external { + // TODO: Put this back in proposal // 1. Deploy GHO - address ghoToken = _deployGhoToken(); + //address ghoToken = _deployGhoToken(); // 2. Accept TokenPool ownership UpgradeableBurnMintTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); @@ -58,25 +61,25 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); // 5. Add CCIP TokenPool as GHO Facilitator - IGhoToken(ghoToken).grantRole( - IGhoToken(ghoToken).FACILITATOR_MANAGER_ROLE(), + IGhoToken(GHO_TOKEN).grantRole( + IGhoToken(GHO_TOKEN).FACILITATOR_MANAGER_ROLE(), GovernanceV3Avalanche.EXECUTOR_LVL_1 ); - IGhoToken(ghoToken).grantRole( - IGhoToken(ghoToken).BUCKET_MANAGER_ROLE(), + IGhoToken(GHO_TOKEN).grantRole( + IGhoToken(GHO_TOKEN).BUCKET_MANAGER_ROLE(), GovernanceV3Avalanche.EXECUTOR_LVL_1 ); - IGhoToken(ghoToken).addFacilitator( + IGhoToken(GHO_TOKEN).addFacilitator( CCIP_TOKEN_POOL, 'CCIP TokenPool', uint128(CCIP_BUCKET_CAPACITY) ); // 6. Accept administrator role from Chainlink token manager - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(ghoToken); + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(GHO_TOKEN); // 7. Link token to pool on Chainlink token admin registry - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(ghoToken, CCIP_TOKEN_POOL); + TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(GHO_TOKEN, CCIP_TOKEN_POOL); } function _deployGhoToken() internal returns (address) { diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 690dab7c3..97d0f2745 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -1,9 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; - import 'forge-std/Test.sol'; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; +import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; +import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; +import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; @@ -14,8 +19,30 @@ import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxL contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { AaveV3Avalanche_GHOAvaxLaunch_20241106 internal proposal; + address public constant TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; + address public constant REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; + // TODO: Remove these constants once we have deployed pool address + address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; + address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + function setUp() public { - vm.createSelectFork(vm.rpcUrl('avalanche'), 52758592); + vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); + + // TODO: Remove this and put back in proposal after Chainlink sets executor as pending admin + address ghoToken = _deployGhoToken(); + + // TODO: Remove this deployment once we have deployed pool address + address tokenPool = _deployCcipTokenPool(ghoToken); + + // TODO: Remove this (will be done on chainlink's side) + // Prank chainlink and set up admin role to be accepted on token registry + vm.startPrank(REGISTRY_ADMIN); + TokenAdminRegistry(TOKEN_ADMIN_REGISTRY).proposeAdministrator( + ghoToken, + GovernanceV3Avalanche.EXECUTOR_LVL_1 + ); + vm.stopPrank(); + proposal = new AaveV3Avalanche_GHOAvaxLaunch_20241106(); } @@ -25,4 +52,37 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function test_defaultProposalExecution() public { defaultTest('AaveV3Avalanche_GHOAvaxLaunch_20241106', AaveV3Avalanche.POOL, address(proposal)); } + + function _deployGhoToken() internal returns (address) { + address imple = address(new UpgradeableGhoToken()); + + bytes memory ghoTokenInitParams = abi.encodeWithSignature( + 'initialize(address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1 // owner + ); + return + address( + new TransparentUpgradeableProxy(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) + ); + } + + function _deployCcipTokenPool(address ghoToken) internal returns (address) { + address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, CCIP_RMN_PROXY, false)); + UpgradeableBurnMintTokenPool(imple).transferOwnership(GovernanceV3Avalanche.EXECUTOR_LVL_1); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + CCIP_ROUTER // router + ); + return + address( + new TransparentUpgradeableProxy( + imple, // logic + MiscAvalanche.PROXY_ADMIN, // proxy admin + tokenPoolInitParams // data + ) + ); + } } From 848a92c5886d0005728df618480bdd5ffad43bc7 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Tue, 26 Nov 2024 16:21:37 +0700 Subject: [PATCH 26/58] test: Validate token and pool deployments --- ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 2 +- ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 66 ++++++++++++++++++- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 373e6c49a..744bddef3 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -39,7 +39,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { // TODO: Remove this and deploy in contract once we Chainlink sets executor as pending Admin address public constant GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; // TODO: Wait until new token pool is deployed on Avalanche, then use corresponding address - address public constant CCIP_TOKEN_POOL = 0xF62849F9A0B5Bf2913b396098F7c7019b51A820a; + address public constant CCIP_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 97d0f2745..eff48befa 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -8,6 +8,7 @@ import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; @@ -24,15 +25,20 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // TODO: Remove these constants once we have deployed pool address address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + address public ghoToken; + UpgradeableGhoToken public GHO; + UpgradeableBurnMintTokenPool public TOKEN_POOL; function setUp() public { vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); // TODO: Remove this and put back in proposal after Chainlink sets executor as pending admin - address ghoToken = _deployGhoToken(); + ghoToken = _deployGhoToken(); + GHO = UpgradeableGhoToken(ghoToken); // TODO: Remove this deployment once we have deployed pool address address tokenPool = _deployCcipTokenPool(ghoToken); + TOKEN_POOL = UpgradeableBurnMintTokenPool(tokenPool); // TODO: Remove this (will be done on chainlink's side) // Prank chainlink and set up admin role to be accepted on token registry @@ -51,6 +57,9 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { */ function test_defaultProposalExecution() public { defaultTest('AaveV3Avalanche_GHOAvaxLaunch_20241106', AaveV3Avalanche.POOL, address(proposal)); + + _validateGhoDeployment(); + _validateCcipTokenPool(); } function _deployGhoToken() internal returns (address) { @@ -68,7 +77,6 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function _deployCcipTokenPool(address ghoToken) internal returns (address) { address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, CCIP_RMN_PROXY, false)); - UpgradeableBurnMintTokenPool(imple).transferOwnership(GovernanceV3Avalanche.EXECUTOR_LVL_1); bytes memory tokenPoolInitParams = abi.encodeWithSignature( 'initialize(address,address[],address)', @@ -85,4 +93,58 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { ) ); } + + function _getProxyAdminAddress(address proxy) internal view returns (address) { + bytes32 ERC1967_ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + bytes32 adminSlot = vm.load(proxy, ERC1967_ADMIN_SLOT); + return address(uint160(uint256(adminSlot))); + } + + function _validateGhoDeployment() internal { + assertEq(GHO.totalSupply(), 0); + assertEq(GHO.getFacilitatorsList().length, 1); + assertEq(_getProxyAdminAddress(address(GHO)), MiscAvalanche.PROXY_ADMIN); + assertTrue(GHO.hasRole(bytes32(0), GovernanceV3Avalanche.EXECUTOR_LVL_1)); + assertTrue(GHO.hasRole(GHO.FACILITATOR_MANAGER_ROLE(), GovernanceV3Avalanche.EXECUTOR_LVL_1)); + assertTrue(GHO.hasRole(GHO.BUCKET_MANAGER_ROLE(), GovernanceV3Avalanche.EXECUTOR_LVL_1)); + } + + function _validateCcipTokenPool() internal { + // Deployment + assertEq(_getProxyAdminAddress(address(TOKEN_POOL)), MiscAvalanche.PROXY_ADMIN); + assertEq(TOKEN_POOL.owner(), GovernanceV3Avalanche.EXECUTOR_LVL_1); + assertEq(address(TOKEN_POOL.getToken()), address(GHO)); + assertEq(TOKEN_POOL.getRmnProxy(), CCIP_RMN_PROXY); + assertEq(TOKEN_POOL.getRouter(), CCIP_ROUTER); + + // Facilitator + (uint256 capacity, uint256 level) = GHO.getFacilitatorBucket(address(TOKEN_POOL)); + assertEq(capacity, proposal.CCIP_BUCKET_CAPACITY()); + assertEq(level, 0); + + // Configs + uint64[] memory supportedChains = TOKEN_POOL.getSupportedChains(); + assertEq(supportedChains.length, 2); + + // ETH + assertEq(supportedChains[0], proposal.CCIP_ETH_CHAIN_SELECTOR()); + RateLimiter.TokenBucket memory outboundRateLimit = TOKEN_POOL + .getCurrentOutboundRateLimiterState(proposal.CCIP_ETH_CHAIN_SELECTOR()); + RateLimiter.TokenBucket memory inboundRateLimit = TOKEN_POOL.getCurrentInboundRateLimiterState( + proposal.CCIP_ETH_CHAIN_SELECTOR() + ); + assertEq(outboundRateLimit.isEnabled, false); + assertEq(inboundRateLimit.isEnabled, false); + + // ARB + assertEq(supportedChains[1], proposal.CCIP_ARB_CHAIN_SELECTOR()); + outboundRateLimit = TOKEN_POOL.getCurrentOutboundRateLimiterState( + proposal.CCIP_ARB_CHAIN_SELECTOR() + ); + inboundRateLimit = TOKEN_POOL.getCurrentInboundRateLimiterState( + proposal.CCIP_ARB_CHAIN_SELECTOR() + ); + assertEq(outboundRateLimit.isEnabled, false); + assertEq(inboundRateLimit.isEnabled, false); + } } From d69c59afa82030eff1e784f95efaaaa3a08f96a3 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 27 Nov 2024 02:08:50 +0700 Subject: [PATCH 27/58] test: Basic pool test --- ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 5 +- ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 111 +++++++++++++++++- 2 files changed, 110 insertions(+), 6 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 744bddef3..22fd0e36d 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -13,6 +13,7 @@ import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3Pa import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; +import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol'; import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; @@ -40,6 +41,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; // TODO: Wait until new token pool is deployed on Avalanche, then use corresponding address address public constant CCIP_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; + address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; + address public constant ETH_GHO = MiscEthereum.GHO_TOKEN; uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; @@ -54,7 +57,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { // 3. Configure CCIP TokenPool for Ethereum // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ETH_CHAIN_SELECTOR, ETH_TOKEN_POOL, ETH_GHO); // 4. Configure CCIP TokenPool for Arbitrum // TODO: Set remote pool and token addresses after deployment? diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index eff48befa..6b818fd4a 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -3,9 +3,12 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; +import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {Pool} from 'ccip/libraries/Pool.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; @@ -25,10 +28,15 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // TODO: Remove these constants once we have deployed pool address address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public ghoToken; UpgradeableGhoToken public GHO; UpgradeableBurnMintTokenPool public TOKEN_POOL; + event Minted(address indexed sender, address indexed recipient, uint256 amount); + event Burned(address indexed sender, uint256 amount); + event Transfer(address indexed from, address indexed to, uint256 value); + function setUp() public { vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); @@ -62,6 +70,86 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { _validateCcipTokenPool(); } + /// @dev Test burn and mint actions, mocking CCIP calls + function test_ccipTokenPool() public { + GovV3Helpers.executePayload(vm, address(proposal)); + + // Mock calls + address router = TOKEN_POOL.getRouter(); + address ramp = makeAddr('ramp'); + vm.mockCall( + router, + abi.encodeWithSelector(bytes4(keccak256('getOnRamp(uint64)'))), + abi.encode(ramp) + ); + vm.mockCall( + router, + abi.encodeWithSelector(bytes4(keccak256('isOffRamp(uint64,address)'))), + abi.encode(true) + ); + + // Prank user + address user = makeAddr('user'); + + // Mint + uint256 amount = 500_000e18; // 500K GHO + uint64 ethChainSelector = proposal.CCIP_ETH_CHAIN_SELECTOR(); + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + + Pool.ReleaseOrMintInV1 memory releaseOrMintIn = Pool.ReleaseOrMintInV1({ + originalSender: bytes(''), + remoteChainSelector: ethChainSelector, + receiver: user, + amount: amount, + localToken: address(GHO), + sourcePoolAddress: abi.encode(ETH_TOKEN_POOL), + sourcePoolData: bytes(''), + offchainTokenData: bytes('') + }); + + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(0), user, amount); + + vm.expectEmit(false, true, true, true, address(TOKEN_POOL)); + emit Minted(address(0), user, amount); + + TOKEN_POOL.releaseOrMint(releaseOrMintIn); + + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), amount); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(user), amount); + + // Burn + // mock router transfer of funds from user to token pool + vm.prank(user); + GHO.transfer(address(TOKEN_POOL), amount); + + Pool.LockOrBurnInV1 memory lockOrBurnIn = Pool.LockOrBurnInV1({ + receiver: bytes(''), + remoteChainSelector: ethChainSelector, + originalSender: user, + amount: amount, + localToken: address(GHO) + }); + + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(TOKEN_POOL), address(0), amount); + + vm.expectEmit(false, true, false, true, address(TOKEN_POOL)); + emit Burned(address(0), amount); + + vm.prank(ramp); + TOKEN_POOL.lockOrBurn(lockOrBurnIn); + + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + } + + // --- + // Deployment + // --- + function _deployGhoToken() internal returns (address) { address imple = address(new UpgradeableGhoToken()); @@ -94,11 +182,9 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { ); } - function _getProxyAdminAddress(address proxy) internal view returns (address) { - bytes32 ERC1967_ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - bytes32 adminSlot = vm.load(proxy, ERC1967_ADMIN_SLOT); - return address(uint160(uint256(adminSlot))); - } + // --- + // Test Helpers + // --- function _validateGhoDeployment() internal { assertEq(GHO.totalSupply(), 0); @@ -147,4 +233,19 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(outboundRateLimit.isEnabled, false); assertEq(inboundRateLimit.isEnabled, false); } + + // --- + // Utils + // --- + + function _getProxyAdminAddress(address proxy) internal view returns (address) { + bytes32 ERC1967_ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + bytes32 adminSlot = vm.load(proxy, ERC1967_ADMIN_SLOT); + return address(uint160(uint256(adminSlot))); + } + + function _getFacilitatorLevel(address f) internal view returns (uint256) { + (, uint256 level) = GHO.getFacilitatorBucket(f); + return level; + } } From 160a17ff416fd34555d1641069fa382841615d5a Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 27 Nov 2024 19:59:52 +0700 Subject: [PATCH 28/58] test: Add avax <> arb checks --- ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 6 +- ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 59 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 22fd0e36d..49d4c2ea9 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -11,9 +11,11 @@ import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadAvalanche.sol'; import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; +import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol'; import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; @@ -43,6 +45,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ETH_GHO = MiscEthereum.GHO_TOKEN; + address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; + address public constant ARB_GHO = 0x7dfF72693f6A4149b17e7C6314655f6A9F7c8B33; // AaveV3Arbitrum.GHO_UNDERLYING; uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; @@ -61,7 +65,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { // 4. Configure CCIP TokenPool for Arbitrum // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ARB_CHAIN_SELECTOR, ARB_TOKEN_POOL, ARB_GHO); // 5. Add CCIP TokenPool as GHO Facilitator IGhoToken(GHO_TOKEN).grantRole( diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 6b818fd4a..8db8d9483 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -8,6 +8,7 @@ import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {Pool} from 'ccip/libraries/Pool.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; @@ -29,6 +30,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; + address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; address public ghoToken; UpgradeableGhoToken public GHO; UpgradeableBurnMintTokenPool public TOKEN_POOL; @@ -91,6 +93,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Prank user address user = makeAddr('user'); + // AVAX <> ETH + // Mint uint256 amount = 500_000e18; // 500K GHO uint64 ethChainSelector = proposal.CCIP_ETH_CHAIN_SELECTOR(); @@ -144,6 +148,61 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + + // AVAX <> ARB + + // Mint + uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + + releaseOrMintIn = Pool.ReleaseOrMintInV1({ + originalSender: bytes(''), + remoteChainSelector: arbChainSelector, + receiver: user, + amount: amount, + localToken: address(GHO), + sourcePoolAddress: abi.encode(ARB_TOKEN_POOL), + sourcePoolData: bytes(''), + offchainTokenData: bytes('') + }); + + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(0), user, amount); + + vm.expectEmit(false, true, true, true, address(TOKEN_POOL)); + emit Minted(address(0), user, amount); + + TOKEN_POOL.releaseOrMint(releaseOrMintIn); + + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), amount); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(user), amount); + + // Burn + // mock router transfer of funds from user to token pool + vm.prank(user); + GHO.transfer(address(TOKEN_POOL), amount); + + lockOrBurnIn = Pool.LockOrBurnInV1({ + receiver: bytes(''), + remoteChainSelector: arbChainSelector, + originalSender: user, + amount: amount, + localToken: address(GHO) + }); + + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(TOKEN_POOL), address(0), amount); + + vm.expectEmit(false, true, false, true, address(TOKEN_POOL)); + emit Burned(address(0), amount); + + vm.prank(ramp); + TOKEN_POOL.lockOrBurn(lockOrBurnIn); + + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); } // --- From a8f1aeb404463d9eca808a0ff59f975110eb5947 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Fri, 29 Nov 2024 16:18:08 +0700 Subject: [PATCH 29/58] test: E2E on avax <> eth --- ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 8db8d9483..aab11c8aa 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -3,16 +3,24 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; +import {IPoolV1} from 'ccip/interfaces/IPool.sol'; import {Pool} from 'ccip/libraries/Pool.sol'; +import {Internal} from 'ccip/libraries/Internal.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {EVM2EVMOnRamp} from 'ccip/onRamp/EVM2EVMOnRamp.sol'; +import {EVM2EVMOffRamp} from 'ccip/offRamp/EVM2EVMOffRamp.sol'; +import {Client} from 'ccip/libraries/Client.sol'; +import {Router} from 'ccip/Router.sol'; +import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; @@ -24,6 +32,9 @@ import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxL contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { AaveV3Avalanche_GHOAvaxLaunch_20241106 internal proposal; + address internal constant CCIP_AVAX_ETH_ON_RAMP = 0xe8784c29c583C52FA89144b9e5DD91Df2a1C2587; + address internal constant CCIP_AVAX_ETH_OFF_RAMP = 0xE5F21F43937199D4D57876A83077b3923F68EB76; + address public constant TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; address public constant REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; // TODO: Remove these constants once we have deployed pool address @@ -205,6 +216,75 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); } + /// @dev CCIP e2e + function test_ccipE2E() public { + GovV3Helpers.executePayload(vm, address(proposal)); + + uint64 ethChainSelector = proposal.CCIP_ETH_CHAIN_SELECTOR(); + + // Chainlink config + Router router = Router(TOKEN_POOL.getRouter()); + + { + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + // ETH -> AVAX + onRampUpdates[0] = Router.OnRamp({ + destChainSelector: ethChainSelector, + onRamp: CCIP_AVAX_ETH_ON_RAMP + }); + // AVAX -> ETH + offRampUpdates[0] = Router.OffRamp({ + sourceChainSelector: ethChainSelector, + offRamp: CCIP_AVAX_ETH_OFF_RAMP + }); + address routerOwner = router.owner(); + vm.startPrank(routerOwner); + router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + { + // OnRamp Price Registry + EVM2EVMOnRamp.DynamicConfig memory onRampDynamicConfig = EVM2EVMOnRamp(CCIP_AVAX_ETH_ON_RAMP) + .getDynamicConfig(); + Internal.PriceUpdates memory priceUpdate = _getSingleTokenPriceUpdateStruct( + address(GHO), + 1e18 + ); + + IPriceRegistry(onRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + // OffRamp Price Registry + EVM2EVMOffRamp.DynamicConfig memory offRampDynamicConfig = EVM2EVMOffRamp( + CCIP_AVAX_ETH_OFF_RAMP + ).getDynamicConfig(); + IPriceRegistry(offRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + } + + // User executes ccipSend + address user = makeAddr('user'); + uint256 amount = 500_000e18; // 500K GHO + deal(user, 1e18); // 1 ETH + + // Mint tokens to user so can burn and bridge out + vm.startPrank(address(TOKEN_POOL)); + GHO.mint(user, amount); + + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + (uint256 capacity, uint256 level) = GHO.getFacilitatorBucket(address(TOKEN_POOL)); + assertEq(capacity, proposal.CCIP_BUCKET_CAPACITY()); + assertEq(level, amount); + + vm.startPrank(user); + // Use address(0) to use native token as fee token + _sendCcip(router, address(GHO), amount, address(0), ethChainSelector, user); + + assertEq(GHO.balanceOf(user), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + (capacity, level) = GHO.getFacilitatorBucket(address(TOKEN_POOL)); + assertEq(capacity, proposal.CCIP_BUCKET_CAPACITY()); + assertEq(level, 0); + } + // --- // Deployment // --- @@ -307,4 +387,68 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { (, uint256 level) = GHO.getFacilitatorBucket(f); return level; } + + function _sendCcip( + Router router, + address token, + uint256 amount, + address feeToken, + uint64 destChainSelector, + address receiver + ) internal { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage( + receiver, + token, + amount, + feeToken + ); + uint256 expectedFee = router.getFee(destChainSelector, message); + + IERC20(token).approve(address(router), amount); + router.ccipSend{value: expectedFee}(destChainSelector, message); + } + + function _generateSingleTokenMessage( + address receiver, + address token, + uint256 amount, + address feeToken + ) public pure returns (Client.EVM2AnyMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); + return + Client.EVM2AnyMessage({ + receiver: abi.encode(receiver), + data: '', + tokenAmounts: tokenAmounts, + feeToken: feeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})) + }); + } + + function _getTokensAndPools( + address[] memory tokens, + IPoolV1[] memory pools + ) internal pure returns (Internal.PoolUpdate[] memory) { + Internal.PoolUpdate[] memory tokensAndPools = new Internal.PoolUpdate[](tokens.length); + for (uint256 i = 0; i < tokens.length; ++i) { + tokensAndPools[i] = Internal.PoolUpdate({token: tokens[i], pool: address(pools[i])}); + } + return tokensAndPools; + } + + function _getSingleTokenPriceUpdateStruct( + address token, + uint224 price + ) internal pure returns (Internal.PriceUpdates memory) { + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](1); + tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: token, usdPerToken: price}); + + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: tokenPriceUpdates, + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + + return priceUpdates; + } } From eaaedb55822ad5c4c8169f40b952c4eecb998274 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Fri, 29 Nov 2024 16:26:10 +0700 Subject: [PATCH 30/58] test: Add arb <> avax e2e test --- ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 75 ++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index aab11c8aa..bf6e0684c 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -34,6 +34,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address internal constant CCIP_AVAX_ETH_ON_RAMP = 0xe8784c29c583C52FA89144b9e5DD91Df2a1C2587; address internal constant CCIP_AVAX_ETH_OFF_RAMP = 0xE5F21F43937199D4D57876A83077b3923F68EB76; + address internal constant CCIP_AVAX_ARB_ON_RAMP = 0x4e910c8Bbe88DaDF90baa6c1B7850DbeA32c5B29; + address internal constant CCIP_AVAX_ARB_OFF_RAMP = 0x508Ea280D46E4796Ce0f1Acf8BEDa610c4238dB3; address public constant TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; address public constant REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; @@ -216,8 +218,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); } - /// @dev CCIP e2e - function test_ccipE2E() public { + /// @dev CCIP e2e eth <> avax + function test_ccipE2E_ETH_AVAX() public { GovV3Helpers.executePayload(vm, address(proposal)); uint64 ethChainSelector = proposal.CCIP_ETH_CHAIN_SELECTOR(); @@ -285,6 +287,75 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(level, 0); } + /// @dev CCIP e2e arb <> avax + function test_ccipE2E_ARB_AVAX() public { + GovV3Helpers.executePayload(vm, address(proposal)); + + uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); + + // Chainlink config + Router router = Router(TOKEN_POOL.getRouter()); + + { + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + // ARB -> AVAX + onRampUpdates[0] = Router.OnRamp({ + destChainSelector: arbChainSelector, + onRamp: CCIP_AVAX_ARB_ON_RAMP + }); + // AVAX -> ARB + offRampUpdates[0] = Router.OffRamp({ + sourceChainSelector: arbChainSelector, + offRamp: CCIP_AVAX_ARB_OFF_RAMP + }); + address routerOwner = router.owner(); + vm.startPrank(routerOwner); + router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + { + // OnRamp Price Registry + EVM2EVMOnRamp.DynamicConfig memory onRampDynamicConfig = EVM2EVMOnRamp(CCIP_AVAX_ARB_ON_RAMP) + .getDynamicConfig(); + Internal.PriceUpdates memory priceUpdate = _getSingleTokenPriceUpdateStruct( + address(GHO), + 1e18 + ); + + IPriceRegistry(onRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + // OffRamp Price Registry + EVM2EVMOffRamp.DynamicConfig memory offRampDynamicConfig = EVM2EVMOffRamp( + CCIP_AVAX_ARB_OFF_RAMP + ).getDynamicConfig(); + IPriceRegistry(offRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + } + + // User executes ccipSend + address user = makeAddr('user'); + uint256 amount = 500_000e18; // 500K GHO + deal(user, 1e18); // 1 ETH + + // Mint tokens to user so can burn and bridge out + vm.startPrank(address(TOKEN_POOL)); + GHO.mint(user, amount); + + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + (uint256 capacity, uint256 level) = GHO.getFacilitatorBucket(address(TOKEN_POOL)); + assertEq(capacity, proposal.CCIP_BUCKET_CAPACITY()); + assertEq(level, amount); + + vm.startPrank(user); + // Use address(0) to use native token as fee token + _sendCcip(router, address(GHO), amount, address(0), arbChainSelector, user); + + assertEq(GHO.balanceOf(user), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + (capacity, level) = GHO.getFacilitatorBucket(address(TOKEN_POOL)); + assertEq(capacity, proposal.CCIP_BUCKET_CAPACITY()); + assertEq(level, 0); + } + // --- // Deployment // --- From bf721db0f0db2cfcca75cf64fd5aae8966e57796 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Fri, 29 Nov 2024 17:03:10 +0700 Subject: [PATCH 31/58] fix: Move gho deployment to proposal --- .../AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 13 ++++++------- .../AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 12 ++++-------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 49d4c2ea9..0e0625902 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -39,10 +39,10 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; - // TODO: Remove this and deploy in contract once we Chainlink sets executor as pending Admin - address public constant GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; + // TODO: Enusre this pre-computed address is correct (even if we launch additional AIPs) + address public constant GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; // TODO: Wait until new token pool is deployed on Avalanche, then use corresponding address - address public constant CCIP_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; + address public constant CCIP_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ETH_GHO = MiscEthereum.GHO_TOKEN; address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; @@ -52,19 +52,18 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; function execute() external { - // TODO: Put this back in proposal // 1. Deploy GHO - //address ghoToken = _deployGhoToken(); + _deployGhoToken(); // 2. Accept TokenPool ownership UpgradeableBurnMintTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); // 3. Configure CCIP TokenPool for Ethereum - // TODO: Set remote pool and token addresses after deployment? + // TODO: Update pool address if we deploy new one _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ETH_CHAIN_SELECTOR, ETH_TOKEN_POOL, ETH_GHO); // 4. Configure CCIP TokenPool for Arbitrum - // TODO: Set remote pool and token addresses after deployment? + // TODO: Update pool address if we deploy new one _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ARB_CHAIN_SELECTOR, ARB_TOKEN_POOL, ARB_GHO); // 5. Add CCIP TokenPool as GHO Facilitator diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index bf6e0684c..93cec7941 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -44,8 +44,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; - address public ghoToken; - UpgradeableGhoToken public GHO; + address public constant GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); UpgradeableBurnMintTokenPool public TOKEN_POOL; event Minted(address indexed sender, address indexed recipient, uint256 amount); @@ -55,19 +55,15 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function setUp() public { vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); - // TODO: Remove this and put back in proposal after Chainlink sets executor as pending admin - ghoToken = _deployGhoToken(); - GHO = UpgradeableGhoToken(ghoToken); - // TODO: Remove this deployment once we have deployed pool address - address tokenPool = _deployCcipTokenPool(ghoToken); + address tokenPool = _deployCcipTokenPool(GHO_TOKEN); TOKEN_POOL = UpgradeableBurnMintTokenPool(tokenPool); // TODO: Remove this (will be done on chainlink's side) // Prank chainlink and set up admin role to be accepted on token registry vm.startPrank(REGISTRY_ADMIN); TokenAdminRegistry(TOKEN_ADMIN_REGISTRY).proposeAdministrator( - ghoToken, + GHO_TOKEN, GovernanceV3Avalanche.EXECUTOR_LVL_1 ); vm.stopPrank(); From 7c315f9d423c984e5f90ff3aa8d72b4bc19c3988 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 2 Dec 2024 01:25:10 +0700 Subject: [PATCH 32/58] feat: Fix arb proposal and default test --- ...V3Arbitrum_GHOAvaxLaunch_20241106_after.md | 15 +++++ .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 46 ++++++++------ ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 61 ++++++++++++++++++- 3 files changed, 104 insertions(+), 18 deletions(-) create mode 100644 diffs/AaveV3Arbitrum_GHOAvaxLaunch_20241106_before_AaveV3Arbitrum_GHOAvaxLaunch_20241106_after.md diff --git a/diffs/AaveV3Arbitrum_GHOAvaxLaunch_20241106_before_AaveV3Arbitrum_GHOAvaxLaunch_20241106_after.md b/diffs/AaveV3Arbitrum_GHOAvaxLaunch_20241106_before_AaveV3Arbitrum_GHOAvaxLaunch_20241106_after.md new file mode 100644 index 000000000..4d686addb --- /dev/null +++ b/diffs/AaveV3Arbitrum_GHOAvaxLaunch_20241106_before_AaveV3Arbitrum_GHOAvaxLaunch_20241106_after.md @@ -0,0 +1,15 @@ +## Emodes changed + +### EMode: Stablecoins(id: 1) + + + +### EMode: ETH correlated(id: 2) + + + +## Raw diff + +```json +{} +``` \ No newline at end of file diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index ea2f23282..3425fa0b0 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -8,8 +8,21 @@ import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; +import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; +/// @dev Minimal interface for exiting ETH and ARB pools +interface IUpgradeablePool { + struct ChainUpdate { + uint64 remoteChainSelector; + bool allowed; + RateLimiter.Config outboundRateLimiterConfig; + RateLimiter.Config inboundRateLimiterConfig; + } + + function applyChainUpdates(ChainUpdate[] calldata updates) external; +} + /** * @title GHOAvaxLaunch * @author Aave Labs @@ -27,24 +40,31 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xC311a21e6fEf769344EB1515588B9d535662a145; address public constant CCIP_ROUTER = 0x141fa059441E0ca23ce184B6A78bafD2A517DdE8; address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; - // TODO: Wait until new token pool is deployed on Arbitrum, then use corresponding address - address public constant CCIP_TOKEN_POOL = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + // TODO: Update pool address if we deploy new one + address public constant CCIP_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; + address public constant AVAX_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; + address public constant AVAX_GHO = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; uint256 public constant CCIP_BUCKET_CAPACITY = 1_000_000e18; // 1M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; function execute() external { + // TODO: Following code applies to case we deploy new pools + /* // 1. Accept TokenPool ownership UpgradeableBurnMintTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); // 2. Configure CCIP TokenPool for Ethereum // TODO: Set remote pool and token addresses after deployment? _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); + */ + // TODO: Update addresses if we deploy new pools // 3. Configure CCIP TokenPool for Avalanche - // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_AVAX_CHAIN_SELECTOR); + // TODO: Following code applies to case we deploy new pools + /* // 4. Add CCIP TokenPool as GHO Facilitator IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).grantRole( IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).FACILITATOR_MANAGER_ROLE(), @@ -70,30 +90,22 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { AaveV3ArbitrumAssets.GHO_UNDERLYING, CCIP_TOKEN_POOL ); + */ } - function _configureCcipTokenPool( - address tokenPool, - uint64 chainSelector, - address remotePool, - address remoteToken - ) internal { - UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( - 1 - ); + function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { + IUpgradeablePool.ChainUpdate[] memory chainUpdates = new IUpgradeablePool.ChainUpdate[](1); RateLimiter.Config memory rateConfig = RateLimiter.Config({ isEnabled: false, capacity: 0, rate: 0 }); - chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ + chainUpdates[0] = IUpgradeablePool.ChainUpdate({ remoteChainSelector: chainSelector, allowed: true, - remotePoolAddress: abi.encode(remotePool), - remoteTokenAddress: abi.encode(remoteToken), outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - UpgradeableBurnMintTokenPool(tokenPool).applyChainUpdates(chainUpdates); + IUpgradeablePool(tokenPool).applyChainUpdates(chainUpdates); } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 8708a8174..80eba9fed 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -1,11 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; +import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; +import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; +import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import 'forge-std/Test.sol'; import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; +import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; +import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; /** * @dev Test for AaveV3Arbitrum_GHOAvaxLaunch_20241106 @@ -14,8 +24,36 @@ import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLau contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { AaveV3Arbitrum_GHOAvaxLaunch_20241106 internal proposal; + address public constant GHO_TOKEN = AaveV3ArbitrumAssets.GHO_UNDERLYING; + address public constant TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; + address public constant TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; + address public constant REGISTRY_ADMIN = 0x8a89770722c84B60cE02989Aedb22Ac4791F8C7f; + address public constant AVAX_GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant AVAX_REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; + address public constant AVAX_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; + address public constant AVAX_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; + address public constant AVAX_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + function setUp() public { - vm.createSelectFork(vm.rpcUrl('arbitrum'), 271862002); + // Execute Avax proposal to deploy Avax token pool + vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); + // TODO: Remove this deployment once we have deployed pool address + _deployCcipTokenPool(); + + // TODO: Remove this (will be done on chainlink's side) + // Prank chainlink and set up admin role to be accepted on token registry + vm.startPrank(AVAX_REGISTRY_ADMIN); + TokenAdminRegistry(AVAX_TOKEN_ADMIN_REGISTRY).proposeAdministrator( + AVAX_GHO_TOKEN, + GovernanceV3Avalanche.EXECUTOR_LVL_1 + ); + vm.stopPrank(); + + AaveV3Avalanche_GHOAvaxLaunch_20241106 avaxProposal = new AaveV3Avalanche_GHOAvaxLaunch_20241106(); + GovV3Helpers.executePayload(vm, address(avaxProposal)); + + // Switch to Arbitrum and create proposal + vm.createSelectFork(vm.rpcUrl('arbitrum'), 279521658); proposal = new AaveV3Arbitrum_GHOAvaxLaunch_20241106(); } @@ -25,4 +63,25 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function test_defaultProposalExecution() public { defaultTest('AaveV3Arbitrum_GHOAvaxLaunch_20241106', AaveV3Arbitrum.POOL, address(proposal)); } + + function _deployCcipTokenPool() internal returns (address) { + address imple = address( + new UpgradeableBurnMintTokenPool(AVAX_GHO_TOKEN, AVAX_RMN_PROXY, false) + ); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + AVAX_ROUTER // router + ); + return + address( + new TransparentUpgradeableProxy( + imple, // logic + MiscAvalanche.PROXY_ADMIN, // proxy admin + tokenPoolInitParams // data + ) + ); + } } From 6337e6e19e5252424651bc22ac97d46f89f301cb Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 2 Dec 2024 01:44:54 +0700 Subject: [PATCH 33/58] test: Validate arb pool avax config --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 4 +-- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 28 ++++++++++++++++--- ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index 3425fa0b0..bfb613c34 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; -import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; +import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 80eba9fed..02b64e274 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -1,19 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import 'forge-std/Test.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; - -import 'forge-std/Test.sol'; -import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; -import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; @@ -62,6 +62,8 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { */ function test_defaultProposalExecution() public { defaultTest('AaveV3Arbitrum_GHOAvaxLaunch_20241106', AaveV3Arbitrum.POOL, address(proposal)); + + _validateCcipTokenPool(); } function _deployCcipTokenPool() internal returns (address) { @@ -84,4 +86,22 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { ) ); } + + function _validateCcipTokenPool() internal { + // Configs + uint64[] memory supportedChains = UpgradeableBurnMintTokenPool(TOKEN_POOL).getSupportedChains(); + assertEq(supportedChains.length, 2); + + // ETH + assertEq(supportedChains[0], proposal.CCIP_ETH_CHAIN_SELECTOR()); + + // AVAX + assertEq(supportedChains[1], proposal.CCIP_AVAX_CHAIN_SELECTOR()); + RateLimiter.TokenBucket memory outboundRateLimit = UpgradeableBurnMintTokenPool(TOKEN_POOL) + .getCurrentOutboundRateLimiterState(proposal.CCIP_AVAX_CHAIN_SELECTOR()); + RateLimiter.TokenBucket memory inboundRateLimit = UpgradeableBurnMintTokenPool(TOKEN_POOL) + .getCurrentInboundRateLimiterState(proposal.CCIP_AVAX_CHAIN_SELECTOR()); + assertEq(outboundRateLimit.isEnabled, false); + assertEq(inboundRateLimit.isEnabled, false); + } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 93cec7941..b3c512069 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; @@ -22,7 +23,6 @@ import {Client} from 'ccip/libraries/Client.sol'; import {Router} from 'ccip/Router.sol'; import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; -import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; /** From d37b736894b0ac2b54164fc80d36a7ce76deed05 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 2 Dec 2024 14:31:18 +0700 Subject: [PATCH 34/58] test: Mint arb <> eth --- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 159 +++++++++++++++++- 1 file changed, 154 insertions(+), 5 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 02b64e274..4de32d3df 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -9,11 +9,15 @@ import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; +import {Pool} from 'ccip/libraries/Pool.sol'; +import {IPoolPriorTo1_5} from 'ccip/interfaces/IPoolPriorTo1_5.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; @@ -25,7 +29,9 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { AaveV3Arbitrum_GHOAvaxLaunch_20241106 internal proposal; address public constant GHO_TOKEN = AaveV3ArbitrumAssets.GHO_UNDERLYING; - address public constant TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; + UpgradeableBurnMintTokenPool public constant TOKEN_POOL = + UpgradeableBurnMintTokenPool(MiscArbitrum.GHO_CCIP_TOKEN_POOL); + UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); address public constant TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; address public constant REGISTRY_ADMIN = 0x8a89770722c84B60cE02989Aedb22Ac4791F8C7f; address public constant AVAX_GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; @@ -33,6 +39,11 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant AVAX_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; address public constant AVAX_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant AVAX_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; + + event Minted(address indexed sender, address indexed recipient, uint256 amount); + event Burned(address indexed sender, uint256 amount); + event Transfer(address indexed from, address indexed to, uint256 value); function setUp() public { // Execute Avax proposal to deploy Avax token pool @@ -66,6 +77,138 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { _validateCcipTokenPool(); } + /// @dev Test burn and mint actions, mocking CCIP calls + function test_ccipTokenPool() public { + GovV3Helpers.executePayload(vm, address(proposal)); + + // Mock calls + address router = TOKEN_POOL.getRouter(); + address ramp = makeAddr('ramp'); + vm.mockCall( + router, + abi.encodeWithSelector(bytes4(keccak256('getOnRamp(uint64)'))), + abi.encode(ramp) + ); + vm.mockCall( + router, + abi.encodeWithSelector(bytes4(keccak256('isOffRamp(uint64,address)'))), + abi.encode(true) + ); + + // Prank user + address user = makeAddr('user'); + + // ARB <> ETH + + // Mint + uint256 amount = 100e18; + uint64 ethChainSelector = proposal.CCIP_ETH_CHAIN_SELECTOR(); + uint256 startingFacilitatorLevel = _getFacilitatorLevel(address(TOKEN_POOL)); + uint256 startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); + + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(0), user, amount); + + vm.expectEmit(false, true, true, true, address(TOKEN_POOL)); + emit Minted(address(0), user, amount); + + IPoolPriorTo1_5(address(TOKEN_POOL)).releaseOrMint( + bytes(''), + user, + amount, + ethChainSelector, + bytes('') + ); + + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel + amount); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); + assertEq(GHO.balanceOf(user), amount); + + /* + // Burn + // mock router transfer of funds from user to token pool + vm.prank(user); + GHO.transfer(address(TOKEN_POOL), amount); + + Pool.LockOrBurnInV1 memory lockOrBurnIn = Pool.LockOrBurnInV1({ + receiver: bytes(''), + remoteChainSelector: ethChainSelector, + originalSender: user, + amount: amount, + localToken: address(GHO) + }); + + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(TOKEN_POOL), address(0), amount); + + vm.expectEmit(false, true, false, true, address(TOKEN_POOL)); + emit Burned(address(0), amount); + + vm.prank(ramp); + TOKEN_POOL.lockOrBurn(lockOrBurnIn); + + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + */ + + // ARB <> AVAX + + /* + // Mint + uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + + releaseOrMintIn = Pool.ReleaseOrMintInV1({ + originalSender: bytes(''), + remoteChainSelector: arbChainSelector, + receiver: user, + amount: amount, + localToken: address(GHO), + sourcePoolAddress: abi.encode(ARB_TOKEN_POOL), + sourcePoolData: bytes(''), + offchainTokenData: bytes('') + }); + + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(0), user, amount); + + vm.expectEmit(false, true, true, true, address(TOKEN_POOL)); + emit Minted(address(0), user, amount); + + TOKEN_POOL.releaseOrMint(releaseOrMintIn); + + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), amount); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(user), amount); + + // Burn + // mock router transfer of funds from user to token pool + vm.prank(user); + GHO.transfer(address(TOKEN_POOL), amount); + + lockOrBurnIn = Pool.LockOrBurnInV1({ + receiver: bytes(''), + remoteChainSelector: arbChainSelector, + originalSender: user, + amount: amount, + localToken: address(GHO) + }); + + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(TOKEN_POOL), address(0), amount); + + vm.expectEmit(false, true, false, true, address(TOKEN_POOL)); + emit Burned(address(0), amount); + + vm.prank(ramp); + TOKEN_POOL.lockOrBurn(lockOrBurnIn); + + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + */ + } + function _deployCcipTokenPool() internal returns (address) { address imple = address( new UpgradeableBurnMintTokenPool(AVAX_GHO_TOKEN, AVAX_RMN_PROXY, false) @@ -89,7 +232,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function _validateCcipTokenPool() internal { // Configs - uint64[] memory supportedChains = UpgradeableBurnMintTokenPool(TOKEN_POOL).getSupportedChains(); + uint64[] memory supportedChains = TOKEN_POOL.getSupportedChains(); assertEq(supportedChains.length, 2); // ETH @@ -97,11 +240,17 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // AVAX assertEq(supportedChains[1], proposal.CCIP_AVAX_CHAIN_SELECTOR()); - RateLimiter.TokenBucket memory outboundRateLimit = UpgradeableBurnMintTokenPool(TOKEN_POOL) + RateLimiter.TokenBucket memory outboundRateLimit = TOKEN_POOL .getCurrentOutboundRateLimiterState(proposal.CCIP_AVAX_CHAIN_SELECTOR()); - RateLimiter.TokenBucket memory inboundRateLimit = UpgradeableBurnMintTokenPool(TOKEN_POOL) - .getCurrentInboundRateLimiterState(proposal.CCIP_AVAX_CHAIN_SELECTOR()); + RateLimiter.TokenBucket memory inboundRateLimit = TOKEN_POOL.getCurrentInboundRateLimiterState( + proposal.CCIP_AVAX_CHAIN_SELECTOR() + ); assertEq(outboundRateLimit.isEnabled, false); assertEq(inboundRateLimit.isEnabled, false); } + + function _getFacilitatorLevel(address f) internal view returns (uint256) { + (, uint256 level) = GHO.getFacilitatorBucket(f); + return level; + } } From 76e3c91624b2c93750248032c1fcc19231e5598e Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 2 Dec 2024 14:37:05 +0700 Subject: [PATCH 35/58] test: Burn arb <> eth --- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 4de32d3df..216ab1c80 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -124,20 +124,11 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); assertEq(GHO.balanceOf(user), amount); - /* // Burn // mock router transfer of funds from user to token pool vm.prank(user); GHO.transfer(address(TOKEN_POOL), amount); - Pool.LockOrBurnInV1 memory lockOrBurnIn = Pool.LockOrBurnInV1({ - receiver: bytes(''), - remoteChainSelector: ethChainSelector, - originalSender: user, - amount: amount, - localToken: address(GHO) - }); - vm.expectEmit(true, true, true, true, address(GHO)); emit Transfer(address(TOKEN_POOL), address(0), amount); @@ -145,14 +136,18 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { emit Burned(address(0), amount); vm.prank(ramp); - TOKEN_POOL.lockOrBurn(lockOrBurnIn); + IPoolPriorTo1_5(address(TOKEN_POOL)).lockOrBurn( + user, + bytes(''), + amount, + ethChainSelector, + bytes('') + ); - assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); - assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); - */ + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); // ARB <> AVAX - /* // Mint uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); From 65ec7dcd9389e38f3d472c4fe15357dcfa3c7421 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 2 Dec 2024 15:01:53 +0700 Subject: [PATCH 36/58] test: Arb <> avax mint and burn --- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 50 ++++++++----------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 216ab1c80..3c93413b3 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -148,22 +148,9 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); // ARB <> AVAX - /* + // Mint - uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); - assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); - assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); - - releaseOrMintIn = Pool.ReleaseOrMintInV1({ - originalSender: bytes(''), - remoteChainSelector: arbChainSelector, - receiver: user, - amount: amount, - localToken: address(GHO), - sourcePoolAddress: abi.encode(ARB_TOKEN_POOL), - sourcePoolData: bytes(''), - offchainTokenData: bytes('') - }); + uint64 avaxChainSelector = proposal.CCIP_AVAX_CHAIN_SELECTOR(); vm.expectEmit(true, true, true, true, address(GHO)); emit Transfer(address(0), user, amount); @@ -171,10 +158,16 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { vm.expectEmit(false, true, true, true, address(TOKEN_POOL)); emit Minted(address(0), user, amount); - TOKEN_POOL.releaseOrMint(releaseOrMintIn); + IPoolPriorTo1_5(address(TOKEN_POOL)).releaseOrMint( + bytes(''), + user, + amount, + avaxChainSelector, + bytes('') + ); - assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), amount); - assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel + amount); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); assertEq(GHO.balanceOf(user), amount); // Burn @@ -182,14 +175,6 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { vm.prank(user); GHO.transfer(address(TOKEN_POOL), amount); - lockOrBurnIn = Pool.LockOrBurnInV1({ - receiver: bytes(''), - remoteChainSelector: arbChainSelector, - originalSender: user, - amount: amount, - localToken: address(GHO) - }); - vm.expectEmit(true, true, true, true, address(GHO)); emit Transfer(address(TOKEN_POOL), address(0), amount); @@ -197,11 +182,16 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { emit Burned(address(0), amount); vm.prank(ramp); - TOKEN_POOL.lockOrBurn(lockOrBurnIn); + IPoolPriorTo1_5(address(TOKEN_POOL)).lockOrBurn( + user, + bytes(''), + amount, + avaxChainSelector, + bytes('') + ); - assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), 0); - assertEq(GHO.balanceOf(address(TOKEN_POOL)), 0); - */ + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); } function _deployCcipTokenPool() internal returns (address) { From 1c0806ce8fc3547bf1b9b157f2555441a761fac6 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Mon, 2 Dec 2024 15:22:27 +0700 Subject: [PATCH 37/58] test: E2E eth <> arb --- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 3c93413b3..253aec0d8 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; @@ -14,9 +15,15 @@ import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {Pool} from 'ccip/libraries/Pool.sol'; import {IPoolPriorTo1_5} from 'ccip/interfaces/IPoolPriorTo1_5.sol'; +import {Internal} from 'ccip/libraries/Internal.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {EVM2EVMOnRamp} from 'ccip/onRamp/EVM2EVMOnRamp.sol'; +import {EVM2EVMOffRamp} from 'ccip/offRamp/EVM2EVMOffRamp.sol'; +import {Client} from 'ccip/libraries/Client.sol'; +import {Router} from 'ccip/Router.sol'; +import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; @@ -40,6 +47,8 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant AVAX_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant AVAX_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; + address public constant CCIP_ARB_ETH_ON_RAMP = 0x67761742ac8A21Ec4D76CA18cbd701e5A6F3Bef3; + address public constant CCIP_ARB_ETH_OFF_RAMP = 0x91e46cc5590A4B9182e47f40006140A7077Dec31; event Minted(address indexed sender, address indexed recipient, uint256 amount); event Burned(address indexed sender, uint256 amount); @@ -194,6 +203,74 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); } + /// @dev CCIP e2e eth <> arb + function test_ccipE2E_ETH_ARB() public { + GovV3Helpers.executePayload(vm, address(proposal)); + + uint64 ethChainSelector = proposal.CCIP_ETH_CHAIN_SELECTOR(); + + // Chainlink config + Router router = Router(TOKEN_POOL.getRouter()); + + { + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + // ETH -> ARB + onRampUpdates[0] = Router.OnRamp({ + destChainSelector: ethChainSelector, + onRamp: CCIP_ARB_ETH_ON_RAMP + }); + // ARB -> ETH + offRampUpdates[0] = Router.OffRamp({ + sourceChainSelector: ethChainSelector, + offRamp: CCIP_ARB_ETH_OFF_RAMP + }); + address routerOwner = router.owner(); + vm.startPrank(routerOwner); + router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + { + // OnRamp Price Registry + EVM2EVMOnRamp.DynamicConfig memory onRampDynamicConfig = EVM2EVMOnRamp(CCIP_ARB_ETH_ON_RAMP) + .getDynamicConfig(); + Internal.PriceUpdates memory priceUpdate = _getSingleTokenPriceUpdateStruct( + address(GHO), + 1e18 + ); + + IPriceRegistry(onRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + // OffRamp Price Registry + EVM2EVMOffRamp.DynamicConfig memory offRampDynamicConfig = EVM2EVMOffRamp( + CCIP_ARB_ETH_OFF_RAMP + ).getDynamicConfig(); + IPriceRegistry(offRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + } + + // User executes ccipSend + address user = makeAddr('user'); + uint256 amount = 100e18; // 100 GHO + deal(user, 1e18); // 1 ETH + + uint256 startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); + uint256 startingFacilitatorLevel = _getFacilitatorLevel(address(TOKEN_POOL)); + + // Mint tokens to user so can burn and bridge out + vm.startPrank(address(TOKEN_POOL)); + GHO.mint(user, amount); + + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel + amount); + + vm.startPrank(user); + // Use address(0) to use native token as fee token + _sendCcip(router, address(GHO), amount, address(0), ethChainSelector, user); + + assertEq(GHO.balanceOf(user), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel); + } + function _deployCcipTokenPool() internal returns (address) { address imple = address( new UpgradeableBurnMintTokenPool(AVAX_GHO_TOKEN, AVAX_RMN_PROXY, false) @@ -238,4 +315,57 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { (, uint256 level) = GHO.getFacilitatorBucket(f); return level; } + + function _sendCcip( + Router router, + address token, + uint256 amount, + address feeToken, + uint64 destChainSelector, + address receiver + ) internal { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage( + receiver, + token, + amount, + feeToken + ); + uint256 expectedFee = router.getFee(destChainSelector, message); + + IERC20(token).approve(address(router), amount); + router.ccipSend{value: expectedFee}(destChainSelector, message); + } + + function _generateSingleTokenMessage( + address receiver, + address token, + uint256 amount, + address feeToken + ) public pure returns (Client.EVM2AnyMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); + return + Client.EVM2AnyMessage({ + receiver: abi.encode(receiver), + data: '', + tokenAmounts: tokenAmounts, + feeToken: feeToken, + extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})) + }); + } + + function _getSingleTokenPriceUpdateStruct( + address token, + uint224 price + ) internal pure returns (Internal.PriceUpdates memory) { + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](1); + tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: token, usdPerToken: price}); + + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: tokenPriceUpdates, + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + + return priceUpdates; + } } From 36c3755d6dc2202991ca7411a08dce45939c7483 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 18 Dec 2024 14:48:42 +0900 Subject: [PATCH 38/58] fix: Use 1.5.1 pools --- .gitmodules | 2 +- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 75 ++++++++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index cf2009570..07649de30 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,7 +4,7 @@ [submodule "lib/ccip"] path = lib/ccip url = https://github.com/aave/ccip.git - branch = feat/1_5_token_pool + branch = feat/1_5_1_token_pool [submodule "lib/gho-core"] path = lib/gho-core url = https://github.com/aave/gho-core.git diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 253aec0d8..478d53be4 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -49,6 +49,8 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant CCIP_ARB_ETH_ON_RAMP = 0x67761742ac8A21Ec4D76CA18cbd701e5A6F3Bef3; address public constant CCIP_ARB_ETH_OFF_RAMP = 0x91e46cc5590A4B9182e47f40006140A7077Dec31; + address public constant CCIP_ARB_AVAX_ON_RAMP = 0xe80cC83B895ada027b722b78949b296Bd1fC5639; + address public constant CCIP_ARB_AVAX_OFF_RAMP = 0x95095007d5Cc3E7517A1A03c9e228adA5D0bc376; event Minted(address indexed sender, address indexed recipient, uint256 amount); event Burned(address indexed sender, uint256 amount); @@ -271,6 +273,77 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel); } + // TODO: This behaves differently on our current pools, which require chainUpdate on tokenPoolAndProxy + /// @dev CCIP e2e avax <> arb + function test_ccipE2E_AVAX_ARB() public { + GovV3Helpers.executePayload(vm, address(proposal)); + + //assertEq(TOKEN_POOL.isSupportedChain(proposal.CCIP_AVAX_CHAIN_SELECTOR()), true); + + uint64 avaxChainSelector = proposal.CCIP_AVAX_CHAIN_SELECTOR(); + + // Chainlink config + Router router = Router(TOKEN_POOL.getRouter()); + + { + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + // AVAX -> ARB + onRampUpdates[0] = Router.OnRamp({ + destChainSelector: avaxChainSelector, + onRamp: CCIP_ARB_AVAX_ON_RAMP + }); + // ARB -> AVAX + offRampUpdates[0] = Router.OffRamp({ + sourceChainSelector: avaxChainSelector, + offRamp: CCIP_ARB_AVAX_OFF_RAMP + }); + address routerOwner = router.owner(); + vm.startPrank(routerOwner); + router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + { + // OnRamp Price Registry + EVM2EVMOnRamp.DynamicConfig memory onRampDynamicConfig = EVM2EVMOnRamp(CCIP_ARB_AVAX_ON_RAMP) + .getDynamicConfig(); + Internal.PriceUpdates memory priceUpdate = _getSingleTokenPriceUpdateStruct( + address(GHO), + 1e18 + ); + + IPriceRegistry(onRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + // OffRamp Price Registry + EVM2EVMOffRamp.DynamicConfig memory offRampDynamicConfig = EVM2EVMOffRamp( + CCIP_ARB_AVAX_OFF_RAMP + ).getDynamicConfig(); + IPriceRegistry(offRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + } + + // User executes ccipSend + address user = makeAddr('user'); + uint256 amount = 100e18; // 100 GHO + deal(user, 1e18); // 1 ETH + + uint256 startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); + uint256 startingFacilitatorLevel = _getFacilitatorLevel(address(TOKEN_POOL)); + + // Mint tokens to user so can burn and bridge out + vm.startPrank(address(TOKEN_POOL)); + GHO.mint(user, amount); + + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel + amount); + + vm.startPrank(user); + // Use address(0) to use native token as fee token + _sendCcip(router, address(GHO), amount, address(0), avaxChainSelector, user); + + assertEq(GHO.balanceOf(user), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); + assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel); + } + function _deployCcipTokenPool() internal returns (address) { address imple = address( new UpgradeableBurnMintTokenPool(AVAX_GHO_TOKEN, AVAX_RMN_PROXY, false) @@ -350,7 +423,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { data: '', tokenAmounts: tokenAmounts, feeToken: feeToken, - extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})) + extraArgs: '' //Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})) }); } From 714147b2c00b2cc50d3ec654b3b684db2f51b571 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 18 Dec 2024 15:22:10 +0900 Subject: [PATCH 39/58] updated submodule --- lib/ccip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ccip b/lib/ccip index 93b0f9333..8fea66bb8 160000 --- a/lib/ccip +++ b/lib/ccip @@ -1 +1 @@ -Subproject commit 93b0f9333c13a24743413ebcf8e7739fba055eae +Subproject commit 8fea66bb81dbcb6d4c2332c1d45b68765766f3e2 From 45f97d9c88c99bdef95b79e6ef0fe29384dcfa87 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 18 Dec 2024 16:02:26 +0900 Subject: [PATCH 40/58] fix: Compilation with 1.5.1 deps --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 4 ++-- .../AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 7 ++++--- .../AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 6 +++--- .../AaveV3Ethereum_GHOAvaxLaunch_20241106.sol | 7 ++++--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 478d53be4..f5e7c2b29 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -346,7 +346,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function _deployCcipTokenPool() internal returns (address) { address imple = address( - new UpgradeableBurnMintTokenPool(AVAX_GHO_TOKEN, AVAX_RMN_PROXY, false) + new UpgradeableBurnMintTokenPool(AVAX_GHO_TOKEN, 18, AVAX_RMN_PROXY, false) ); bytes memory tokenPoolInitParams = abi.encodeWithSignature( @@ -365,7 +365,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { ); } - function _validateCcipTokenPool() internal { + function _validateCcipTokenPool() internal view { // Configs uint64[] memory supportedChains = TOKEN_POOL.getSupportedChains(); assertEq(supportedChains.length, 2); diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 0e0625902..ed9721e52 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -115,15 +115,16 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { capacity: 0, rate: 0 }); + bytes[] memory remotePools = new bytes[](1); + remotePools[0] = abi.encode(remotePool); chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ remoteChainSelector: chainSelector, - allowed: true, - remotePoolAddress: abi.encode(remotePool), + remotePoolAddresses: remotePools, remoteTokenAddress: abi.encode(remoteToken), outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - UpgradeableBurnMintTokenPool(tokenPool).applyChainUpdates(chainUpdates); + UpgradeableBurnMintTokenPool(tokenPool).applyChainUpdates(new uint64[](0), chainUpdates); } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index b3c512069..57e7ac93f 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -370,7 +370,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { } function _deployCcipTokenPool(address ghoToken) internal returns (address) { - address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, CCIP_RMN_PROXY, false)); + address imple = address(new UpgradeableBurnMintTokenPool(ghoToken, 18, CCIP_RMN_PROXY, false)); bytes memory tokenPoolInitParams = abi.encodeWithSignature( 'initialize(address,address[],address)', @@ -392,7 +392,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Test Helpers // --- - function _validateGhoDeployment() internal { + function _validateGhoDeployment() internal view { assertEq(GHO.totalSupply(), 0); assertEq(GHO.getFacilitatorsList().length, 1); assertEq(_getProxyAdminAddress(address(GHO)), MiscAvalanche.PROXY_ADMIN); @@ -401,7 +401,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertTrue(GHO.hasRole(GHO.BUCKET_MANAGER_ROLE(), GovernanceV3Avalanche.EXECUTOR_LVL_1)); } - function _validateCcipTokenPool() internal { + function _validateCcipTokenPool() internal view { // Deployment assertEq(_getProxyAdminAddress(address(TOKEN_POOL)), MiscAvalanche.PROXY_ADMIN); assertEq(TOKEN_POOL.owner(), GovernanceV3Avalanche.EXECUTOR_LVL_1); diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol index 72e9b4841..8943d475b 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol @@ -63,14 +63,15 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { capacity: 0, rate: 0 }); + bytes[] memory remotePools = new bytes[](1); + remotePools[0] = abi.encode(remotePool); chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ remoteChainSelector: chainSelector, - allowed: true, - remotePoolAddress: abi.encode(remotePool), + remotePoolAddresses: remotePools, remoteTokenAddress: abi.encode(remoteToken), outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - UpgradeableLockReleaseTokenPool(tokenPool).applyChainUpdates(chainUpdates); + UpgradeableLockReleaseTokenPool(tokenPool).applyChainUpdates(new uint64[](0), chainUpdates); } } From bcdd6c201482eb148e9364f73000b7f7575055c4 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 18 Dec 2024 17:24:31 +0900 Subject: [PATCH 41/58] fix: Avax proposal tests --- .../AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 7 +++++-- .../AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index ed9721e52..2cb70ce85 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -40,9 +40,9 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; // TODO: Enusre this pre-computed address is correct (even if we launch additional AIPs) - address public constant GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; // TODO: Wait until new token pool is deployed on Avalanche, then use corresponding address - address public constant CCIP_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; + address public constant CCIP_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ETH_GHO = MiscEthereum.GHO_TOKEN; address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; @@ -52,8 +52,11 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; function execute() external { + // For now, deploying GHO token separately + /* // 1. Deploy GHO _deployGhoToken(); + */ // 2. Accept TokenPool ownership UpgradeableBurnMintTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 57e7ac93f..3c805d2f5 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -44,7 +44,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; - address public constant GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); UpgradeableBurnMintTokenPool public TOKEN_POOL; @@ -55,6 +55,9 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function setUp() public { vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); + // TODO: Decide if we want to deploy this beforehand or in AIP + _deployGhoToken(); + // TODO: Remove this deployment once we have deployed pool address address tokenPool = _deployCcipTokenPool(GHO_TOKEN); TOKEN_POOL = UpgradeableBurnMintTokenPool(tokenPool); From e1d40c6543c485e00bd3e8c0e9127214b6797404 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Wed, 18 Dec 2024 20:45:21 +0900 Subject: [PATCH 42/58] fix: Arb apply chain updates on token pool and proxy --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 17 ++----- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 50 +++++++++++++++++-- src/interfaces/ccip/IUpgradeablePool.sol | 16 ++++++ src/interfaces/ccip/IUpgradeablePool14.sol | 18 +++++++ 4 files changed, 83 insertions(+), 18 deletions(-) create mode 100644 src/interfaces/ccip/IUpgradeablePool.sol create mode 100644 src/interfaces/ccip/IUpgradeablePool14.sol diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index bfb613c34..e82fc9bc4 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -10,18 +10,7 @@ import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; - -/// @dev Minimal interface for exiting ETH and ARB pools -interface IUpgradeablePool { - struct ChainUpdate { - uint64 remoteChainSelector; - bool allowed; - RateLimiter.Config outboundRateLimiterConfig; - RateLimiter.Config inboundRateLimiterConfig; - } - - function applyChainUpdates(ChainUpdate[] calldata updates) external; -} +import {IUpgradeablePool} from 'src/interfaces/ccip/IUpgradeablePool.sol'; /** * @title GHOAvaxLaunch @@ -42,8 +31,8 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; // TODO: Update pool address if we deploy new one address public constant CCIP_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; - address public constant AVAX_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; - address public constant AVAX_GHO = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant AVAX_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; + address public constant AVAX_GHO = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; uint256 public constant CCIP_BUCKET_CAPACITY = 1_000_000e18; // 1M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index f5e7c2b29..e8dc31a5f 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -25,6 +25,7 @@ import {Client} from 'ccip/libraries/Client.sol'; import {Router} from 'ccip/Router.sol'; import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; +import {IUpgradeablePool14} from 'src/interfaces/ccip/IUpgradeablePool14.sol'; import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; @@ -41,7 +42,8 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); address public constant TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; address public constant REGISTRY_ADMIN = 0x8a89770722c84B60cE02989Aedb22Ac4791F8C7f; - address public constant AVAX_GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant AVAX_GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; + address public constant AVAX_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; address public constant AVAX_REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; address public constant AVAX_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; address public constant AVAX_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; @@ -51,6 +53,8 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant CCIP_ARB_ETH_OFF_RAMP = 0x91e46cc5590A4B9182e47f40006140A7077Dec31; address public constant CCIP_ARB_AVAX_ON_RAMP = 0xe80cC83B895ada027b722b78949b296Bd1fC5639; address public constant CCIP_ARB_AVAX_OFF_RAMP = 0x95095007d5Cc3E7517A1A03c9e228adA5D0bc376; + address public constant TOKEN_POOL_AND_PROXY = 0x26329558f08cbb40d6a4CCA0E0C67b29D64A8c50; + uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; event Minted(address indexed sender, address indexed recipient, uint256 amount); event Burned(address indexed sender, uint256 amount); @@ -59,6 +63,10 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function setUp() public { // Execute Avax proposal to deploy Avax token pool vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); + + // TODO: Decide if we want to deploy this beforehand or in AIP + _deployGhoToken(); + // TODO: Remove this deployment once we have deployed pool address _deployCcipTokenPool(); @@ -76,6 +84,12 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Switch to Arbitrum and create proposal vm.createSelectFork(vm.rpcUrl('arbitrum'), 279521658); + + // Configure TokenPoolAndProxy for Avalanche + // Prank Registry owner + vm.startPrank(REGISTRY_ADMIN); + _configureCcipTokenPool(TOKEN_POOL_AND_PROXY, CCIP_AVAX_CHAIN_SELECTOR); + vm.stopPrank(); proposal = new AaveV3Arbitrum_GHOAvaxLaunch_20241106(); } @@ -273,13 +287,10 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel); } - // TODO: This behaves differently on our current pools, which require chainUpdate on tokenPoolAndProxy /// @dev CCIP e2e avax <> arb function test_ccipE2E_AVAX_ARB() public { GovV3Helpers.executePayload(vm, address(proposal)); - //assertEq(TOKEN_POOL.isSupportedChain(proposal.CCIP_AVAX_CHAIN_SELECTOR()), true); - uint64 avaxChainSelector = proposal.CCIP_AVAX_CHAIN_SELECTOR(); // Chainlink config @@ -344,6 +355,19 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel); } + function _deployGhoToken() internal returns (address) { + address imple = address(new UpgradeableGhoToken()); + + bytes memory ghoTokenInitParams = abi.encodeWithSignature( + 'initialize(address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1 // owner + ); + return + address( + new TransparentUpgradeableProxy(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) + ); + } + function _deployCcipTokenPool() internal returns (address) { address imple = address( new UpgradeableBurnMintTokenPool(AVAX_GHO_TOKEN, 18, AVAX_RMN_PROXY, false) @@ -365,6 +389,24 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { ); } + function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { + IUpgradeablePool14.ChainUpdate[] memory chainUpdates = new IUpgradeablePool14.ChainUpdate[](1); + RateLimiter.Config memory rateConfig = RateLimiter.Config({ + isEnabled: false, + capacity: 0, + rate: 0 + }); + chainUpdates[0] = IUpgradeablePool14.ChainUpdate({ + remoteChainSelector: chainSelector, + allowed: true, + remotePoolAddress: abi.encode(AVAX_TOKEN_POOL), + remoteTokenAddress: abi.encode(AVAX_GHO_TOKEN), + outboundRateLimiterConfig: rateConfig, + inboundRateLimiterConfig: rateConfig + }); + IUpgradeablePool14(tokenPool).applyChainUpdates(chainUpdates); + } + function _validateCcipTokenPool() internal view { // Configs uint64[] memory supportedChains = TOKEN_POOL.getSupportedChains(); diff --git a/src/interfaces/ccip/IUpgradeablePool.sol b/src/interfaces/ccip/IUpgradeablePool.sol new file mode 100644 index 000000000..48c29e0c2 --- /dev/null +++ b/src/interfaces/ccip/IUpgradeablePool.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; + +/// @dev Minimal interface for exiting ETH and ARB pools +interface IUpgradeablePool { + struct ChainUpdate { + uint64 remoteChainSelector; + bool allowed; + RateLimiter.Config outboundRateLimiterConfig; + RateLimiter.Config inboundRateLimiterConfig; + } + + function applyChainUpdates(ChainUpdate[] calldata updates) external; +} diff --git a/src/interfaces/ccip/IUpgradeablePool14.sol b/src/interfaces/ccip/IUpgradeablePool14.sol new file mode 100644 index 000000000..49e108405 --- /dev/null +++ b/src/interfaces/ccip/IUpgradeablePool14.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; + +/// @dev Minimal interface for exiting ETH and ARB pools +interface IUpgradeablePool14 { + struct ChainUpdate { + uint64 remoteChainSelector; + bool allowed; + bytes remotePoolAddress; + bytes remoteTokenAddress; + RateLimiter.Config outboundRateLimiterConfig; + RateLimiter.Config inboundRateLimiterConfig; + } + + function applyChainUpdates(ChainUpdate[] calldata updates) external; +} From 5d68817b3b99fa0174213393538fdf4db765509e Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 02:11:55 +0900 Subject: [PATCH 43/58] chore: Reorg code --- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 68 +++++++++++-------- ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 2 +- ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 22 +++--- 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index e8dc31a5f..e9e7d1f73 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -4,6 +4,17 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {IPoolPriorTo1_5} from 'ccip/interfaces/IPoolPriorTo1_5.sol'; +import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; +import {Internal} from 'ccip/libraries/Internal.sol'; +import {Pool} from 'ccip/libraries/Pool.sol'; +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {Client} from 'ccip/libraries/Client.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; +import {EVM2EVMOnRamp} from 'ccip/onRamp/EVM2EVMOnRamp.sol'; +import {EVM2EVMOffRamp} from 'ccip/offRamp/EVM2EVMOffRamp.sol'; +import {Router} from 'ccip/Router.sol'; import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; @@ -13,17 +24,6 @@ import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; -import {Pool} from 'ccip/libraries/Pool.sol'; -import {IPoolPriorTo1_5} from 'ccip/interfaces/IPoolPriorTo1_5.sol'; -import {Internal} from 'ccip/libraries/Internal.sol'; -import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; -import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; -import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; -import {EVM2EVMOnRamp} from 'ccip/onRamp/EVM2EVMOnRamp.sol'; -import {EVM2EVMOffRamp} from 'ccip/offRamp/EVM2EVMOffRamp.sol'; -import {Client} from 'ccip/libraries/Client.sol'; -import {Router} from 'ccip/Router.sol'; -import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {IUpgradeablePool14} from 'src/interfaces/ccip/IUpgradeablePool14.sol'; import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; @@ -355,6 +355,10 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(_getFacilitatorLevel(address(TOKEN_POOL)), startingFacilitatorLevel); } + // --- + // Deployment + // --- + function _deployGhoToken() internal returns (address) { address imple = address(new UpgradeableGhoToken()); @@ -389,23 +393,9 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { ); } - function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { - IUpgradeablePool14.ChainUpdate[] memory chainUpdates = new IUpgradeablePool14.ChainUpdate[](1); - RateLimiter.Config memory rateConfig = RateLimiter.Config({ - isEnabled: false, - capacity: 0, - rate: 0 - }); - chainUpdates[0] = IUpgradeablePool14.ChainUpdate({ - remoteChainSelector: chainSelector, - allowed: true, - remotePoolAddress: abi.encode(AVAX_TOKEN_POOL), - remoteTokenAddress: abi.encode(AVAX_GHO_TOKEN), - outboundRateLimiterConfig: rateConfig, - inboundRateLimiterConfig: rateConfig - }); - IUpgradeablePool14(tokenPool).applyChainUpdates(chainUpdates); - } + // --- + // Test Helpers + // --- function _validateCcipTokenPool() internal view { // Configs @@ -426,6 +416,28 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(inboundRateLimit.isEnabled, false); } + // --- + // Utils + // --- + + function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { + IUpgradeablePool14.ChainUpdate[] memory chainUpdates = new IUpgradeablePool14.ChainUpdate[](1); + RateLimiter.Config memory rateConfig = RateLimiter.Config({ + isEnabled: false, + capacity: 0, + rate: 0 + }); + chainUpdates[0] = IUpgradeablePool14.ChainUpdate({ + remoteChainSelector: chainSelector, + allowed: true, + remotePoolAddress: abi.encode(AVAX_TOKEN_POOL), + remoteTokenAddress: abi.encode(AVAX_GHO_TOKEN), + outboundRateLimiterConfig: rateConfig, + inboundRateLimiterConfig: rateConfig + }); + IUpgradeablePool14(tokenPool).applyChainUpdates(chainUpdates); + } + function _getFacilitatorLevel(address f) internal view returns (uint256) { (, uint256 level) = GHO.getFacilitatorBucket(f); return level; diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 2cb70ce85..8921778cc 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -18,8 +18,8 @@ import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol'; import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol'; -import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; +import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; /** * @title GHO Avax Launch diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 3c805d2f5..9914ffebd 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -4,24 +4,24 @@ pragma solidity ^0.8.0; import 'forge-std/Test.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; -import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; -import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; -import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; -import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; -import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; -import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; -import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; +import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {IPoolV1} from 'ccip/interfaces/IPool.sol'; +import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; import {Pool} from 'ccip/libraries/Pool.sol'; import {Internal} from 'ccip/libraries/Internal.sol'; -import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; -import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {Client} from 'ccip/libraries/Client.sol'; import {EVM2EVMOnRamp} from 'ccip/onRamp/EVM2EVMOnRamp.sol'; import {EVM2EVMOffRamp} from 'ccip/offRamp/EVM2EVMOffRamp.sol'; -import {Client} from 'ccip/libraries/Client.sol'; import {Router} from 'ccip/Router.sol'; -import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; +import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; +import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; +import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; +import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; From 43989670344718a74d7fd9092ed7512e1d15455a Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 02:22:33 +0900 Subject: [PATCH 44/58] fix: Rename token pool interfaces --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 9 +++++---- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 9 +++++---- .../{IUpgradeablePool.sol => IUpgradeableTokenPool.sol} | 2 +- ...gradeablePool14.sol => IUpgradeableTokenPool_1_4.sol} | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) rename src/interfaces/ccip/{IUpgradeablePool.sol => IUpgradeableTokenPool.sol} (92%) rename src/interfaces/ccip/{IUpgradeablePool14.sol => IUpgradeableTokenPool_1_4.sol} (92%) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index e82fc9bc4..182fc5690 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -10,7 +10,7 @@ import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; -import {IUpgradeablePool} from 'src/interfaces/ccip/IUpgradeablePool.sol'; +import {IUpgradeableTokenPool} from 'src/interfaces/ccip/IUpgradeableTokenPool.sol'; /** * @title GHOAvaxLaunch @@ -83,18 +83,19 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { } function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { - IUpgradeablePool.ChainUpdate[] memory chainUpdates = new IUpgradeablePool.ChainUpdate[](1); + IUpgradeableTokenPool.ChainUpdate[] + memory chainUpdates = new IUpgradeableTokenPool.ChainUpdate[](1); RateLimiter.Config memory rateConfig = RateLimiter.Config({ isEnabled: false, capacity: 0, rate: 0 }); - chainUpdates[0] = IUpgradeablePool.ChainUpdate({ + chainUpdates[0] = IUpgradeableTokenPool.ChainUpdate({ remoteChainSelector: chainSelector, allowed: true, outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - IUpgradeablePool(tokenPool).applyChainUpdates(chainUpdates); + IUpgradeableTokenPool(tokenPool).applyChainUpdates(chainUpdates); } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index e9e7d1f73..bfd198253 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -25,7 +25,7 @@ import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; -import {IUpgradeablePool14} from 'src/interfaces/ccip/IUpgradeablePool14.sol'; +import {IUpgradeableTokenPool_1_4} from 'src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol'; import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; @@ -421,13 +421,14 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // --- function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { - IUpgradeablePool14.ChainUpdate[] memory chainUpdates = new IUpgradeablePool14.ChainUpdate[](1); + IUpgradeableTokenPool_1_4.ChainUpdate[] + memory chainUpdates = new IUpgradeableTokenPool_1_4.ChainUpdate[](1); RateLimiter.Config memory rateConfig = RateLimiter.Config({ isEnabled: false, capacity: 0, rate: 0 }); - chainUpdates[0] = IUpgradeablePool14.ChainUpdate({ + chainUpdates[0] = IUpgradeableTokenPool_1_4.ChainUpdate({ remoteChainSelector: chainSelector, allowed: true, remotePoolAddress: abi.encode(AVAX_TOKEN_POOL), @@ -435,7 +436,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - IUpgradeablePool14(tokenPool).applyChainUpdates(chainUpdates); + IUpgradeableTokenPool_1_4(tokenPool).applyChainUpdates(chainUpdates); } function _getFacilitatorLevel(address f) internal view returns (uint256) { diff --git a/src/interfaces/ccip/IUpgradeablePool.sol b/src/interfaces/ccip/IUpgradeableTokenPool.sol similarity index 92% rename from src/interfaces/ccip/IUpgradeablePool.sol rename to src/interfaces/ccip/IUpgradeableTokenPool.sol index 48c29e0c2..150264220 100644 --- a/src/interfaces/ccip/IUpgradeablePool.sol +++ b/src/interfaces/ccip/IUpgradeableTokenPool.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; /// @dev Minimal interface for exiting ETH and ARB pools -interface IUpgradeablePool { +interface IUpgradeableTokenPool { struct ChainUpdate { uint64 remoteChainSelector; bool allowed; diff --git a/src/interfaces/ccip/IUpgradeablePool14.sol b/src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol similarity index 92% rename from src/interfaces/ccip/IUpgradeablePool14.sol rename to src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol index 49e108405..61c21b60f 100644 --- a/src/interfaces/ccip/IUpgradeablePool14.sol +++ b/src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; /// @dev Minimal interface for exiting ETH and ARB pools -interface IUpgradeablePool14 { +interface IUpgradeableTokenPool_1_4 { struct ChainUpdate { uint64 remoteChainSelector; bool allowed; From 9eab2160eea3db7ccece29e1ec9bcde4cfebbdc9 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 04:02:11 +0900 Subject: [PATCH 45/58] test: Ethereum default proposal test --- ...V3Ethereum_GHOAvaxLaunch_20241106_after.md | 11 ++ .../AaveV3Ethereum_GHOAvaxLaunch_20241106.sol | 34 ++--- ...aveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 134 ++++++++++++++++++ 3 files changed, 160 insertions(+), 19 deletions(-) create mode 100644 diffs/AaveV3Ethereum_GHOAvaxLaunch_20241106_before_AaveV3Ethereum_GHOAvaxLaunch_20241106_after.md diff --git a/diffs/AaveV3Ethereum_GHOAvaxLaunch_20241106_before_AaveV3Ethereum_GHOAvaxLaunch_20241106_after.md b/diffs/AaveV3Ethereum_GHOAvaxLaunch_20241106_before_AaveV3Ethereum_GHOAvaxLaunch_20241106_after.md new file mode 100644 index 000000000..12b5664e5 --- /dev/null +++ b/diffs/AaveV3Ethereum_GHOAvaxLaunch_20241106_before_AaveV3Ethereum_GHOAvaxLaunch_20241106_after.md @@ -0,0 +1,11 @@ +## Emodes changed + +### EMode: ETH correlated(id: 1) + + + +## Raw diff + +```json +{} +``` \ No newline at end of file diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol index 8943d475b..82d816ca3 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol @@ -7,6 +7,7 @@ import {UpgradeableLockReleaseTokenPool} from 'ccip/pools/GHO/UpgradeableLockRel import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; +import {IUpgradeableTokenPool} from 'src/interfaces/ccip/IUpgradeableTokenPool.sol'; /** * @title GHO Avax Launch @@ -24,54 +25,49 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0x411dE17f12D1A34ecC7F45f49844626267c75e81; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xb22764f98dD05c789929716D677382Df22C05Cb6; - // TODO: Wait until new token pool is deployed on Ethereum, then use corresponding address - address public constant CCIP_TOKEN_POOL = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; + address public constant CCIP_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; uint256 public constant CCIP_BRIDGE_LIMIT = 25_000_000e18; // 25M uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; function execute() external { + // TODO: Following code applies to case we deploy new pools + /* // 1. Accept TokenPool ownership UpgradeableLockReleaseTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); // 2. Configure CCIP for Arbitrum // TODO: Set remote pool and token addresses after deployment? _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); + */ // 3. Configure CCIP for Avalanche - // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_AVAX_CHAIN_SELECTOR, address(0), address(0)); + _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_AVAX_CHAIN_SELECTOR); + // TODO: Following code applies to case we deploy new pools + /* // 4. Accept Administrator role from Chainlink token manager TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(MiscEthereum.GHO_TOKEN); // 5. Link token to pool on Chainlink token admin registry TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(MiscEthereum.GHO_TOKEN, CCIP_TOKEN_POOL); + */ } - function _configureCcipTokenPool( - address tokenPool, - uint64 chainSelector, - address remotePool, - address remoteToken - ) internal { - UpgradeableTokenPool.ChainUpdate[] memory chainUpdates = new UpgradeableTokenPool.ChainUpdate[]( - 1 - ); + function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { + IUpgradeableTokenPool.ChainUpdate[] + memory chainUpdates = new IUpgradeableTokenPool.ChainUpdate[](1); RateLimiter.Config memory rateConfig = RateLimiter.Config({ isEnabled: false, capacity: 0, rate: 0 }); - bytes[] memory remotePools = new bytes[](1); - remotePools[0] = abi.encode(remotePool); - chainUpdates[0] = UpgradeableTokenPool.ChainUpdate({ + chainUpdates[0] = IUpgradeableTokenPool.ChainUpdate({ remoteChainSelector: chainSelector, - remotePoolAddresses: remotePools, - remoteTokenAddress: abi.encode(remoteToken), + allowed: true, outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - UpgradeableLockReleaseTokenPool(tokenPool).applyChainUpdates(new uint64[](0), chainUpdates); + IUpgradeableTokenPool(tokenPool).applyChainUpdates(chainUpdates); } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index 3e48e9836..2996aed0f 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -4,7 +4,31 @@ pragma solidity ^0.8.0; import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; import 'forge-std/Test.sol'; +import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {IPoolPriorTo1_5} from 'ccip/interfaces/IPoolPriorTo1_5.sol'; +import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; +import {Internal} from 'ccip/libraries/Internal.sol'; +import {Pool} from 'ccip/libraries/Pool.sol'; +import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; +import {Client} from 'ccip/libraries/Client.sol'; +import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; +import {EVM2EVMOnRamp} from 'ccip/onRamp/EVM2EVMOnRamp.sol'; +import {EVM2EVMOffRamp} from 'ccip/offRamp/EVM2EVMOffRamp.sol'; +import {Router} from 'ccip/Router.sol'; import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; +import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; +import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; +import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; +import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; +import {IUpgradeableTokenPool_1_4} from 'src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol'; +import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; import {AaveV3Ethereum_GHOAvaxLaunch_20241106} from './AaveV3Ethereum_GHOAvaxLaunch_20241106.sol'; /** @@ -14,8 +38,55 @@ import {AaveV3Ethereum_GHOAvaxLaunch_20241106} from './AaveV3Ethereum_GHOAvaxLau contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { AaveV3Ethereum_GHOAvaxLaunch_20241106 internal proposal; + UpgradeableBurnMintTokenPool public constant TOKEN_POOL = + UpgradeableBurnMintTokenPool(MiscEthereum.GHO_CCIP_TOKEN_POOL); + + address public constant AVAX_GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; + address public constant AVAX_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; + address public constant AVAX_REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; + address public constant AVAX_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; + address public constant AVAX_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; + address public constant AVAX_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; + uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; + + event Minted(address indexed sender, address indexed recipient, uint256 amount); + event Burned(address indexed sender, uint256 amount); + event Transfer(address indexed from, address indexed to, uint256 value); + function setUp() public { + // Execute Avax proposal to deploy Avax token pool + vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); + + // TODO: Decide if we want to deploy this beforehand or in AIP + _deployGhoToken(); + + // TODO: Remove this deployment once we have deployed pool address + _deployCcipTokenPool(); + + // TODO: Remove this (will be done on chainlink's side) + // Prank chainlink and set up admin role to be accepted on token registry + vm.startPrank(AVAX_REGISTRY_ADMIN); + TokenAdminRegistry(AVAX_TOKEN_ADMIN_REGISTRY).proposeAdministrator( + AVAX_GHO_TOKEN, + GovernanceV3Avalanche.EXECUTOR_LVL_1 + ); + vm.stopPrank(); + + AaveV3Avalanche_GHOAvaxLaunch_20241106 avaxProposal = new AaveV3Avalanche_GHOAvaxLaunch_20241106(); + GovV3Helpers.executePayload(vm, address(avaxProposal)); + + // Switch to Ethereum and create proposal vm.createSelectFork(vm.rpcUrl('mainnet'), 21133428); + + // TODO: Find tokenPoolAndProxy address on Eth pool + // Configure TokenPoolAndProxy for Avalanche + // Prank Registry owner + /* + vm.startPrank(REGISTRY_ADMIN); + _configureCcipTokenPool(TOKEN_POOL_AND_PROXY, CCIP_AVAX_CHAIN_SELECTOR); + vm.stopPrank(); + */ proposal = new AaveV3Ethereum_GHOAvaxLaunch_20241106(); } @@ -24,5 +95,68 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { */ function test_defaultProposalExecution() public { defaultTest('AaveV3Ethereum_GHOAvaxLaunch_20241106', AaveV3Ethereum.POOL, address(proposal)); + + _validateCcipTokenPool(); + } + + // --- + // Deployment + // --- + + function _deployGhoToken() internal returns (address) { + address imple = address(new UpgradeableGhoToken()); + + bytes memory ghoTokenInitParams = abi.encodeWithSignature( + 'initialize(address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1 // owner + ); + return + address( + new TransparentUpgradeableProxy(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) + ); + } + + function _deployCcipTokenPool() internal returns (address) { + address imple = address( + new UpgradeableBurnMintTokenPool(AVAX_GHO_TOKEN, 18, AVAX_RMN_PROXY, false) + ); + + bytes memory tokenPoolInitParams = abi.encodeWithSignature( + 'initialize(address,address[],address)', + GovernanceV3Avalanche.EXECUTOR_LVL_1, // owner + new address[](0), // allowList + AVAX_ROUTER // router + ); + return + address( + new TransparentUpgradeableProxy( + imple, // logic + MiscAvalanche.PROXY_ADMIN, // proxy admin + tokenPoolInitParams // data + ) + ); + } + + // --- + // Test Helpers + // --- + + function _validateCcipTokenPool() internal view { + // Configs + uint64[] memory supportedChains = TOKEN_POOL.getSupportedChains(); + assertEq(supportedChains.length, 2); + + // ARB + assertEq(supportedChains[0], proposal.CCIP_ARB_CHAIN_SELECTOR()); + + // AVAX + assertEq(supportedChains[1], proposal.CCIP_AVAX_CHAIN_SELECTOR()); + RateLimiter.TokenBucket memory outboundRateLimit = TOKEN_POOL + .getCurrentOutboundRateLimiterState(proposal.CCIP_AVAX_CHAIN_SELECTOR()); + RateLimiter.TokenBucket memory inboundRateLimit = TOKEN_POOL.getCurrentInboundRateLimiterState( + proposal.CCIP_AVAX_CHAIN_SELECTOR() + ); + assertEq(outboundRateLimit.isEnabled, false); + assertEq(inboundRateLimit.isEnabled, false); } } From 06b447398d569dbceeaa73b98904152852ee1888 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 15:29:29 +0900 Subject: [PATCH 46/58] test: Eth basic lock release --- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 3 +- ...aveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 146 +++++++++++++++++- 2 files changed, 143 insertions(+), 6 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index bfd198253..b5fdb6fab 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -36,10 +36,11 @@ import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxL contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { AaveV3Arbitrum_GHOAvaxLaunch_20241106 internal proposal; - address public constant GHO_TOKEN = AaveV3ArbitrumAssets.GHO_UNDERLYING; UpgradeableBurnMintTokenPool public constant TOKEN_POOL = UpgradeableBurnMintTokenPool(MiscArbitrum.GHO_CCIP_TOKEN_POOL); + address public constant GHO_TOKEN = AaveV3ArbitrumAssets.GHO_UNDERLYING; UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); + address public constant TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; address public constant REGISTRY_ADMIN = 0x8a89770722c84B60cE02989Aedb22Ac4791F8C7f; address public constant AVAX_GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index 2996aed0f..da29d74e9 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -7,6 +7,7 @@ import 'forge-std/Test.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; +import {UpgradeableLockReleaseTokenPool} from 'ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol'; import {IPoolPriorTo1_5} from 'ccip/interfaces/IPoolPriorTo1_5.sol'; import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; import {Internal} from 'ccip/libraries/Internal.sol'; @@ -22,7 +23,7 @@ import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; -import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; @@ -38,8 +39,10 @@ import {AaveV3Ethereum_GHOAvaxLaunch_20241106} from './AaveV3Ethereum_GHOAvaxLau contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { AaveV3Ethereum_GHOAvaxLaunch_20241106 internal proposal; - UpgradeableBurnMintTokenPool public constant TOKEN_POOL = - UpgradeableBurnMintTokenPool(MiscEthereum.GHO_CCIP_TOKEN_POOL); + UpgradeableLockReleaseTokenPool public constant TOKEN_POOL = + UpgradeableLockReleaseTokenPool(MiscEthereum.GHO_CCIP_TOKEN_POOL); + address public constant GHO_TOKEN = AaveV3EthereumAssets.GHO_UNDERLYING; + UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); address public constant AVAX_GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; address public constant AVAX_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; @@ -50,8 +53,9 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; - event Minted(address indexed sender, address indexed recipient, uint256 amount); - event Burned(address indexed sender, uint256 amount); + event Released(address indexed sender, address indexed recipient, uint256 amount); + event Locked(address indexed sender, uint256 amount); + event CCIPSendRequested(Internal.EVM2EVMMessage message); event Transfer(address indexed from, address indexed to, uint256 value); function setUp() public { @@ -99,6 +103,115 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { _validateCcipTokenPool(); } + /// @dev Test burn and mint actions, mocking CCIP calls + function test_ccipTokenPool() public { + GovV3Helpers.executePayload(vm, address(proposal)); + + // Mock calls + address router = TOKEN_POOL.getRouter(); + address ramp = makeAddr('ramp'); + vm.mockCall( + router, + abi.encodeWithSelector(bytes4(keccak256('getOnRamp(uint64)'))), + abi.encode(ramp) + ); + vm.mockCall( + router, + abi.encodeWithSelector(bytes4(keccak256('isOffRamp(uint64,address)'))), + abi.encode(true) + ); + + // Prank user + address user = makeAddr('user'); + + // ETH <> ARB + + // Lock + uint256 amount = 100e18; // 100 GHO + deal(address(GHO), user, amount); + uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); + + uint256 startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); + + // mock router transfer of funds from user to token pool + vm.prank(user); + GHO.transfer(address(TOKEN_POOL), amount); + + vm.expectEmit(false, true, false, true, address(TOKEN_POOL)); + emit Locked(address(0), amount); + + vm.prank(ramp); + IPoolPriorTo1_5(address(TOKEN_POOL)).lockOrBurn( + user, + bytes(''), + amount, + arbChainSelector, + bytes('') + ); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance + amount); + assertEq(GHO.balanceOf(user), 0); + + // Release + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(TOKEN_POOL), user, amount); + + vm.expectEmit(false, true, true, true, address(TOKEN_POOL)); + emit Released(address(0), user, amount); + + IPoolPriorTo1_5(address(TOKEN_POOL)).releaseOrMint( + bytes(''), + user, + amount, + arbChainSelector, + bytes('') + ); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); + assertEq(GHO.balanceOf(user), amount); + + // ETH <> AVAX + + // Lock + deal(address(GHO), user, amount); + uint64 avaxChainSelector = proposal.CCIP_AVAX_CHAIN_SELECTOR(); + + startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); + + // mock router transfer of funds from user to token pool + vm.prank(user); + GHO.transfer(address(TOKEN_POOL), amount); + + vm.expectEmit(false, true, false, true, address(TOKEN_POOL)); + emit Locked(address(0), amount); + + vm.prank(ramp); + IPoolPriorTo1_5(address(TOKEN_POOL)).lockOrBurn( + user, + bytes(''), + amount, + arbChainSelector, + bytes('') + ); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance + amount); + assertEq(GHO.balanceOf(user), 0); + + // Release + vm.expectEmit(true, true, true, true, address(GHO)); + emit Transfer(address(TOKEN_POOL), user, amount); + + vm.expectEmit(false, true, true, true, address(TOKEN_POOL)); + emit Released(address(0), user, amount); + + IPoolPriorTo1_5(address(TOKEN_POOL)).releaseOrMint( + bytes(''), + user, + amount, + arbChainSelector, + bytes('') + ); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); + assertEq(GHO.balanceOf(user), amount); + } + // --- // Deployment // --- @@ -159,4 +272,27 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(outboundRateLimit.isEnabled, false); assertEq(inboundRateLimit.isEnabled, false); } + + // --- + // Utils + // --- + + function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { + IUpgradeableTokenPool_1_4.ChainUpdate[] + memory chainUpdates = new IUpgradeableTokenPool_1_4.ChainUpdate[](1); + RateLimiter.Config memory rateConfig = RateLimiter.Config({ + isEnabled: false, + capacity: 0, + rate: 0 + }); + chainUpdates[0] = IUpgradeableTokenPool_1_4.ChainUpdate({ + remoteChainSelector: chainSelector, + allowed: true, + remotePoolAddress: abi.encode(AVAX_TOKEN_POOL), + remoteTokenAddress: abi.encode(AVAX_GHO_TOKEN), + outboundRateLimiterConfig: rateConfig, + inboundRateLimiterConfig: rateConfig + }); + IUpgradeableTokenPool_1_4(tokenPool).applyChainUpdates(chainUpdates); + } } From aee6a8890597c3546baa896f98ea8f5d36895e08 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 17:59:57 +0900 Subject: [PATCH 47/58] wip: Eth proposal e2e test --- ...aveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 130 +++++++++++++++++- 1 file changed, 126 insertions(+), 4 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index da29d74e9..369a7101a 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -50,6 +50,10 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant AVAX_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; address public constant AVAX_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant AVAX_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; + address public constant CCIP_ETH_ARB_ON_RAMP = 0x69eCC4E2D8ea56E2d0a05bF57f4Fd6aEE7f2c284; + address public constant CCIP_ETH_ARB_OFF_RAMP = 0xdf615eF8D4C64d0ED8Fd7824BBEd2f6a10245aC9; + address public constant TOKEN_POOL_AND_PROXY = 0x9Ec9F9804733df96D1641666818eFb5198eC50f0; + address public constant REGISTRY_ADMIN = 0x44835bBBA9D40DEDa9b64858095EcFB2693c9449; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; @@ -83,14 +87,15 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Switch to Ethereum and create proposal vm.createSelectFork(vm.rpcUrl('mainnet'), 21133428); - // TODO: Find tokenPoolAndProxy address on Eth pool + // TODO: Unsure if this is needed + /* // Configure TokenPoolAndProxy for Avalanche // Prank Registry owner - /* vm.startPrank(REGISTRY_ADMIN); _configureCcipTokenPool(TOKEN_POOL_AND_PROXY, CCIP_AVAX_CHAIN_SELECTOR); vm.stopPrank(); */ + proposal = new AaveV3Ethereum_GHOAvaxLaunch_20241106(); } @@ -188,7 +193,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { user, bytes(''), amount, - arbChainSelector, + avaxChainSelector, bytes('') ); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance + amount); @@ -205,13 +210,77 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { bytes(''), user, amount, - arbChainSelector, + avaxChainSelector, bytes('') ); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); assertEq(GHO.balanceOf(user), amount); } + /// @dev CCIP e2e arb <> eth + function test_ccipE2E_ARB_ETH() public { + GovV3Helpers.executePayload(vm, address(proposal)); + + uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); + + // Chainlink config + Router router = Router(TOKEN_POOL.getRouter()); + + { + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + // ARB -> ETH + onRampUpdates[0] = Router.OnRamp({ + destChainSelector: arbChainSelector, + onRamp: CCIP_ETH_ARB_ON_RAMP + }); + // ETH -> ARB + offRampUpdates[0] = Router.OffRamp({ + sourceChainSelector: arbChainSelector, + offRamp: CCIP_ETH_ARB_OFF_RAMP + }); + address routerOwner = router.owner(); + vm.startPrank(routerOwner); + router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + { + // OnRamp Price Registry + EVM2EVMOnRamp.DynamicConfig memory onRampDynamicConfig = EVM2EVMOnRamp(CCIP_ETH_ARB_ON_RAMP) + .getDynamicConfig(); + Internal.PriceUpdates memory priceUpdate = _getSingleTokenPriceUpdateStruct( + address(GHO), + 1e18 + ); + + IPriceRegistry(onRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + // OffRamp Price Registry + EVM2EVMOffRamp.DynamicConfig memory offRampDynamicConfig = EVM2EVMOffRamp( + CCIP_ETH_ARB_OFF_RAMP + ).getDynamicConfig(); + IPriceRegistry(offRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + } + + // User executes ccipSend + address user = makeAddr('user'); + uint256 amount = 100e18; // 100 GHO + deal(user, 1e18); // 1 ETH + deal(address(GHO), user, amount); + + uint256 startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); + uint256 startingBridgeLimit = TOKEN_POOL.getBridgeLimit(); + uint256 startingBridgedAmount = TOKEN_POOL.getCurrentBridgedAmount(); + + vm.startPrank(user); + // Use address(0) to use native token as fee token + _sendCcip(router, address(GHO), amount, address(0), arbChainSelector, user); + + assertEq(GHO.balanceOf(user), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance + amount); + assertEq(TOKEN_POOL.getBridgeLimit(), startingBridgeLimit); + assertEq(TOKEN_POOL.getCurrentBridgedAmount(), startingBridgedAmount + amount); + } + // --- // Deployment // --- @@ -277,6 +346,44 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Utils // --- + function _sendCcip( + Router router, + address token, + uint256 amount, + address feeToken, + uint64 destChainSelector, + address receiver + ) internal { + Client.EVM2AnyMessage memory message = _generateSingleTokenMessage( + receiver, + token, + amount, + feeToken + ); + uint256 expectedFee = router.getFee(destChainSelector, message); + + IERC20(token).approve(address(router), amount); + router.ccipSend{value: expectedFee}(destChainSelector, message); + } + + function _generateSingleTokenMessage( + address receiver, + address token, + uint256 amount, + address feeToken + ) public pure returns (Client.EVM2AnyMessage memory) { + Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); + tokenAmounts[0] = Client.EVMTokenAmount({token: token, amount: amount}); + return + Client.EVM2AnyMessage({ + receiver: abi.encode(receiver), + data: '', + tokenAmounts: tokenAmounts, + feeToken: feeToken, + extraArgs: '' //Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 200_000})) + }); + } + function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { IUpgradeableTokenPool_1_4.ChainUpdate[] memory chainUpdates = new IUpgradeableTokenPool_1_4.ChainUpdate[](1); @@ -295,4 +402,19 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { }); IUpgradeableTokenPool_1_4(tokenPool).applyChainUpdates(chainUpdates); } + + function _getSingleTokenPriceUpdateStruct( + address token, + uint224 price + ) internal pure returns (Internal.PriceUpdates memory) { + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](1); + tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: token, usdPerToken: price}); + + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: tokenPriceUpdates, + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + + return priceUpdates; + } } From a1dbbae7be90e48ed268efb74668890f07d4e84f Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 18:05:42 +0900 Subject: [PATCH 48/58] fix: Eth <> arb e2e test --- ...aveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index 369a7101a..984c447c0 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -223,44 +223,8 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); - // Chainlink config Router router = Router(TOKEN_POOL.getRouter()); - { - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - // ARB -> ETH - onRampUpdates[0] = Router.OnRamp({ - destChainSelector: arbChainSelector, - onRamp: CCIP_ETH_ARB_ON_RAMP - }); - // ETH -> ARB - offRampUpdates[0] = Router.OffRamp({ - sourceChainSelector: arbChainSelector, - offRamp: CCIP_ETH_ARB_OFF_RAMP - }); - address routerOwner = router.owner(); - vm.startPrank(routerOwner); - router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - { - // OnRamp Price Registry - EVM2EVMOnRamp.DynamicConfig memory onRampDynamicConfig = EVM2EVMOnRamp(CCIP_ETH_ARB_ON_RAMP) - .getDynamicConfig(); - Internal.PriceUpdates memory priceUpdate = _getSingleTokenPriceUpdateStruct( - address(GHO), - 1e18 - ); - - IPriceRegistry(onRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); - // OffRamp Price Registry - EVM2EVMOffRamp.DynamicConfig memory offRampDynamicConfig = EVM2EVMOffRamp( - CCIP_ETH_ARB_OFF_RAMP - ).getDynamicConfig(); - IPriceRegistry(offRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); - } - // User executes ccipSend address user = makeAddr('user'); uint256 amount = 100e18; // 100 GHO From ec7883675977774807fe8f664c10f82453aec371 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 18:44:33 +0900 Subject: [PATCH 49/58] wip: Eth <> avax e2e test --- ...aveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 71 ++++++++++++++++++- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index 984c447c0..c94342fb9 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -52,6 +52,8 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant AVAX_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant CCIP_ETH_ARB_ON_RAMP = 0x69eCC4E2D8ea56E2d0a05bF57f4Fd6aEE7f2c284; address public constant CCIP_ETH_ARB_OFF_RAMP = 0xdf615eF8D4C64d0ED8Fd7824BBEd2f6a10245aC9; + address public constant CCIP_ETH_AVAX_ON_RAMP = 0xaFd31C0C78785aDF53E4c185670bfd5376249d8A; + address public constant CCIP_ETH_AVAX_OFF_RAMP = 0xd98E80C79a15E4dbaF4C40B6cCDF690fe619BFBb; address public constant TOKEN_POOL_AND_PROXY = 0x9Ec9F9804733df96D1641666818eFb5198eC50f0; address public constant REGISTRY_ADMIN = 0x44835bBBA9D40DEDa9b64858095EcFB2693c9449; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; @@ -87,14 +89,11 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Switch to Ethereum and create proposal vm.createSelectFork(vm.rpcUrl('mainnet'), 21133428); - // TODO: Unsure if this is needed - /* // Configure TokenPoolAndProxy for Avalanche // Prank Registry owner vm.startPrank(REGISTRY_ADMIN); _configureCcipTokenPool(TOKEN_POOL_AND_PROXY, CCIP_AVAX_CHAIN_SELECTOR); vm.stopPrank(); - */ proposal = new AaveV3Ethereum_GHOAvaxLaunch_20241106(); } @@ -245,6 +244,72 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(TOKEN_POOL.getCurrentBridgedAmount(), startingBridgedAmount + amount); } + /// @dev CCIP e2e avax <> eth + function test_ccipE2E_AVAX_ETH() public { + GovV3Helpers.executePayload(vm, address(proposal)); + + uint64 avaxChainSelector = proposal.CCIP_AVAX_CHAIN_SELECTOR(); + + // Chainlink config + Router router = Router(TOKEN_POOL.getRouter()); + + /* + { + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + // AVAX -> ETH + onRampUpdates[0] = Router.OnRamp({ + destChainSelector: avaxChainSelector, + onRamp: CCIP_ETH_AVAX_ON_RAMP + }); + // ETH -> AVAX + offRampUpdates[0] = Router.OffRamp({ + sourceChainSelector: avaxChainSelector, + offRamp: CCIP_ETH_AVAX_OFF_RAMP + }); + address routerOwner = router.owner(); + vm.startPrank(routerOwner); + router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + { + // OnRamp Price Registry + EVM2EVMOnRamp.DynamicConfig memory onRampDynamicConfig = EVM2EVMOnRamp(CCIP_ETH_AVAX_ON_RAMP) + .getDynamicConfig(); + Internal.PriceUpdates memory priceUpdate = _getSingleTokenPriceUpdateStruct( + address(GHO), + 1e18 + ); + + IPriceRegistry(onRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + // OffRamp Price Registry + EVM2EVMOffRamp.DynamicConfig memory offRampDynamicConfig = EVM2EVMOffRamp( + CCIP_ETH_AVAX_OFF_RAMP + ).getDynamicConfig(); + IPriceRegistry(offRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); + } + */ + + // User executes ccipSend + address user = makeAddr('user'); + uint256 amount = 100e18; // 100 GHO + deal(user, 1e18); // 1 ETH + deal(address(GHO), user, amount); + + uint256 startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); + uint256 startingBridgeLimit = TOKEN_POOL.getBridgeLimit(); + uint256 startingBridgedAmount = TOKEN_POOL.getCurrentBridgedAmount(); + + vm.startPrank(user); + // Use address(0) to use native token as fee token + _sendCcip(router, address(GHO), amount, address(0), avaxChainSelector, user); + + assertEq(GHO.balanceOf(user), 0); + assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance + amount); + assertEq(TOKEN_POOL.getBridgeLimit(), startingBridgeLimit); + assertEq(TOKEN_POOL.getCurrentBridgedAmount(), startingBridgedAmount + amount); + } + // --- // Deployment // --- From 66ebf7c5b4e19c4cbc64ec935d000e08a30b1a4e Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 20:58:31 +0900 Subject: [PATCH 50/58] fix: Avax <> eth e2e test --- ...V3Ethereum_GHOAvaxLaunch_20241106_after.md | 8 ++ ...aveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 77 +++++-------------- 2 files changed, 28 insertions(+), 57 deletions(-) diff --git a/diffs/AaveV3Ethereum_GHOAvaxLaunch_20241106_before_AaveV3Ethereum_GHOAvaxLaunch_20241106_after.md b/diffs/AaveV3Ethereum_GHOAvaxLaunch_20241106_before_AaveV3Ethereum_GHOAvaxLaunch_20241106_after.md index 12b5664e5..95861275d 100644 --- a/diffs/AaveV3Ethereum_GHOAvaxLaunch_20241106_before_AaveV3Ethereum_GHOAvaxLaunch_20241106_after.md +++ b/diffs/AaveV3Ethereum_GHOAvaxLaunch_20241106_before_AaveV3Ethereum_GHOAvaxLaunch_20241106_after.md @@ -4,6 +4,14 @@ +### EMode: sUSDe Stablecoins(id: 2) + + + +### EMode: rsETH LST main(id: 3) + + + ## Raw diff ```json diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index c94342fb9..82e750a73 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -87,7 +87,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { GovV3Helpers.executePayload(vm, address(avaxProposal)); // Switch to Ethereum and create proposal - vm.createSelectFork(vm.rpcUrl('mainnet'), 21133428); + vm.createSelectFork(vm.rpcUrl('mainnet'), 21436313); // Configure TokenPoolAndProxy for Avalanche // Prank Registry owner @@ -253,43 +253,6 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Chainlink config Router router = Router(TOKEN_POOL.getRouter()); - /* - { - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - // AVAX -> ETH - onRampUpdates[0] = Router.OnRamp({ - destChainSelector: avaxChainSelector, - onRamp: CCIP_ETH_AVAX_ON_RAMP - }); - // ETH -> AVAX - offRampUpdates[0] = Router.OffRamp({ - sourceChainSelector: avaxChainSelector, - offRamp: CCIP_ETH_AVAX_OFF_RAMP - }); - address routerOwner = router.owner(); - vm.startPrank(routerOwner); - router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - { - // OnRamp Price Registry - EVM2EVMOnRamp.DynamicConfig memory onRampDynamicConfig = EVM2EVMOnRamp(CCIP_ETH_AVAX_ON_RAMP) - .getDynamicConfig(); - Internal.PriceUpdates memory priceUpdate = _getSingleTokenPriceUpdateStruct( - address(GHO), - 1e18 - ); - - IPriceRegistry(onRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); - // OffRamp Price Registry - EVM2EVMOffRamp.DynamicConfig memory offRampDynamicConfig = EVM2EVMOffRamp( - CCIP_ETH_AVAX_OFF_RAMP - ).getDynamicConfig(); - IPriceRegistry(offRampDynamicConfig.priceRegistry).updatePrices(priceUpdate); - } - */ - // User executes ccipSend address user = makeAddr('user'); uint256 amount = 100e18; // 100 GHO @@ -375,6 +338,25 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Utils // --- + function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { + IUpgradeableTokenPool_1_4.ChainUpdate[] + memory chainUpdates = new IUpgradeableTokenPool_1_4.ChainUpdate[](1); + RateLimiter.Config memory rateConfig = RateLimiter.Config({ + isEnabled: false, + capacity: 0, + rate: 0 + }); + chainUpdates[0] = IUpgradeableTokenPool_1_4.ChainUpdate({ + remoteChainSelector: chainSelector, + allowed: true, + remotePoolAddress: abi.encode(AVAX_TOKEN_POOL), + remoteTokenAddress: abi.encode(AVAX_GHO_TOKEN), + outboundRateLimiterConfig: rateConfig, + inboundRateLimiterConfig: rateConfig + }); + IUpgradeableTokenPool_1_4(tokenPool).applyChainUpdates(chainUpdates); + } + function _sendCcip( Router router, address token, @@ -413,25 +395,6 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { }); } - function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { - IUpgradeableTokenPool_1_4.ChainUpdate[] - memory chainUpdates = new IUpgradeableTokenPool_1_4.ChainUpdate[](1); - RateLimiter.Config memory rateConfig = RateLimiter.Config({ - isEnabled: false, - capacity: 0, - rate: 0 - }); - chainUpdates[0] = IUpgradeableTokenPool_1_4.ChainUpdate({ - remoteChainSelector: chainSelector, - allowed: true, - remotePoolAddress: abi.encode(AVAX_TOKEN_POOL), - remoteTokenAddress: abi.encode(AVAX_GHO_TOKEN), - outboundRateLimiterConfig: rateConfig, - inboundRateLimiterConfig: rateConfig - }); - IUpgradeableTokenPool_1_4(tokenPool).applyChainUpdates(chainUpdates); - } - function _getSingleTokenPriceUpdateStruct( address token, uint224 price From e6717c8560062e5654dbba0729b3afd3343e92d3 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 21:16:16 +0900 Subject: [PATCH 51/58] chore: Cleanup arbitrum proposal --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 63 +------------------ ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 40 +++++------- 2 files changed, 17 insertions(+), 86 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index 182fc5690..fb9a0a7d8 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -2,14 +2,8 @@ pragma solidity ^0.8.0; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; -import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; -import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; -import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; -import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; -import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; -import {IGhoToken} from 'gho-core/gho/interfaces/IGhoToken.sol'; import {IUpgradeableTokenPool} from 'src/interfaces/ccip/IUpgradeableTokenPool.sol'; /** @@ -17,69 +11,14 @@ import {IUpgradeableTokenPool} from 'src/interfaces/ccip/IUpgradeableTokenPool.s * @author Aave Labs * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 - * @dev This payload consists of the following set of actions: - * 1. Accept ownership of CCIP TokenPool - * 2. Configure CCIP TokenPool for Ethereum - * 3. Configure CCIP TokenPool for Avalanche - * 4. Add CCIP TokenPool as GHO Facilitator (allowing burn and mint) - * 5. Accept administrator role from Chainlink token admin registry - * 6. Link token to pool on Chainlink token admin registry + * @dev This payload configures the CCIP TokenPool for Avalanche */ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { - address public constant CCIP_RMN_PROXY = 0xC311a21e6fEf769344EB1515588B9d535662a145; - address public constant CCIP_ROUTER = 0x141fa059441E0ca23ce184B6A78bafD2A517DdE8; - address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; - // TODO: Update pool address if we deploy new one address public constant CCIP_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; - address public constant AVAX_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; - address public constant AVAX_GHO = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; - uint256 public constant CCIP_BUCKET_CAPACITY = 1_000_000e18; // 1M - uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; function execute() external { - // TODO: Following code applies to case we deploy new pools - /* - // 1. Accept TokenPool ownership - UpgradeableBurnMintTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); - - // 2. Configure CCIP TokenPool for Ethereum - // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ETH_CHAIN_SELECTOR, address(0), address(0)); - */ - - // TODO: Update addresses if we deploy new pools - // 3. Configure CCIP TokenPool for Avalanche _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_AVAX_CHAIN_SELECTOR); - - // TODO: Following code applies to case we deploy new pools - /* - // 4. Add CCIP TokenPool as GHO Facilitator - IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).grantRole( - IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).FACILITATOR_MANAGER_ROLE(), - GovernanceV3Arbitrum.EXECUTOR_LVL_1 - ); - IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).grantRole( - IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).BUCKET_MANAGER_ROLE(), - GovernanceV3Arbitrum.EXECUTOR_LVL_1 - ); - IGhoToken(AaveV3ArbitrumAssets.GHO_UNDERLYING).addFacilitator( - CCIP_TOKEN_POOL, - 'CCIP TokenPool', - uint128(CCIP_BUCKET_CAPACITY) - ); - - // 5. Accept administrator role from Chainlink token manager - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole( - AaveV3ArbitrumAssets.GHO_UNDERLYING - ); - - // 6. Link token to pool on Chainlink token admin registry - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool( - AaveV3ArbitrumAssets.GHO_UNDERLYING, - CCIP_TOKEN_POOL - ); - */ } function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index b5fdb6fab..cfd97bc74 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -8,18 +8,16 @@ import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTo import {IPoolPriorTo1_5} from 'ccip/interfaces/IPoolPriorTo1_5.sol'; import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; import {Internal} from 'ccip/libraries/Internal.sol'; -import {Pool} from 'ccip/libraries/Pool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {Client} from 'ccip/libraries/Client.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {EVM2EVMOnRamp} from 'ccip/onRamp/EVM2EVMOnRamp.sol'; import {EVM2EVMOffRamp} from 'ccip/offRamp/EVM2EVMOffRamp.sol'; import {Router} from 'ccip/Router.sol'; -import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; -import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; @@ -56,6 +54,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant CCIP_ARB_AVAX_OFF_RAMP = 0x95095007d5Cc3E7517A1A03c9e228adA5D0bc376; address public constant TOKEN_POOL_AND_PROXY = 0x26329558f08cbb40d6a4CCA0E0C67b29D64A8c50; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; + uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; event Minted(address indexed sender, address indexed recipient, uint256 amount); event Burned(address indexed sender, uint256 amount); @@ -128,7 +127,6 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Mint uint256 amount = 100e18; - uint64 ethChainSelector = proposal.CCIP_ETH_CHAIN_SELECTOR(); uint256 startingFacilitatorLevel = _getFacilitatorLevel(address(TOKEN_POOL)); uint256 startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); @@ -142,7 +140,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { bytes(''), user, amount, - ethChainSelector, + CCIP_ETH_CHAIN_SELECTOR, bytes('') ); @@ -166,7 +164,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { user, bytes(''), amount, - ethChainSelector, + CCIP_ETH_CHAIN_SELECTOR, bytes('') ); @@ -176,8 +174,6 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // ARB <> AVAX // Mint - uint64 avaxChainSelector = proposal.CCIP_AVAX_CHAIN_SELECTOR(); - vm.expectEmit(true, true, true, true, address(GHO)); emit Transfer(address(0), user, amount); @@ -188,7 +184,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { bytes(''), user, amount, - avaxChainSelector, + CCIP_AVAX_CHAIN_SELECTOR, bytes('') ); @@ -212,7 +208,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { user, bytes(''), amount, - avaxChainSelector, + CCIP_AVAX_CHAIN_SELECTOR, bytes('') ); @@ -224,8 +220,6 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function test_ccipE2E_ETH_ARB() public { GovV3Helpers.executePayload(vm, address(proposal)); - uint64 ethChainSelector = proposal.CCIP_ETH_CHAIN_SELECTOR(); - // Chainlink config Router router = Router(TOKEN_POOL.getRouter()); @@ -234,12 +228,12 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); // ETH -> ARB onRampUpdates[0] = Router.OnRamp({ - destChainSelector: ethChainSelector, + destChainSelector: CCIP_ETH_CHAIN_SELECTOR, onRamp: CCIP_ARB_ETH_ON_RAMP }); // ARB -> ETH offRampUpdates[0] = Router.OffRamp({ - sourceChainSelector: ethChainSelector, + sourceChainSelector: CCIP_ETH_CHAIN_SELECTOR, offRamp: CCIP_ARB_ETH_OFF_RAMP }); address routerOwner = router.owner(); @@ -281,7 +275,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { vm.startPrank(user); // Use address(0) to use native token as fee token - _sendCcip(router, address(GHO), amount, address(0), ethChainSelector, user); + _sendCcip(router, address(GHO), amount, address(0), CCIP_ETH_CHAIN_SELECTOR, user); assertEq(GHO.balanceOf(user), 0); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); @@ -292,8 +286,6 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function test_ccipE2E_AVAX_ARB() public { GovV3Helpers.executePayload(vm, address(proposal)); - uint64 avaxChainSelector = proposal.CCIP_AVAX_CHAIN_SELECTOR(); - // Chainlink config Router router = Router(TOKEN_POOL.getRouter()); @@ -302,12 +294,12 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); // AVAX -> ARB onRampUpdates[0] = Router.OnRamp({ - destChainSelector: avaxChainSelector, + destChainSelector: CCIP_AVAX_CHAIN_SELECTOR, onRamp: CCIP_ARB_AVAX_ON_RAMP }); // ARB -> AVAX offRampUpdates[0] = Router.OffRamp({ - sourceChainSelector: avaxChainSelector, + sourceChainSelector: CCIP_AVAX_CHAIN_SELECTOR, offRamp: CCIP_ARB_AVAX_OFF_RAMP }); address routerOwner = router.owner(); @@ -349,7 +341,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { vm.startPrank(user); // Use address(0) to use native token as fee token - _sendCcip(router, address(GHO), amount, address(0), avaxChainSelector, user); + _sendCcip(router, address(GHO), amount, address(0), CCIP_AVAX_CHAIN_SELECTOR, user); assertEq(GHO.balanceOf(user), 0); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); @@ -404,14 +396,14 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(supportedChains.length, 2); // ETH - assertEq(supportedChains[0], proposal.CCIP_ETH_CHAIN_SELECTOR()); + assertEq(supportedChains[0], CCIP_ETH_CHAIN_SELECTOR); // AVAX - assertEq(supportedChains[1], proposal.CCIP_AVAX_CHAIN_SELECTOR()); + assertEq(supportedChains[1], CCIP_AVAX_CHAIN_SELECTOR); RateLimiter.TokenBucket memory outboundRateLimit = TOKEN_POOL - .getCurrentOutboundRateLimiterState(proposal.CCIP_AVAX_CHAIN_SELECTOR()); + .getCurrentOutboundRateLimiterState(CCIP_AVAX_CHAIN_SELECTOR); RateLimiter.TokenBucket memory inboundRateLimit = TOKEN_POOL.getCurrentInboundRateLimiterState( - proposal.CCIP_AVAX_CHAIN_SELECTOR() + CCIP_AVAX_CHAIN_SELECTOR ); assertEq(outboundRateLimit.isEnabled, false); assertEq(inboundRateLimit.isEnabled, false); From b025a25282f25f859e13b32a0cde548c21c40861 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 21:46:01 +0900 Subject: [PATCH 52/58] chore: Cleanup avax proposal comments, correct price feed --- .../AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 10 +++------- ...AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 17 ++--------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index 8921778cc..c4c17a890 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -11,7 +11,7 @@ import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; import {AaveV3PayloadAvalanche} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadAvalanche.sol'; import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; -import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; @@ -39,14 +39,12 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; - // TODO: Enusre this pre-computed address is correct (even if we launch additional AIPs) address public constant GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; - // TODO: Wait until new token pool is deployed on Avalanche, then use corresponding address address public constant CCIP_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ETH_GHO = MiscEthereum.GHO_TOKEN; address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; - address public constant ARB_GHO = 0x7dfF72693f6A4149b17e7C6314655f6A9F7c8B33; // AaveV3Arbitrum.GHO_UNDERLYING; + address public constant ARB_GHO = AaveV3ArbitrumAssets.GHO_UNDERLYING; uint256 public constant CCIP_BUCKET_CAPACITY = 25_000_000e18; // 25M uint64 public constant CCIP_ETH_CHAIN_SELECTOR = 5009297550715157269; uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; @@ -62,11 +60,9 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { UpgradeableBurnMintTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); // 3. Configure CCIP TokenPool for Ethereum - // TODO: Update pool address if we deploy new one _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ETH_CHAIN_SELECTOR, ETH_TOKEN_POOL, ETH_GHO); // 4. Configure CCIP TokenPool for Arbitrum - // TODO: Update pool address if we deploy new one _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ARB_CHAIN_SELECTOR, ARB_TOKEN_POOL, ARB_GHO); // 5. Add CCIP TokenPool as GHO Facilitator @@ -153,7 +149,7 @@ contract GhoAvaxListing is AaveV3PayloadAvalanche { listings[0] = IAaveV3ConfigEngine.Listing({ asset: ghoToken, assetSymbol: 'GHO', - priceFeed: 0xB05984aD83C20b3ADE7bf97a9a0Cb539DDE28DBb, // TODO: Correct price feed + priceFeed: 0x076DE3812BDbdAe1330064fc01Adf7f4EAa123f3, enabledToBorrow: EngineFlags.ENABLED, borrowableInIsolation: EngineFlags.DISABLED, withSiloedBorrowing: EngineFlags.DISABLED, diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 9914ffebd..d0f6f1f09 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -15,7 +15,7 @@ import {Client} from 'ccip/libraries/Client.sol'; import {EVM2EVMOnRamp} from 'ccip/onRamp/EVM2EVMOnRamp.sol'; import {EVM2EVMOffRamp} from 'ccip/offRamp/EVM2EVMOffRamp.sol'; import {Router} from 'ccip/Router.sol'; -import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; @@ -39,7 +39,6 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; address public constant REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; - // TODO: Remove these constants once we have deployed pool address address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; @@ -55,10 +54,9 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function setUp() public { vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); - // TODO: Decide if we want to deploy this beforehand or in AIP + // TODO: Move this back to AIP _deployGhoToken(); - // TODO: Remove this deployment once we have deployed pool address address tokenPool = _deployCcipTokenPool(GHO_TOKEN); TOKEN_POOL = UpgradeableBurnMintTokenPool(tokenPool); @@ -496,17 +494,6 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { }); } - function _getTokensAndPools( - address[] memory tokens, - IPoolV1[] memory pools - ) internal pure returns (Internal.PoolUpdate[] memory) { - Internal.PoolUpdate[] memory tokensAndPools = new Internal.PoolUpdate[](tokens.length); - for (uint256 i = 0; i < tokens.length; ++i) { - tokensAndPools[i] = Internal.PoolUpdate({token: tokens[i], pool: address(pools[i])}); - } - return tokensAndPools; - } - function _getSingleTokenPriceUpdateStruct( address token, uint224 price From 9ff0b8eea70215c9cb8c8fcd537853a2637444a1 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 22:00:11 +0900 Subject: [PATCH 53/58] chore: Cleanup eth proposal --- .../AaveV3Ethereum_GHOAvaxLaunch_20241106.sol | 35 +--------------- ...aveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 41 ++++++------------- 2 files changed, 14 insertions(+), 62 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol index 82d816ca3..f05af4b88 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol @@ -3,10 +3,7 @@ pragma solidity ^0.8.0; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; -import {UpgradeableLockReleaseTokenPool} from 'ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol'; -import {UpgradeableTokenPool} from 'ccip/pools/GHO/UpgradeableTokenPool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; -import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; import {IUpgradeableTokenPool} from 'src/interfaces/ccip/IUpgradeableTokenPool.sol'; /** @@ -14,44 +11,14 @@ import {IUpgradeableTokenPool} from 'src/interfaces/ccip/IUpgradeableTokenPool.s * @author Aave Labs * - Snapshot: https://snapshot.org/#/aave.eth/proposal/0x2aed7eb8b03cb3f961cbf790bf2e2e1e449f841a4ad8bdbcdd223bb6ac69e719 * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-avalanche-set-aci-as-emissions-manager-for-rewards/19339 - * @dev This payload consists of the following set of actions: - * 1. Accept ownership of CCIP TokenPool - * 2. Configure CCIP TokenPool for Arbitrum - * 3. Configure CCIP TokenPool for Avalanche - * 4. Accept administrator role from Chainlink token manager - * 5. Link token to pool on Chainlink token admin registry + * @dev This payload configures the CCIP TokenPool for Avalanche */ contract AaveV3Ethereum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { - address public constant CCIP_RMN_PROXY = 0x411dE17f12D1A34ecC7F45f49844626267c75e81; - address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; - address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xb22764f98dD05c789929716D677382Df22C05Cb6; address public constant CCIP_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; - uint256 public constant CCIP_BRIDGE_LIMIT = 25_000_000e18; // 25M - uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; uint64 public constant CCIP_AVAX_CHAIN_SELECTOR = 6433500567565415381; function execute() external { - // TODO: Following code applies to case we deploy new pools - /* - // 1. Accept TokenPool ownership - UpgradeableLockReleaseTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); - - // 2. Configure CCIP for Arbitrum - // TODO: Set remote pool and token addresses after deployment? - _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_ARB_CHAIN_SELECTOR, address(0), address(0)); - */ - - // 3. Configure CCIP for Avalanche _configureCcipTokenPool(CCIP_TOKEN_POOL, CCIP_AVAX_CHAIN_SELECTOR); - - // TODO: Following code applies to case we deploy new pools - /* - // 4. Accept Administrator role from Chainlink token manager - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).acceptAdminRole(MiscEthereum.GHO_TOKEN); - - // 5. Link token to pool on Chainlink token admin registry - TokenAdminRegistry(CCIP_TOKEN_ADMIN_REGISTRY).setPool(MiscEthereum.GHO_TOKEN, CCIP_TOKEN_POOL); - */ } function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index 82e750a73..7ed239086 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -1,30 +1,22 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; - import 'forge-std/Test.sol'; import {TransparentUpgradeableProxy} from 'solidity-utils/contracts/transparent-proxy/TransparentUpgradeableProxy.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; import {UpgradeableBurnMintTokenPool} from 'ccip/pools/GHO/UpgradeableBurnMintTokenPool.sol'; import {UpgradeableLockReleaseTokenPool} from 'ccip/pools/GHO/UpgradeableLockReleaseTokenPool.sol'; import {IPoolPriorTo1_5} from 'ccip/interfaces/IPoolPriorTo1_5.sol'; -import {IPriceRegistry} from 'ccip/interfaces/IPriceRegistry.sol'; import {Internal} from 'ccip/libraries/Internal.sol'; -import {Pool} from 'ccip/libraries/Pool.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {Client} from 'ccip/libraries/Client.sol'; import {TokenAdminRegistry} from 'ccip/tokenAdminRegistry/TokenAdminRegistry.sol'; -import {EVM2EVMOnRamp} from 'ccip/onRamp/EVM2EVMOnRamp.sol'; -import {EVM2EVMOffRamp} from 'ccip/offRamp/EVM2EVMOffRamp.sol'; import {Router} from 'ccip/Router.sol'; -import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/src/ProtocolV3TestBase.sol'; import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol'; -import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {GovernanceV3Arbitrum} from 'aave-address-book/GovernanceV3Arbitrum.sol'; -import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; -import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; @@ -68,10 +60,9 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Execute Avax proposal to deploy Avax token pool vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); - // TODO: Decide if we want to deploy this beforehand or in AIP + // TODO: Move this back to AIP _deployGhoToken(); - // TODO: Remove this deployment once we have deployed pool address _deployCcipTokenPool(); // TODO: Remove this (will be done on chainlink's side) @@ -133,7 +124,6 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Lock uint256 amount = 100e18; // 100 GHO deal(address(GHO), user, amount); - uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); uint256 startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); @@ -149,7 +139,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { user, bytes(''), amount, - arbChainSelector, + CCIP_ARB_CHAIN_SELECTOR, bytes('') ); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance + amount); @@ -166,7 +156,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { bytes(''), user, amount, - arbChainSelector, + CCIP_ARB_CHAIN_SELECTOR, bytes('') ); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); @@ -176,7 +166,6 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Lock deal(address(GHO), user, amount); - uint64 avaxChainSelector = proposal.CCIP_AVAX_CHAIN_SELECTOR(); startingGhoBalance = GHO.balanceOf(address(TOKEN_POOL)); @@ -192,7 +181,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { user, bytes(''), amount, - avaxChainSelector, + CCIP_AVAX_CHAIN_SELECTOR, bytes('') ); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance + amount); @@ -209,7 +198,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { bytes(''), user, amount, - avaxChainSelector, + CCIP_AVAX_CHAIN_SELECTOR, bytes('') ); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance); @@ -220,8 +209,6 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function test_ccipE2E_ARB_ETH() public { GovV3Helpers.executePayload(vm, address(proposal)); - uint64 arbChainSelector = proposal.CCIP_ARB_CHAIN_SELECTOR(); - Router router = Router(TOKEN_POOL.getRouter()); // User executes ccipSend @@ -236,7 +223,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { vm.startPrank(user); // Use address(0) to use native token as fee token - _sendCcip(router, address(GHO), amount, address(0), arbChainSelector, user); + _sendCcip(router, address(GHO), amount, address(0), CCIP_ARB_CHAIN_SELECTOR, user); assertEq(GHO.balanceOf(user), 0); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance + amount); @@ -248,8 +235,6 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function test_ccipE2E_AVAX_ETH() public { GovV3Helpers.executePayload(vm, address(proposal)); - uint64 avaxChainSelector = proposal.CCIP_AVAX_CHAIN_SELECTOR(); - // Chainlink config Router router = Router(TOKEN_POOL.getRouter()); @@ -265,7 +250,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { vm.startPrank(user); // Use address(0) to use native token as fee token - _sendCcip(router, address(GHO), amount, address(0), avaxChainSelector, user); + _sendCcip(router, address(GHO), amount, address(0), CCIP_AVAX_CHAIN_SELECTOR, user); assertEq(GHO.balanceOf(user), 0); assertEq(GHO.balanceOf(address(TOKEN_POOL)), startingGhoBalance + amount); @@ -321,14 +306,14 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { assertEq(supportedChains.length, 2); // ARB - assertEq(supportedChains[0], proposal.CCIP_ARB_CHAIN_SELECTOR()); + assertEq(supportedChains[0], CCIP_ARB_CHAIN_SELECTOR); // AVAX - assertEq(supportedChains[1], proposal.CCIP_AVAX_CHAIN_SELECTOR()); + assertEq(supportedChains[1], CCIP_AVAX_CHAIN_SELECTOR); RateLimiter.TokenBucket memory outboundRateLimit = TOKEN_POOL - .getCurrentOutboundRateLimiterState(proposal.CCIP_AVAX_CHAIN_SELECTOR()); + .getCurrentOutboundRateLimiterState(CCIP_AVAX_CHAIN_SELECTOR); RateLimiter.TokenBucket memory inboundRateLimit = TOKEN_POOL.getCurrentInboundRateLimiterState( - proposal.CCIP_AVAX_CHAIN_SELECTOR() + CCIP_AVAX_CHAIN_SELECTOR ); assertEq(outboundRateLimit.isEnabled, false); assertEq(inboundRateLimit.isEnabled, false); From 7f3d66d0f54a15a7b51e5734c8a5861eb39a68c2 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Thu, 19 Dec 2024 23:55:19 +0900 Subject: [PATCH 54/58] fix: Update ccip submodule --- lib/ccip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ccip b/lib/ccip index 8fea66bb8..1881f2070 160000 --- a/lib/ccip +++ b/lib/ccip @@ -1 +1 @@ -Subproject commit 8fea66bb81dbcb6d4c2332c1d45b68765766f3e2 +Subproject commit 1881f2070c7b34e6b2195e5b9fe26e771a0233b4 From 1dfcac00059676340d9ea271ccb33bcad4cba1f8 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Fri, 20 Dec 2024 00:05:40 +0900 Subject: [PATCH 55/58] fix: Move gho deployment back into proposal --- .../AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 9 +++------ .../AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 6 +----- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index c4c17a890..c7c88c58c 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -39,8 +39,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; - address public constant GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; - address public constant CCIP_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; + address public constant GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant CCIP_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ETH_GHO = MiscEthereum.GHO_TOKEN; address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; @@ -50,11 +50,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { uint64 public constant CCIP_ARB_CHAIN_SELECTOR = 4949039107694359620; function execute() external { - // For now, deploying GHO token separately - /* // 1. Deploy GHO _deployGhoToken(); - */ // 2. Accept TokenPool ownership UpgradeableBurnMintTokenPool(CCIP_TOKEN_POOL).acceptOwnership(); @@ -137,7 +134,7 @@ contract GhoAvaxListing is AaveV3PayloadAvalanche { using SafeERC20 for IERC20; uint256 public constant GHO_SEED_AMOUNT = 1_000_000e18; - address public ghoToken; + address public immutable ghoToken; constructor(address gho) { ghoToken = gho; diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index d0f6f1f09..5e798f80a 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -43,7 +43,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; - address public constant GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; + address public constant GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); UpgradeableBurnMintTokenPool public TOKEN_POOL; @@ -53,10 +53,6 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function setUp() public { vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); - - // TODO: Move this back to AIP - _deployGhoToken(); - address tokenPool = _deployCcipTokenPool(GHO_TOKEN); TOKEN_POOL = UpgradeableBurnMintTokenPool(tokenPool); From b57b3d4826638cdc5ba6f42c4a12c6316cc1d3ff Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Fri, 20 Dec 2024 00:13:36 +0900 Subject: [PATCH 56/58] fix: Remove gho deployment from tests --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 8 ++------ .../AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 2 ++ .../AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 8 +++----- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index cfd97bc74..4813bd8dd 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -41,8 +41,8 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; address public constant REGISTRY_ADMIN = 0x8a89770722c84B60cE02989Aedb22Ac4791F8C7f; - address public constant AVAX_GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; - address public constant AVAX_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; + address public constant AVAX_GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant AVAX_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; address public constant AVAX_REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; address public constant AVAX_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; address public constant AVAX_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; @@ -64,10 +64,6 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Execute Avax proposal to deploy Avax token pool vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); - // TODO: Decide if we want to deploy this beforehand or in AIP - _deployGhoToken(); - - // TODO: Remove this deployment once we have deployed pool address _deployCcipTokenPool(); // TODO: Remove this (will be done on chainlink's side) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 5e798f80a..8f1838bff 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -53,6 +53,8 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { function setUp() public { vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); + + // Assume token pool deployed on Avalanche address tokenPool = _deployCcipTokenPool(GHO_TOKEN); TOKEN_POOL = UpgradeableBurnMintTokenPool(tokenPool); diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index 7ed239086..55ab9ba21 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -36,8 +36,8 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant GHO_TOKEN = AaveV3EthereumAssets.GHO_UNDERLYING; UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); - address public constant AVAX_GHO_TOKEN = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; - address public constant AVAX_TOKEN_POOL = 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9; + address public constant AVAX_GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant AVAX_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; address public constant AVAX_REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; address public constant AVAX_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; address public constant AVAX_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; @@ -60,9 +60,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // Execute Avax proposal to deploy Avax token pool vm.createSelectFork(vm.rpcUrl('avalanche'), 53559217); - // TODO: Move this back to AIP - _deployGhoToken(); - + // Assume token pool deployed on Avalanche _deployCcipTokenPool(); // TODO: Remove this (will be done on chainlink's side) From f3b9712a4846bc80b05bc1518255093d7951c3c2 Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Fri, 20 Dec 2024 00:56:00 +0900 Subject: [PATCH 57/58] fix: Token pool names --- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol | 10 +++++----- .../AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 10 +++++----- .../AaveV3Ethereum_GHOAvaxLaunch_20241106.sol | 10 +++++----- .../AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 10 +++++----- src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol | 3 --- ...ableTokenPool.sol => IUpgradeableTokenPool_1_5.sol} | 5 +++-- 6 files changed, 23 insertions(+), 25 deletions(-) rename src/interfaces/ccip/{IUpgradeableTokenPool.sol => IUpgradeableTokenPool_1_5.sol} (79%) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol index fb9a0a7d8..d6662f02a 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; import {MiscArbitrum} from 'aave-address-book/MiscArbitrum.sol'; -import {IUpgradeableTokenPool} from 'src/interfaces/ccip/IUpgradeableTokenPool.sol'; +import {IUpgradeableTokenPool_1_4} from 'src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol'; /** * @title GHOAvaxLaunch @@ -22,19 +22,19 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { } function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { - IUpgradeableTokenPool.ChainUpdate[] - memory chainUpdates = new IUpgradeableTokenPool.ChainUpdate[](1); + IUpgradeableTokenPool_1_4.ChainUpdate[] + memory chainUpdates = new IUpgradeableTokenPool_1_4.ChainUpdate[](1); RateLimiter.Config memory rateConfig = RateLimiter.Config({ isEnabled: false, capacity: 0, rate: 0 }); - chainUpdates[0] = IUpgradeableTokenPool.ChainUpdate({ + chainUpdates[0] = IUpgradeableTokenPool_1_4.ChainUpdate({ remoteChainSelector: chainSelector, allowed: true, outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - IUpgradeableTokenPool(tokenPool).applyChainUpdates(chainUpdates); + IUpgradeableTokenPool_1_4(tokenPool).applyChainUpdates(chainUpdates); } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 4813bd8dd..4e244d27d 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -23,7 +23,7 @@ import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; -import {IUpgradeableTokenPool_1_4} from 'src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol'; +import {IUpgradeableTokenPool_1_5} from 'src/interfaces/ccip/IUpgradeableTokenPool_1_5.sol'; import {AaveV3Arbitrum_GHOAvaxLaunch_20241106} from './AaveV3Arbitrum_GHOAvaxLaunch_20241106.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; @@ -410,14 +410,14 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // --- function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { - IUpgradeableTokenPool_1_4.ChainUpdate[] - memory chainUpdates = new IUpgradeableTokenPool_1_4.ChainUpdate[](1); + IUpgradeableTokenPool_1_5.ChainUpdate[] + memory chainUpdates = new IUpgradeableTokenPool_1_5.ChainUpdate[](1); RateLimiter.Config memory rateConfig = RateLimiter.Config({ isEnabled: false, capacity: 0, rate: 0 }); - chainUpdates[0] = IUpgradeableTokenPool_1_4.ChainUpdate({ + chainUpdates[0] = IUpgradeableTokenPool_1_5.ChainUpdate({ remoteChainSelector: chainSelector, allowed: true, remotePoolAddress: abi.encode(AVAX_TOKEN_POOL), @@ -425,7 +425,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - IUpgradeableTokenPool_1_4(tokenPool).applyChainUpdates(chainUpdates); + IUpgradeableTokenPool_1_5(tokenPool).applyChainUpdates(chainUpdates); } function _getFacilitatorLevel(address f) internal view returns (uint256) { diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol index f05af4b88..b088a01ac 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; -import {IUpgradeableTokenPool} from 'src/interfaces/ccip/IUpgradeableTokenPool.sol'; +import {IUpgradeableTokenPool_1_4} from 'src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol'; /** * @title GHO Avax Launch @@ -22,19 +22,19 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { } function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { - IUpgradeableTokenPool.ChainUpdate[] - memory chainUpdates = new IUpgradeableTokenPool.ChainUpdate[](1); + IUpgradeableTokenPool_1_4.ChainUpdate[] + memory chainUpdates = new IUpgradeableTokenPool_1_4.ChainUpdate[](1); RateLimiter.Config memory rateConfig = RateLimiter.Config({ isEnabled: false, capacity: 0, rate: 0 }); - chainUpdates[0] = IUpgradeableTokenPool.ChainUpdate({ + chainUpdates[0] = IUpgradeableTokenPool_1_4.ChainUpdate({ remoteChainSelector: chainSelector, allowed: true, outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - IUpgradeableTokenPool(tokenPool).applyChainUpdates(chainUpdates); + IUpgradeableTokenPool_1_4(tokenPool).applyChainUpdates(chainUpdates); } } diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index 55ab9ba21..2389008a6 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -20,7 +20,7 @@ import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethe import {GovernanceV3Avalanche} from 'aave-address-book/GovernanceV3Avalanche.sol'; import {MiscAvalanche} from 'aave-address-book/MiscAvalanche.sol'; import {UpgradeableGhoToken} from 'gho-core/gho/UpgradeableGhoToken.sol'; -import {IUpgradeableTokenPool_1_4} from 'src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol'; +import {IUpgradeableTokenPool_1_5} from 'src/interfaces/ccip/IUpgradeableTokenPool_1_5.sol'; import {AaveV3Avalanche_GHOAvaxLaunch_20241106} from './AaveV3Avalanche_GHOAvaxLaunch_20241106.sol'; import {AaveV3Ethereum_GHOAvaxLaunch_20241106} from './AaveV3Ethereum_GHOAvaxLaunch_20241106.sol'; @@ -322,14 +322,14 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { // --- function _configureCcipTokenPool(address tokenPool, uint64 chainSelector) internal { - IUpgradeableTokenPool_1_4.ChainUpdate[] - memory chainUpdates = new IUpgradeableTokenPool_1_4.ChainUpdate[](1); + IUpgradeableTokenPool_1_5.ChainUpdate[] + memory chainUpdates = new IUpgradeableTokenPool_1_5.ChainUpdate[](1); RateLimiter.Config memory rateConfig = RateLimiter.Config({ isEnabled: false, capacity: 0, rate: 0 }); - chainUpdates[0] = IUpgradeableTokenPool_1_4.ChainUpdate({ + chainUpdates[0] = IUpgradeableTokenPool_1_5.ChainUpdate({ remoteChainSelector: chainSelector, allowed: true, remotePoolAddress: abi.encode(AVAX_TOKEN_POOL), @@ -337,7 +337,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { outboundRateLimiterConfig: rateConfig, inboundRateLimiterConfig: rateConfig }); - IUpgradeableTokenPool_1_4(tokenPool).applyChainUpdates(chainUpdates); + IUpgradeableTokenPool_1_5(tokenPool).applyChainUpdates(chainUpdates); } function _sendCcip( diff --git a/src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol b/src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol index 61c21b60f..3d83c1d9f 100644 --- a/src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol +++ b/src/interfaces/ccip/IUpgradeableTokenPool_1_4.sol @@ -3,13 +3,10 @@ pragma solidity ^0.8.0; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; -/// @dev Minimal interface for exiting ETH and ARB pools interface IUpgradeableTokenPool_1_4 { struct ChainUpdate { uint64 remoteChainSelector; bool allowed; - bytes remotePoolAddress; - bytes remoteTokenAddress; RateLimiter.Config outboundRateLimiterConfig; RateLimiter.Config inboundRateLimiterConfig; } diff --git a/src/interfaces/ccip/IUpgradeableTokenPool.sol b/src/interfaces/ccip/IUpgradeableTokenPool_1_5.sol similarity index 79% rename from src/interfaces/ccip/IUpgradeableTokenPool.sol rename to src/interfaces/ccip/IUpgradeableTokenPool_1_5.sol index 150264220..7ef9cbd0c 100644 --- a/src/interfaces/ccip/IUpgradeableTokenPool.sol +++ b/src/interfaces/ccip/IUpgradeableTokenPool_1_5.sol @@ -3,11 +3,12 @@ pragma solidity ^0.8.0; import {RateLimiter} from 'ccip/libraries/RateLimiter.sol'; -/// @dev Minimal interface for exiting ETH and ARB pools -interface IUpgradeableTokenPool { +interface IUpgradeableTokenPool_1_5 { struct ChainUpdate { uint64 remoteChainSelector; bool allowed; + bytes remotePoolAddress; + bytes remoteTokenAddress; RateLimiter.Config outboundRateLimiterConfig; RateLimiter.Config inboundRateLimiterConfig; } From 9968529c6db64c7830889b711d6a7456b537227c Mon Sep 17 00:00:00 2001 From: Cheyenne Atapour Date: Fri, 20 Dec 2024 17:27:40 +0900 Subject: [PATCH 58/58] feat: Deploy gho deterministically --- ...aveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol | 2 +- ...AaveV3Avalanche_GHOAvaxLaunch_20241106.sol | 30 ++++++++++++++----- ...veV3Avalanche_GHOAvaxLaunch_20241106.t.sol | 2 +- ...aveV3Ethereum_GHOAvaxLaunch_20241106.t.sol | 2 +- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol index 4e244d27d..e92237812 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Arbitrum_GHOAvaxLaunch_20241106.t.sol @@ -41,7 +41,7 @@ contract AaveV3Arbitrum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant TOKEN_ADMIN_REGISTRY = 0x39AE1032cF4B334a1Ed41cdD0833bdD7c7E7751E; address public constant REGISTRY_ADMIN = 0x8a89770722c84B60cE02989Aedb22Ac4791F8C7f; - address public constant AVAX_GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant AVAX_GHO_TOKEN = 0xc0F850AfdeFF8E0292C638C3e237fB2168E703d0; address public constant AVAX_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; address public constant AVAX_REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; address public constant AVAX_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol index c7c88c58c..9d05da15f 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.sol @@ -39,7 +39,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { address public constant CCIP_RMN_PROXY = 0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc; address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant CCIP_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F; - address public constant GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant GHO_TOKEN = 0xc0F850AfdeFF8E0292C638C3e237fB2168E703d0; address public constant CCIP_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ETH_GHO = MiscEthereum.GHO_TOKEN; @@ -85,16 +85,32 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106 is IProposalGenericExecutor { } function _deployGhoToken() internal returns (address) { - address imple = address(new UpgradeableGhoToken()); - + // Deterministically deploy the gho token using create2 + bytes memory bytecode = type(UpgradeableGhoToken).creationCode; + bytes32 salt = keccak256(abi.encodePacked(GovernanceV3Avalanche.EXECUTOR_LVL_1, 'AVAX-GHO')); + address imple; + assembly { + imple := create2(0, add(bytecode, 0x20), mload(bytecode), salt) + } + + // Deterministically deploy the proxy bytes memory ghoTokenInitParams = abi.encodeWithSignature( 'initialize(address)', GovernanceV3Avalanche.EXECUTOR_LVL_1 // owner ); - return - address( - new TransparentUpgradeableProxy(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) - ); + bytes memory proxyBytecode = abi.encodePacked( + type(TransparentUpgradeableProxy).creationCode, + abi.encode(imple, MiscAvalanche.PROXY_ADMIN, ghoTokenInitParams) + ); + bytes32 proxySalt = keccak256( + abi.encodePacked(GovernanceV3Avalanche.EXECUTOR_LVL_1, 'AVAX-GHO-PROXY') + ); + address proxy; + assembly { + proxy := create2(0, add(proxyBytecode, 0x20), mload(proxyBytecode), proxySalt) + } + + return proxy; } function _configureCcipTokenPool( diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol index 8f1838bff..e97f25ca3 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Avalanche_GHOAvaxLaunch_20241106.t.sol @@ -43,7 +43,7 @@ contract AaveV3Avalanche_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant CCIP_ROUTER = 0xF4c7E640EdA248ef95972845a62bdC74237805dB; address public constant ETH_TOKEN_POOL = MiscEthereum.GHO_CCIP_TOKEN_POOL; address public constant ARB_TOKEN_POOL = MiscArbitrum.GHO_CCIP_TOKEN_POOL; - address public constant GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant GHO_TOKEN = 0xc0F850AfdeFF8E0292C638C3e237fB2168E703d0; UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); UpgradeableBurnMintTokenPool public TOKEN_POOL; diff --git a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol index 2389008a6..a5b8c1e25 100644 --- a/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol +++ b/src/20241106_Multi_GHOAvaxLaunch/AaveV3Ethereum_GHOAvaxLaunch_20241106.t.sol @@ -36,7 +36,7 @@ contract AaveV3Ethereum_GHOAvaxLaunch_20241106_Test is ProtocolV3TestBase { address public constant GHO_TOKEN = AaveV3EthereumAssets.GHO_UNDERLYING; UpgradeableGhoToken public GHO = UpgradeableGhoToken(GHO_TOKEN); - address public constant AVAX_GHO_TOKEN = 0xb025950B02b9cfe851C6a4C041f9D6c0942f0eB1; + address public constant AVAX_GHO_TOKEN = 0xc0F850AfdeFF8E0292C638C3e237fB2168E703d0; address public constant AVAX_TOKEN_POOL = 0x2e234DAe75C793f67A35089C9d99245E1C58470b; address public constant AVAX_REGISTRY_ADMIN = 0xA3f32a07CCd8569f49cf350D4e61C016CA484644; address public constant AVAX_TOKEN_ADMIN_REGISTRY = 0xc8df5D618c6a59Cc6A311E96a39450381001464F;