From 3fe31d63c2ce2d142cca56a0675b5b94ec37fcf0 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 23 Apr 2024 13:22:22 +0530 Subject: [PATCH 1/9] feat: robots migration --- ...sToChainlinkAutomationV2_20240422_after.md | 5 + ...sToChainlinkAutomationV2_20240422_after.md | 5 + ...sToChainlinkAutomationV2_20240422_after.md | 40 +++ ...sToChainlinkAutomationV2_20240422_after.md | 5 + ...sToChainlinkAutomationV2_20240422_after.md | 5 + ...sToChainlinkAutomationV2_20240422_after.md | 5 + ...sToChainlinkAutomationV2_20240422_after.md | 5 + ...RobotsToChainlinkAutomationV2_20240422.sol | 25 ++ ...botsToChainlinkAutomationV2_20240422.t.sol | 49 ++++ ...RobotsToChainlinkAutomationV2_20240422.sol | 25 ++ ...botsToChainlinkAutomationV2_20240422.t.sol | 49 ++++ ...RobotsToChainlinkAutomationV2_20240422.sol | 57 ++++ ...botsToChainlinkAutomationV2_20240422.t.sol | 52 ++++ ...RobotsToChainlinkAutomationV2_20240422.sol | 60 +++++ ...botsToChainlinkAutomationV2_20240422.t.sol | 67 +++++ ...RobotsToChainlinkAutomationV2_20240422.sol | 126 +++++++++ ...botsToChainlinkAutomationV2_20240422.t.sol | 118 ++++++++ ...RobotsToChainlinkAutomationV2_20240422.sol | 54 ++++ ...botsToChainlinkAutomationV2_20240422.t.sol | 54 ++++ ...RobotsToChainlinkAutomationV2_20240422.sol | 61 +++++ ...botsToChainlinkAutomationV2_20240422.t.sol | 67 +++++ .../MigrateRobotsToChainlinkAutomationV2.md | 50 ++++ ...botsToChainlinkAutomationV2_20240422.s.sol | 194 ++++++++++++++ .../config.ts | 29 ++ .../interfaces/IAaveCLRobotOperator.sol | 251 ++++++++++++++++++ .../interfaces/IRootsConsumer.sol | 137 ++++++++++ 26 files changed, 1595 insertions(+) create mode 100644 diffs/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_after.md create mode 100644 diffs/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_after.md create mode 100644 diffs/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md create mode 100644 diffs/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_after.md create mode 100644 diffs/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md create mode 100644 diffs/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_after.md create mode 100644 diffs/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_after.md create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/config.ts create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IRootsConsumer.sol diff --git a/diffs/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_after.md b/diffs/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_after.md new file mode 100644 index 000000000..c15d3e2bc --- /dev/null +++ b/diffs/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_after.md @@ -0,0 +1,5 @@ +## Raw diff + +```json +{} +``` \ No newline at end of file diff --git a/diffs/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_after.md b/diffs/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_after.md new file mode 100644 index 000000000..c15d3e2bc --- /dev/null +++ b/diffs/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_after.md @@ -0,0 +1,5 @@ +## Raw diff + +```json +{} +``` \ No newline at end of file diff --git a/diffs/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md b/diffs/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md new file mode 100644 index 000000000..c225b99a9 --- /dev/null +++ b/diffs/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md @@ -0,0 +1,40 @@ +## Reserve changes + +### Reserves altered + +#### LINK ([0xf97f4df75117a78c1A5a0DBb814Af92458539FB4](https://arbiscan.io/address/0xf97f4df75117a78c1A5a0DBb814Af92458539FB4)) + +| description | value before | value after | +| --- | --- | --- | +| liquidityIndex | 1.004 | 1.004 | +| variableBorrowIndex | 1.03 | 1.03 | +| currentLiquidityRate | 0.002 % | 0.002 % | +| currentVariableBorrowRate | 0.205 % | 0.205 % | + + +## Raw diff + +```json +{ + "reserves": { + "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4": { + "currentLiquidityRate": { + "from": "21519899216131949746774", + "to": "21520920172477038470997" + }, + "currentVariableBorrowRate": { + "from": "2045586675646185482544796", + "to": "2045635198873576104131496" + }, + "liquidityIndex": { + "from": "1003748294487317650250818674", + "to": "1003748294984590865323782988" + }, + "variableBorrowIndex": { + "from": "1030010588256949865469612818", + "to": "1030010636762295022112692520" + } + } + } +} +``` \ No newline at end of file diff --git a/diffs/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_after.md b/diffs/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_after.md new file mode 100644 index 000000000..c15d3e2bc --- /dev/null +++ b/diffs/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_after.md @@ -0,0 +1,5 @@ +## Raw diff + +```json +{} +``` \ No newline at end of file diff --git a/diffs/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md b/diffs/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md new file mode 100644 index 000000000..c15d3e2bc --- /dev/null +++ b/diffs/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md @@ -0,0 +1,5 @@ +## Raw diff + +```json +{} +``` \ No newline at end of file diff --git a/diffs/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_after.md b/diffs/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_after.md new file mode 100644 index 000000000..c15d3e2bc --- /dev/null +++ b/diffs/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_after.md @@ -0,0 +1,5 @@ +## Raw diff + +```json +{} +``` \ No newline at end of file diff --git a/diffs/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_after.md b/diffs/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_after.md new file mode 100644 index 000000000..c15d3e2bc --- /dev/null +++ b/diffs/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_after.md @@ -0,0 +1,5 @@ +## Raw diff + +```json +{} +``` \ No newline at end of file diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol new file mode 100644 index 000000000..807eb94f4 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; +import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; + +/** + * @title Migrate Robots to Chainlink Automation v2 + * @author BGD Labs (@bgdlabs) + * @notice This payload should be executed before the payload for registering new robots. + * - Discussion: TODO + */ +contract AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { + address public constant OLD_ROBOT_OPERATOR = 0x7A9ff54A6eE4a21223036890bB8c4ea2D62c686b; + uint256 public constant OLD_EXECUTION_CHAIN_ROBOT_ID = + 42967470609923359998605990815360926273002411113492386351801017384824248835129; + uint256 public constant OLD_VOTING_CHAIN_ROBOT_ID = + 23105234861606727783784560473737793446534476931507704105643023042466416318991; + + function execute() external { + // cancel previous robots + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_EXECUTION_CHAIN_ROBOT_ID); + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_VOTING_CHAIN_ROBOT_ID); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol new file mode 100644 index 000000000..bcf94c6c2 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV2Avalanche} from 'aave-address-book/AaveV2Avalanche.sol'; +import {ProtocolV2TestBase} from 'aave-helpers/ProtocolV2TestBase.sol'; +import {AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; + +/** + * @dev Test for AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 + * command: make test-contract filter=AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 + */ +contract AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_Test is ProtocolV2TestBase { + AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 internal proposal; + event KeeperCancelled(uint256 indexed id, address indexed upkeep); + + address public constant OLD_EXECUTION_CHAIN_ROBOT_ADDRESS = + 0x7B74938583Eb03e06042fcB651046BaF0bf15644; + address public constant OLD_VOTING_CHAIN_ROBOT_ADDRESS = + 0x10E49034306EaA663646773C04b7B67E81eD0D52; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('avalanche'), 44528432); + proposal = new AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest( + 'AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422', + AaveV2Avalanche.POOL, + address(proposal) + ); + } + + function test_keepersCancelled() public { + vm.expectEmit(); + emit KeeperCancelled( + proposal.OLD_EXECUTION_CHAIN_ROBOT_ID(), + OLD_EXECUTION_CHAIN_ROBOT_ADDRESS + ); + + vm.expectEmit(); + emit KeeperCancelled(proposal.OLD_VOTING_CHAIN_ROBOT_ID(), OLD_VOTING_CHAIN_ROBOT_ADDRESS); + + executePayload(vm, address(proposal)); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol new file mode 100644 index 000000000..d89ded7ba --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; +import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; + +/** + * @title Migrate Robots to Chainlink Automation v2 + * @author BGD Labs (@bgdlabs) + * @notice This payload should be executed before the payload for registering new robots. + * - Discussion: TODO + */ +contract AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { + address public constant OLD_ROBOT_OPERATOR = 0x4e8984D11A47Ff89CD67c7651eCaB6C00a74B4A9; + uint256 public constant OLD_EXECUTION_CHAIN_ROBOT_ID = + 82990232394810788826748981965753730350133859818029683929136401112559915179430; + uint256 public constant OLD_VOTING_CHAIN_ROBOT_ID = + 5475326125853957331243818268970211605617607736278808003229011576358255850220; + + function execute() external { + // cancel previous robots + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_EXECUTION_CHAIN_ROBOT_ID); + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_VOTING_CHAIN_ROBOT_ID); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol new file mode 100644 index 000000000..83b2bc10a --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV2Polygon} from 'aave-address-book/AaveV2Polygon.sol'; +import {ProtocolV2TestBase} from 'aave-helpers/ProtocolV2TestBase.sol'; +import {AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; + +/** + * @dev Test for AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 + * command: make test-contract filter=AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 + */ +contract AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_Test is ProtocolV2TestBase { + AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 internal proposal; + event KeeperCancelled(uint256 indexed id, address indexed upkeep); + + address public constant OLD_EXECUTION_CHAIN_ROBOT_ADDRESS = + 0x249396a890F89D47F89326d7EE116b1d374Fb3A9; + address public constant OLD_VOTING_CHAIN_ROBOT_ADDRESS = + 0xbe7998712402B6A63975515A532Ce503437998b7; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('polygon'), 56113527); + proposal = new AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest( + 'AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422', + AaveV2Polygon.POOL, + address(proposal) + ); + } + + function test_keepersCancelled() public { + vm.expectEmit(); + emit KeeperCancelled( + proposal.OLD_EXECUTION_CHAIN_ROBOT_ID(), + OLD_EXECUTION_CHAIN_ROBOT_ADDRESS + ); + + vm.expectEmit(); + emit KeeperCancelled(proposal.OLD_VOTING_CHAIN_ROBOT_ID(), OLD_VOTING_CHAIN_ROBOT_ADDRESS); + + executePayload(vm, address(proposal)); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol new file mode 100644 index 000000000..755e2f9c9 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Arbitrum, AaveV3ArbitrumAssets} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; +import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; + +/** + * @title Migrate Robots to Chainlink Automation v2 + * @author BGD Labs (@bgdlabs) + * - Discussion: TODO + */ +contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { + using SafeERC20 for IERC20; + using SafeCast for uint256; + + address public constant OLD_ROBOT_OPERATOR = 0xb0A73671C97BAC9Ba899CD1a23604Fd2278cD02A; + uint256 public constant OLD_EXECUTION_CHAIN_ROBOT_ID = + 78329451080216164099529400539433108989111820950862041749656351555695961643082; + + address public constant ROBOT_OPERATOR = 0xAa589e4c7539e8D7465c36578098499F0b2BBd12; + address public constant EXECUTION_CHAIN_ROBOT_ADDRESS = + 0x64093fe5f8Cf62aFb4377cf7EF4373537fe9155B; + uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; + + function execute() external { + // cancel previous robot + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_EXECUTION_CHAIN_ROBOT_ID); + + AaveV3Arbitrum.COLLECTOR.transfer( + AaveV3ArbitrumAssets.LINK_A_TOKEN, + address(this), + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + ); + AaveV3Arbitrum.POOL.withdraw( + AaveV3ArbitrumAssets.LINK_UNDERLYING, + type(uint256).max, + address(this) + ); + + uint256 linkBalance = IERC20(AaveV3ArbitrumAssets.LINK_UNDERLYING).balanceOf(address(this)); + IERC20(AaveV3ArbitrumAssets.LINK_UNDERLYING).forceApprove(ROBOT_OPERATOR, linkBalance); + + // register new robot + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Execution Chain Robot', + EXECUTION_CHAIN_ROBOT_ADDRESS, + 5_000_000, + linkBalance.toUint96(), + 0, + '' + ); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol new file mode 100644 index 000000000..52acfe64a --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; + +/** + * @dev Test for AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 + * command: make test-contract filter=AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 + */ +contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_Test is ProtocolV3TestBase { + AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 internal proposal; + + event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); + event KeeperCancelled(uint256 indexed id, address indexed upkeep); + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('arbitrum'), 203931041); + proposal = new AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest( + 'AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422', + AaveV3Arbitrum.POOL, + address(proposal) + ); + } + + function test_oldKeeperCancelledAndNewRegistered() public { + // validate robots cancelled + vm.expectEmit(); + emit KeeperCancelled( + proposal.OLD_EXECUTION_CHAIN_ROBOT_ID(), + proposal.EXECUTION_CHAIN_ROBOT_ADDRESS() + ); + + // validate robots registered + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.EXECUTION_CHAIN_ROBOT_ADDRESS(), + uint96(proposal.EXECUTION_CHAIN_ROBOT_LINK_AMOUNT()) + ); + + executePayload(vm, address(proposal)); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol new file mode 100644 index 000000000..c39aca218 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Avalanche, AaveV3AvalancheAssets} from 'aave-address-book/AaveV3Avalanche.sol'; +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; +import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; +import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; + +/** + * @title Migrate Robots to Chainlink Automation v2 + * @author BGD Labs (@bgdlabs) + * @notice This payload should be executed after the payload for cancelling old robots has been executed and link tokens + * have been transferred to the collector by calling the `withdrawLink()` method on the old operator contract. + * - Discussion: TODO + */ +contract AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { + using SafeERC20 for IERC20; + using SafeCast for uint256; + + address public constant ROBOT_OPERATOR = 0x023640D7CDa2E2063546A45005393756B9b4ac9D; + address public constant EXECUTION_CHAIN_ROBOT_ADDRESS = + 0x7B74938583Eb03e06042fcB651046BaF0bf15644; + address public constant VOTING_CHAIN_ROBOT_ADDRESS = 0x10E49034306EaA663646773C04b7B67E81eD0D52; + + uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; + uint256 public constant VOTING_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; + + function execute() external { + AaveV3Avalanche.COLLECTOR.transfer( + AaveV3AvalancheAssets.LINKe_UNDERLYING, + address(this), + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + VOTING_CHAIN_ROBOT_LINK_AMOUNT + ); + + IERC20(AaveV3AvalancheAssets.LINKe_UNDERLYING).forceApprove( + ROBOT_OPERATOR, + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + VOTING_CHAIN_ROBOT_LINK_AMOUNT + ); + + // register new robots + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Execution Chain Robot', + EXECUTION_CHAIN_ROBOT_ADDRESS, + 5_000_000, + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Voting Chain Robot', + VOTING_CHAIN_ROBOT_ADDRESS, + 5_000_000, + VOTING_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol new file mode 100644 index 000000000..52f66f5d6 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol'; + +import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; + +/** + * @dev Test for AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 + * command: make test-contract filter=AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 + */ +contract AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_Test is ProtocolV3TestBase { + AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 internal cancelRobotsProposal; + AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 internal proposal; + + event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('avalanche'), 44512842); + proposal = new AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422(); + cancelRobotsProposal = new AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422(); + + // execute the payload to cancel the robot and withraw link to collector + executePayload(vm, address(cancelRobotsProposal)); + + // after robot cancel we need to wait for some blocks to withdraw so we fast-forward + vm.roll(block.number + 50); + IAaveCLRobotOperator(cancelRobotsProposal.OLD_ROBOT_OPERATOR()).withdrawLink( + cancelRobotsProposal.OLD_EXECUTION_CHAIN_ROBOT_ID() + ); + IAaveCLRobotOperator(cancelRobotsProposal.OLD_ROBOT_OPERATOR()).withdrawLink( + cancelRobotsProposal.OLD_VOTING_CHAIN_ROBOT_ID() + ); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecutionX() public { + defaultTest( + 'AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422', + AaveV3Avalanche.POOL, + address(proposal) + ); + } + + function test_robotsRegistered() public { + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.EXECUTION_CHAIN_ROBOT_ADDRESS(), + uint96(proposal.EXECUTION_CHAIN_ROBOT_LINK_AMOUNT()) + ); + + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.VOTING_CHAIN_ROBOT_ADDRESS(), + uint96(proposal.VOTING_CHAIN_ROBOT_LINK_AMOUNT()) + ); + + executePayload(vm, address(proposal)); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol new file mode 100644 index 000000000..140e69a9f --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; +import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; +import {IRootsConsumer} from './interfaces/IRootsConsumer.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; +import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; +import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; + +/** + * @title Migrate Robots to Chainlink Automation v2 + * @author BGD Labs (@bgdlabs) + * - Discussion: TODO + */ +contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { + using SafeERC20 for IERC20; + using SafeCast for uint256; + + address public constant OLD_ROBOT_OPERATOR = 0x020E452b463568f55BAc6Dc5aFC8F0B62Ea5f0f3; + uint256 public constant OLD_EXECUTION_CHAIN_ROBOT_ID = + 103962992988872542945147446194468190544109628047207929929141163121857186570465; + uint256 public constant OLD_GOVERNANCE_CHAIN_ROBOT_ID = + 2651260633509968244842245718659958660539758109819220392919944208741153930322; + uint256 public constant OLD_VOTING_CHAIN_ROBOT_ID = + 37197956100690146667709888676659477205673841758151251597253206670225866349198; + uint256 public constant OLD_GSM_SWAP_FREEZE_USDC_ROBOT_ID = + 27746244780147594627138196730124243558900438379060566825820479909082807342202; + uint256 public constant OLD_GSM_SWAP_FREEZE_USDT_ROBOT_ID = + 29419557335377754353590946220126755014551271053492007946914462953700619858182; + + address public constant ROBOT_OPERATOR = 0x737806fe47FDBDEcBcB82dF7b89AA3D74AdadF62; + address public constant ROOTS_CONSUMER = 0x2fA6F0A65886123AFD24A575aE4554d0FCe8B577; + + address public constant GSM_SWAP_FREEZE_USDC_ROBOT_ADDRESS = + 0xef6beCa8D9543eC007bceA835aF768B58F730C1f; + address public constant GSM_SWAP_FREEZE_USDT_ROBOT_ADDRESS = + 0x71381e6718b37C12155CB961Ca3D374A8BfFa0e5; + address public constant GAS_CAPPED_EXECUTION_CHAIN_ROBOT_ADDRESS = + 0xBa37F9eDC52f57caFA3a13ddfD655797Cc4FE257; + address public constant GAS_CAPPED_VOTING_CHAIN_ROBOT_ADDRESS = + 0x7Ed0A6A294Cf085c90917c0ee1aa34e795932558; + address public constant GAS_CAPPED_GOVERNANCE_CHAIN_ROBOT_ADDRESS = + 0x1996c281235D99bB3c6B8d2afbEb8ac6c7A39C11; + + uint256 public constant GSM_SWAP_FREEZE_USDC_ROBOT_LINK_AMOUNT = 80 ether; + uint256 public constant GSM_SWAP_FREEZE_USDT_ROBOT_LINK_AMOUNT = 80 ether; + uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 1500 ether; + uint256 public constant GOVERNANCE_CHAIN_ROBOT_LINK_AMOUNT = 2500 ether; + uint256 public constant VOTING_CHAIN_ROBOT_LINK_AMOUNT = 400 ether; + + function execute() external { + // cancel previous robots + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_GSM_SWAP_FREEZE_USDC_ROBOT_ID); + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_GSM_SWAP_FREEZE_USDT_ROBOT_ID); + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_EXECUTION_CHAIN_ROBOT_ID); + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_GOVERNANCE_CHAIN_ROBOT_ID); + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_VOTING_CHAIN_ROBOT_ID); + + uint256 totalLinkAmount = EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + + GOVERNANCE_CHAIN_ROBOT_LINK_AMOUNT + + VOTING_CHAIN_ROBOT_LINK_AMOUNT + + GSM_SWAP_FREEZE_USDC_ROBOT_LINK_AMOUNT + + GSM_SWAP_FREEZE_USDT_ROBOT_LINK_AMOUNT; + + AaveV2Ethereum.COLLECTOR.transfer( + AaveV2EthereumAssets.LINK_A_TOKEN, + address(this), + totalLinkAmount + ); + AaveV2Ethereum.POOL.withdraw( + AaveV2EthereumAssets.LINK_UNDERLYING, + type(uint256).max, + address(this) + ); + + uint256 linkBalance = IERC20(AaveV2EthereumAssets.LINK_UNDERLYING).balanceOf(address(this)); + IERC20(AaveV2EthereumAssets.LINK_UNDERLYING).forceApprove(ROBOT_OPERATOR, linkBalance); + + // register new robots + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Execution Chain Robot', + GAS_CAPPED_EXECUTION_CHAIN_ROBOT_ADDRESS, + 5_000_000, + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Governance Chain Robot', + GAS_CAPPED_GOVERNANCE_CHAIN_ROBOT_ADDRESS, + 5_000_000, + GOVERNANCE_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Voting Chain Robot', + GAS_CAPPED_VOTING_CHAIN_ROBOT_ADDRESS, + 5_000_000, + VOTING_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'GHO GSM USDC OracleSwapFreezer', + GSM_SWAP_FREEZE_USDC_ROBOT_ADDRESS, + 150_000, + GSM_SWAP_FREEZE_USDC_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'GHO GSM USDT OracleSwapFreezer', + GSM_SWAP_FREEZE_USDT_ROBOT_ADDRESS, + 150_000, + IERC20(AaveV2EthereumAssets.LINK_UNDERLYING).balanceOf(address(this)).toUint96(), + 0, + '' + ); + + // whitelist new robot on the roots consumer contract + IRootsConsumer(ROOTS_CONSUMER).setRobotKeeper(GAS_CAPPED_VOTING_CHAIN_ROBOT_ADDRESS); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol new file mode 100644 index 000000000..201e46443 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; +import {IRootsConsumer} from './interfaces/IRootsConsumer.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; + +/** + * @dev Test for AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 + * command: make test-contract filter=AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 + */ +contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_Test is ProtocolV3TestBase { + AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 internal proposal; + + event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); + event KeeperCancelled(uint256 indexed id, address indexed upkeep); + + address public constant OLD_EXECUTION_CHAIN_ROBOT_ADDRESS = + 0x365d47ceD3D7Eb6a9bdB3814aA23cc06B2D33Ef8; + address public constant OLD_VOTING_CHAIN_ROBOT_ADDRESS = + 0x2cf0fA5b36F0f89a5EA18F835d1375974a7720B8; + address public constant OLD_GOVERNANCE_CHAIN_ROBOT_ADDRESS = + 0x011824f238AEE05329213d5Ae029e899e5412343; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('mainnet'), 19709151); + proposal = new AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest( + 'AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422', + AaveV3Ethereum.POOL, + address(proposal) + ); + } + + function test_oldKeepersCancelledAndNewRegistered() public { + // validate robots cancelled + vm.expectEmit(); + emit KeeperCancelled( + proposal.OLD_GSM_SWAP_FREEZE_USDC_ROBOT_ID(), + proposal.GSM_SWAP_FREEZE_USDC_ROBOT_ADDRESS() + ); + + vm.expectEmit(); + emit KeeperCancelled( + proposal.OLD_GSM_SWAP_FREEZE_USDT_ROBOT_ID(), + proposal.GSM_SWAP_FREEZE_USDT_ROBOT_ADDRESS() + ); + + vm.expectEmit(); + emit KeeperCancelled( + proposal.OLD_EXECUTION_CHAIN_ROBOT_ID(), + OLD_EXECUTION_CHAIN_ROBOT_ADDRESS + ); + + vm.expectEmit(); + emit KeeperCancelled( + proposal.OLD_GOVERNANCE_CHAIN_ROBOT_ID(), + OLD_GOVERNANCE_CHAIN_ROBOT_ADDRESS + ); + + vm.expectEmit(); + emit KeeperCancelled(proposal.OLD_VOTING_CHAIN_ROBOT_ID(), OLD_VOTING_CHAIN_ROBOT_ADDRESS); + + // validate robots registered + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.GAS_CAPPED_EXECUTION_CHAIN_ROBOT_ADDRESS(), + uint96(proposal.EXECUTION_CHAIN_ROBOT_LINK_AMOUNT()) + ); + + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.GAS_CAPPED_GOVERNANCE_CHAIN_ROBOT_ADDRESS(), + uint96(proposal.GOVERNANCE_CHAIN_ROBOT_LINK_AMOUNT()) + ); + + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.GAS_CAPPED_VOTING_CHAIN_ROBOT_ADDRESS(), + uint96(proposal.VOTING_CHAIN_ROBOT_LINK_AMOUNT()) + ); + + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.GSM_SWAP_FREEZE_USDC_ROBOT_ADDRESS(), + uint96(proposal.GSM_SWAP_FREEZE_USDC_ROBOT_LINK_AMOUNT()) + ); + + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.GSM_SWAP_FREEZE_USDT_ROBOT_ADDRESS(), + uint96(proposal.GSM_SWAP_FREEZE_USDT_ROBOT_LINK_AMOUNT()) + ); + + executePayload(vm, address(proposal)); + } + + function test_robotWhitelistedOnRootsConsumer() public { + executePayload(vm, address(proposal)); + + assertEq( + IRootsConsumer(proposal.ROOTS_CONSUMER()).getRobotKeeper(), + proposal.GAS_CAPPED_VOTING_CHAIN_ROBOT_ADDRESS() + ); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol new file mode 100644 index 000000000..9e286b3f4 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Optimism, AaveV3OptimismAssets} from 'aave-address-book/AaveV3Optimism.sol'; +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; +import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; +import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; + +/** + * @title Migrate Robots to Chainlink Automation v2 + * @author BGD Labs (@bgdlabs) + * - Snapshot: TODO + */ +contract AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { + using SafeERC20 for IERC20; + using SafeCast for uint256; + + address public constant OLD_ROBOT_OPERATOR = 0x4f830bc2DdaC99307a3709c85F7533842BdA7c63; + uint256 public constant OLD_EXECUTION_CHAIN_ROBOT_ID = + 98991846084053478582099013231511635776224064505474556907242977329597039975307; + + address public constant ROBOT_OPERATOR = 0x34F098B9B67B147d8a679476bc89982DdE525F8c; + address public constant EXECUTION_CHAIN_ROBOT_ADDRESS = + 0xa0195539e21A6553243344A3BE6b874B5d3EC7b9; + uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; + + function execute() external { + // cancel previous robot + IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_EXECUTION_CHAIN_ROBOT_ID); + + AaveV3Optimism.COLLECTOR.transfer( + AaveV3OptimismAssets.LINK_UNDERLYING, + address(this), + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + ); + + IERC20(AaveV3OptimismAssets.LINK_UNDERLYING).forceApprove( + ROBOT_OPERATOR, + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + ); + + // register new robot + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Execution Chain Robot', + EXECUTION_CHAIN_ROBOT_ADDRESS, + 5_000_000, + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol new file mode 100644 index 000000000..a7e0da940 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Optimism} from 'aave-address-book/AaveV3Optimism.sol'; + +import 'forge-std/Test.sol'; +import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; + +/** + * @dev Test for AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422 + * command: make test-contract filter=AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422 + */ +contract AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_Test is ProtocolV3TestBase { + AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422 internal proposal; + + event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); + event KeeperCancelled(uint256 indexed id, address indexed upkeep); + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('optimism'), 119084285); + proposal = new AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest( + 'AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422', + AaveV3Optimism.POOL, + address(proposal) + ); + } + + function test_oldKeeperCancelledAndNewRegistered() public { + // validate robots cancelled + vm.expectEmit(); + emit KeeperCancelled( + proposal.OLD_EXECUTION_CHAIN_ROBOT_ID(), + proposal.EXECUTION_CHAIN_ROBOT_ADDRESS() + ); + + // validate robots registered + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.EXECUTION_CHAIN_ROBOT_ADDRESS(), + uint96(proposal.EXECUTION_CHAIN_ROBOT_LINK_AMOUNT()) + ); + + executePayload(vm, address(proposal)); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol new file mode 100644 index 000000000..f4cddcf93 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {AaveV3Polygon} from 'aave-address-book/AaveV3Polygon.sol'; +import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; +import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; +import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; +import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; +import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; + +/** + * @title Migrate Robots to Chainlink Automation v2 + * @author BGD Labs (@bgdlabs) + * @notice This payload should be executed after the payload for cancelling old robots has been executed and link tokens + * have been transferred to the collector by calling the `withdrawLink()` method on the old operator contract. + * - Discussion: TODO + */ +contract AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { + using SafeERC20 for IERC20; + using SafeCast for uint256; + + address public constant LINK_TOKEN = 0xb0897686c545045aFc77CF20eC7A532E3120E0F1; + address public constant ROBOT_OPERATOR = 0x4F341c371ab7E2F34A4d3EAd5b2C30F0A6BDC7d0; + address public constant EXECUTION_CHAIN_ROBOT_ADDRESS = + 0x249396a890F89D47F89326d7EE116b1d374Fb3A9; + address public constant VOTING_CHAIN_ROBOT_ADDRESS = 0xbe7998712402B6A63975515A532Ce503437998b7; + + uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; + uint256 public constant VOTING_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; + + function execute() external { + AaveV3Polygon.COLLECTOR.transfer( + LINK_TOKEN, + address(this), + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + VOTING_CHAIN_ROBOT_LINK_AMOUNT + ); + + IERC20(LINK_TOKEN).forceApprove( + ROBOT_OPERATOR, + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + VOTING_CHAIN_ROBOT_LINK_AMOUNT + ); + + // register new robots + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Execution Chain Robot', + EXECUTION_CHAIN_ROBOT_ADDRESS, + 5_000_000, + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Voting Chain Robot', + VOTING_CHAIN_ROBOT_ADDRESS, + 5_000_000, + VOTING_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol new file mode 100644 index 000000000..08b9edf8b --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {AaveV3Polygon} from 'aave-address-book/AaveV3Polygon.sol'; +import {AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; + +/** + * @dev Test for AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 + * command: make test-contract filter=AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 + */ +contract AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_Test is ProtocolV3TestBase { + AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 internal cancelRobotsProposal; + AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 internal proposal; + + event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('polygon'), 56113531); + proposal = new AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422(); + + cancelRobotsProposal = new AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422(); + + // execute the payload to cancel the robot and withraw link to collector + executePayload(vm, address(cancelRobotsProposal)); + + // after robot cancel we need to wait for some blocks to withdraw so we fast-forward + vm.roll(block.number + 50); + IAaveCLRobotOperator(cancelRobotsProposal.OLD_ROBOT_OPERATOR()).withdrawLink( + cancelRobotsProposal.OLD_EXECUTION_CHAIN_ROBOT_ID() + ); + IAaveCLRobotOperator(cancelRobotsProposal.OLD_ROBOT_OPERATOR()).withdrawLink( + cancelRobotsProposal.OLD_VOTING_CHAIN_ROBOT_ID() + ); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest( + 'AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422', + AaveV3Polygon.POOL, + address(proposal) + ); + } + + function test_robotsRegistered() public { + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.EXECUTION_CHAIN_ROBOT_ADDRESS(), + uint96(proposal.EXECUTION_CHAIN_ROBOT_LINK_AMOUNT()) + ); + + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.VOTING_CHAIN_ROBOT_ADDRESS(), + uint96(proposal.VOTING_CHAIN_ROBOT_LINK_AMOUNT()) + ); + + executePayload(vm, address(proposal)); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md new file mode 100644 index 000000000..79b1418a8 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md @@ -0,0 +1,50 @@ +--- +title: "Migrate Robots to Chainlink Automation v2" +author: "BGD Labs (@bgdlabs)" +discussions: "" +--- + +## Simple Summary + +Proposal to migrate existing Aave robots from chainlink automation `v1.2` to `v2.1`. For governance v3 robots on ethereum, we also introduce gas-capped robots in order to limit execution based on network gas price. + +## Motivation + +With the release of Chainlink automation `v2.1`, we think its a good idea to update our existing infrastructure to the latest `v2.1` version. +In addition, as an effort to reduce the cost spent in gas in times of high gas prices, we also introduce gas-capped robots on mainnet which will be activated via this proposal. + +## Specification + +For the migration, the robots registered on the previous robot operator contract will be cancelled and new robots will be registered using an updated robot operator contract which is compatible with the newer version of chainlink automation `v2.1`. + +The robots will be cancelled by calling the `cancel()` method by the payload on the previous robot operator contract, and after the delay has passed anyone could call the permissionless method `withdrawLink()` on the robot operator contract to withdraw the unused funds on the previous robots to the collector. + +On the newer robot operator, the payload will call the `register()` method to register the keepers with the newer chainlink automation registry supporting `v2.1`. + +_Note: All aave governance v3 robots along with robots used for gsm swap freeze will be migrated via this proposal_ + +| | Deployed AaveCLRobotOperator | +| --------- | -------------------------------------------------------------------------------------------------------------------------------- | +| Mainnet | [0x737806fe47FDBDEcBcB82dF7b89AA3D74AdadF62](https://etherscan.io/address/0x737806fe47FDBDEcBcB82dF7b89AA3D74AdadF62) | +| Polygon | [0x4F341c371ab7E2F34A4d3EAd5b2C30F0A6BDC7d0](https://polygonscan.com/address/0x4F341c371ab7E2F34A4d3EAd5b2C30F0A6BDC7d0) | +| Avalanche | [0x023640D7CDa2E2063546A45005393756B9b4ac9D](https://snowscan.xyz/address/0x023640D7CDa2E2063546A45005393756B9b4ac9D) | +| Optimism | [0x34F098B9B67B147d8a679476bc89982DdE525F8c](https://optimistic.etherscan.io/address/0x34F098B9B67B147d8a679476bc89982DdE525F8c) | +| Arbitrum | [0xAa589e4c7539e8D7465c36578098499F0b2BBd12](https://arbiscan.io/address/0xAa589e4c7539e8D7465c36578098499F0b2BBd12) | +| Base | [0xBAC282927CE0cFD1698C5853dCED2eEf9F62a8bb](https://basescan.org/address/0xBAC282927CE0cFD1698C5853dCED2eEf9F62a8bb) | +| BNB | [0xf092900FC8D4962412eC784d7Fbc92a1F69c47bC](https://bscscan.com/address/0xf092900FC8D4962412eC784d7Fbc92a1F69c47bC) | + +| | Deployed Gas Capped Robots | +| --------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| Gas Capped Governance Robot | [0x1996c281235D99bB3c6B8d2afbEb8ac6c7A39C11](https://etherscan.io/address/0x1996c281235D99bB3c6B8d2afbEb8ac6c7A39C11) | +| Gas Capped Voting Robot | [0x7Ed0A6A294Cf085c90917c0ee1aa34e795932558](https://etherscan.io/address/0x7Ed0A6A294Cf085c90917c0ee1aa34e795932558) | +| Gas Capped Execution Robot | [0xBa37F9eDC52f57caFA3a13ddfD655797Cc4FE257](https://etherscan.io/address/0xBa37F9eDC52f57caFA3a13ddfD655797Cc4FE257) | + +## References + +- Implementation: [AaveV2Polygon](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV2Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Polygon](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Optimism](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Arbitrum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol) +- Tests: [AaveV2Polygon](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV2Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Polygon](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Optimism](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Arbitrum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol) +- [Discussion](TODO) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol new file mode 100644 index 000000000..d834bbaf8 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/GovV3Helpers.sol'; +import {EthereumScript, PolygonScript, AvalancheScript, OptimismScript, ArbitrumScript} from 'aave-helpers/ScriptUtils.sol'; +import {AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; + +/** + * @dev Deploy Polygon + * deploy-command: make deploy-ledger contract=src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol:DeployPolygon chain=polygon + * verify-command: npx catapulta-verify -b broadcast/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol/137/run-latest.json + */ +contract DeployPolygon is PolygonScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + address payload1 = GovV3Helpers.deployDeterministic( + type(AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + + // compose action + IPayloadsControllerCore.ExecutionAction[] + memory actions = new IPayloadsControllerCore.ExecutionAction[](2); + actions[0] = GovV3Helpers.buildAction(payload0); + actions[1] = GovV3Helpers.buildAction(payload1); + + // register action at payloadsController + GovV3Helpers.createPayload(actions); + } +} + +/** + * @dev Deploy Avalanche + * deploy-command: make deploy-ledger contract=src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol:DeployAvalanche chain=avalanche + * verify-command: npx catapulta-verify -b broadcast/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol/43114/run-latest.json + */ +contract DeployAvalanche is AvalancheScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + address payload1 = GovV3Helpers.deployDeterministic( + type(AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + + // compose action + IPayloadsControllerCore.ExecutionAction[] + memory actions = new IPayloadsControllerCore.ExecutionAction[](2); + actions[0] = GovV3Helpers.buildAction(payload0); + actions[1] = GovV3Helpers.buildAction(payload1); + + // register action at payloadsController + GovV3Helpers.createPayload(actions); + } +} + +/** + * @dev Deploy Ethereum + * deploy-command: make deploy-ledger contract=src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol:DeployEthereum chain=mainnet + * verify-command: npx catapulta-verify -b broadcast/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol/1/run-latest.json + */ +contract DeployEthereum is EthereumScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422).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 Optimism + * deploy-command: make deploy-ledger contract=src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol:DeployOptimism chain=optimism + * verify-command: npx catapulta-verify -b broadcast/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol/10/run-latest.json + */ +contract DeployOptimism is OptimismScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422).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/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol:DeployArbitrum chain=arbitrum + * verify-command: npx catapulta-verify -b broadcast/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol/42161/run-latest.json + */ +contract DeployArbitrum is ArbitrumScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422).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/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol:CreateProposal chain=mainnet + */ +contract CreateProposal is EthereumScript { + function run() external { + // create payloads + PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](5); + + // compose actions for validation + IPayloadsControllerCore.ExecutionAction[] + memory actionsPolygon = new IPayloadsControllerCore.ExecutionAction[](2); + actionsPolygon[0] = GovV3Helpers.buildAction( + type(AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + actionsPolygon[1] = GovV3Helpers.buildAction( + type(AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + payloads[0] = GovV3Helpers.buildPolygonPayload(vm, actionsPolygon); + + IPayloadsControllerCore.ExecutionAction[] + memory actionsAvalanche = new IPayloadsControllerCore.ExecutionAction[](2); + actionsAvalanche[0] = GovV3Helpers.buildAction( + type(AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + actionsAvalanche[1] = GovV3Helpers.buildAction( + type(AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + payloads[1] = GovV3Helpers.buildAvalanchePayload(vm, actionsAvalanche); + + IPayloadsControllerCore.ExecutionAction[] + memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1); + actionsEthereum[0] = GovV3Helpers.buildAction( + type(AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + payloads[2] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); + + IPayloadsControllerCore.ExecutionAction[] + memory actionsOptimism = new IPayloadsControllerCore.ExecutionAction[](1); + actionsOptimism[0] = GovV3Helpers.buildAction( + type(AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + payloads[3] = GovV3Helpers.buildOptimismPayload(vm, actionsOptimism); + + IPayloadsControllerCore.ExecutionAction[] + memory actionsArbitrum = new IPayloadsControllerCore.ExecutionAction[](1); + actionsArbitrum[0] = GovV3Helpers.buildAction( + type(AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode + ); + payloads[4] = GovV3Helpers.buildArbitrumPayload(vm, actionsArbitrum); + + // create proposal + vm.startBroadcast(); + GovV3Helpers.createProposal( + vm, + payloads, + GovV3Helpers.ipfsHashFile( + vm, + 'src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md' + ) + ); + } +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/config.ts b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/config.ts new file mode 100644 index 000000000..8f4ee0416 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/config.ts @@ -0,0 +1,29 @@ +import {ConfigFile} from '../../generator/types'; +export const config: ConfigFile = { + rootOptions: { + pools: [ + 'AaveV2Polygon', + 'AaveV2Avalanche', + 'AaveV3Ethereum', + 'AaveV3Polygon', + 'AaveV3Avalanche', + 'AaveV3Optimism', + 'AaveV3Arbitrum', + ], + title: 'Migrate Robots to Chainlink Automation v2', + shortName: 'MigrateRobotsToChainlinkAutomationV2', + date: '20240422', + author: 'BGD Labs (@bgdlabs)', + discussion: '', + snapshot: '', + }, + poolOptions: { + AaveV2Polygon: {configs: {OTHERS: {}}, cache: {blockNumber: 56113527}}, + AaveV2Avalanche: {configs: {OTHERS: {}}, cache: {blockNumber: 44512836}}, + AaveV3Ethereum: {configs: {OTHERS: {}}, cache: {blockNumber: 19709151}}, + AaveV3Polygon: {configs: {OTHERS: {}}, cache: {blockNumber: 56113531}}, + AaveV3Avalanche: {configs: {OTHERS: {}}, cache: {blockNumber: 44512842}}, + AaveV3Optimism: {configs: {OTHERS: {}}, cache: {blockNumber: 119084285}}, + AaveV3Arbitrum: {configs: {OTHERS: {}}, cache: {blockNumber: 203571065}}, + }, +}; diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol new file mode 100644 index 000000000..8b2317692 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * @title IAaveCLRobotOperator + * @author BGD Labs + * @notice Defines the interface for the robot operator contract to perform admin actions on the automation keepers. + **/ +interface IAaveCLRobotOperator { + /** + * @dev Emitted when a keeper is registered using the operator contract. + * @param id id of the keeper registered. + * @param upkeep address of the keeper contract. + * @param amount amount of link the keeper has been registered with. + */ + event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); + + /** + * @dev Emitted when a keeper is cancelled using the operator contract. + * @param id id of the keeper cancelled. + * @param upkeep address of the keeper contract. + */ + event KeeperCancelled(uint256 indexed id, address indexed upkeep); + + /** + * @dev Emitted when a keeper is already cancelled, and link is being withdrawn using the operator contract. + * @param id id of the keeper to withdraw link from. + * @param upkeep address of the keeper contract. + * @param to address where link needs to be withdrawn to. + */ + event LinkWithdrawn(uint256 indexed id, address indexed upkeep, address indexed to); + + /** + * @dev Emitted when a keeper is refilled using the operator contract. + * @param id id of the keeper which has been refilled. + * @param from address which refilled the keeper. + * @param amount amount of link which has been refilled for the keeper. + */ + event KeeperRefilled(uint256 indexed id, address indexed from, uint96 indexed amount); + + /** + * @dev Emitted when a keeper is paused using the operator contract. + * @param id id of the keeper which has been paused. + */ + event KeeperPaused(uint256 indexed id); + + /** + * @dev Emitted when a keeper is unpaused using the operator contract. + * @param id id of the keeper which has been unpaused. + */ + event KeeperUnpaused(uint256 indexed id); + + /** + * @dev Emitted when the link withdraw address has been changed of the keeper. + * @param newWithdrawAddress address of the new withdraw address where link will be withdrawn to. + */ + event WithdrawAddressSet(address indexed newWithdrawAddress); + + /** + * @dev Emitted when gas limit is configured using the operator contract. + * @param id id of the keeper for which gas limit has been configured. + * @param upkeep address of the keeper contract. + * @param gasLimit max gas limit which has been configured for the keeper. + */ + event GasLimitSet(uint256 indexed id, address indexed upkeep, uint32 indexed gasLimit); + + /** + * @dev Emitted when trigger config is configured for a log type robot using the operator contract. + * @param id id of the keeper for which trigger config has been configured. + */ + event TriggerConfigSet(uint256 indexed id); + + /** + * @dev Emitted when a new chainlink keeper registry is set on the operator contract. + * @param newKeeperRegistry address of the new chainlink keeper registry contract. + */ + event KeeperRegistrySet(address indexed newKeeperRegistry); + + /** + * @dev Emitted when a new chainlink keeper registrar is set on the operator contract. + * @param newKeeperRegistrar address of the new chainlink keeper registrar contract. + */ + event KeeperRegistrarSet(address indexed newKeeperRegistrar); + + /** + * @dev Emitted when a the keepers are migrated to a new chainlink keeper registry contract. + * @param ids array of ids all the chainlink keepers to migrate. + * @param newKeeperRegistry address of the new chainlink keeper registry contract to migrate to. + * @param newKeeperRegistrar address of the new chainlink keeper registrar contract associated with the registry. + */ + event KeepersMigrated( + uint256[] indexed ids, + address indexed newKeeperRegistry, + address indexed newKeeperRegistrar + ); + + /** + * @notice holds the keeper info registered via the operator. + * @param upkeep address of the keeper contract registered. + * @param name name of the registered keeper. + */ + struct KeeperInfo { + address upkeep; + string name; + } + + /** + * @notice method called by owner to register the automation robot keeper. + * @param name name of keeper. + * @param upkeepContract upkeepContract of the keeper. + * @param gasLimit max gasLimit which the chainlink automation node can execute for the automation. + * @param amountToFund amount of link to fund the keeper with. + * @param triggerType type of robot keeper to register, 0 for conditional and 1 for event log based. + * @param triggerConfig encoded trigger config for event log based robots, unused for conditional type robots. + * @return chainlink id for the registered keeper. + **/ + function register( + string memory name, + address upkeepContract, + uint32 gasLimit, + uint96 amountToFund, + uint8 triggerType, + bytes memory triggerConfig + ) external returns (uint256); + + /** + * @notice method called to refill the keeper. + * @param id - id of the chainlink registered keeper to refill. + * @param amount - amount of LINK to refill the keeper with. + **/ + function refillKeeper(uint256 id, uint96 amount) external; + + /** + * @notice method called by the owner to cancel the automation robot keeper. + * @param id - id of the chainlink registered keeper to cancel. + **/ + function cancel(uint256 id) external; + + /** + * @notice method called permissionlessly to withdraw link of automation robot keeper to the withdraw address. + * this method should only be called after the automation robot keeper is cancelled. + * @param id - id of the chainlink registered keeper to withdraw funds of. + **/ + function withdrawLink(uint256 id) external; + + /** + * @notice method called by the owner to migrate the keepers to a newer version of chainlink automation. + * @param newRegistry address of the new chainlink registry to migrate the keepers to. + * @param newRegistrar address of the new associated chainlink registrar of the new registry. + **/ + function migrate(address newRegistry, address newRegistrar) external; + + /** + * @notice method called by owner / robot guardian to pause the upkeep robot keeper. + * @param id - id of the chainlink registered keeper to pause. + **/ + function pause(uint256 id) external; + + /** + * @notice method called by owner / robot guardian to unpause the upkeep robot keeper. + * @param id - id of the chainlink registered keeper to unpause. + **/ + function unpause(uint256 id) external; + + /** + * @notice method to check if the keeper is paused or not. + * @param id - id of the chainlink registered keeper to check. + * @return true if the keeper is paused, false otherwise. + **/ + function isPaused(uint256 id) external returns (bool); + + /** + * @notice method called by owner / robot guardian to set the max gasLimit of upkeep robot keeper. + * @param id - id of the chainlink registered keeper to set the gasLimit. + * @param gasLimit max gasLimit which the chainlink automation node can execute. + **/ + function setGasLimit(uint256 id, uint32 gasLimit) external; + + /** + * @notice method called by owner to set the withdraw address when withdrawing excess link from the automation robot keeeper. + * @param withdrawAddress withdraw address to withdaw link to. + **/ + function setWithdrawAddress(address withdrawAddress) external; + + /** + * @notice method called by owner / guardian to set the trigger configuration for event log type robots. + * @param id - id of the chainlink registered keeper to set the trigger config. + * @param triggerConfig encoded data containing the configuration + * Ex: + * abi.encode( + * address contractAddress, (address that will be emitting the log) + * uint8 filterSelector, (denoting which topics apply to filter ex 000, 101, 111...only last 3 bits apply) + * bytes32 topic0, (signature of the emitted event) + * bytes32 topic1, (filter on indexed topic 1) + * bytes32 topic2, (filter on indexed topic 2) + * bytes32 topic3 (filter on indexed topic 3) + * ); + **/ + function setTriggerConfig(uint256 id, bytes calldata triggerConfig) external; + + /** + * @notice method called by owner to set the address of chainlink keeper registry contract. + * @param newRegistry address of the new chainlink keeper registry contract to set. + */ + function setRegistry(address newRegistry) external; + + /** + * @notice method called by owner to set the address of chainlink keeper registrar contract. + * @param newRegistrar address of the new chainlink keeper registrar contract to set. + */ + function setRegistrar(address newRegistrar) external; + + /** + * @notice method to get the withdraw address for the robot operator contract. + * @return withdraw address to send excess link to. + **/ + function getWithdrawAddress() external view returns (address); + + /** + * @notice method to get the keeper information registered via the operator. + * @param id - id of the chainlink registered keeper. + * @return Struct containing the following information about the keeper: + * - uint256 chainlink id of the registered keeper. + * - string name of the registered keeper. + **/ + function getKeeperInfo(uint256 id) external view returns (KeeperInfo memory); + + /** + * @notice method to get the address of chainlink keeper registry contract. + * @return keeper registry address. + */ + function getRegistry() external returns (address); + + /** + * @notice method to get the address of chainlink keeper registrar contract. + * @return keeper registrar address. + */ + function getRegistrar() external returns (address); + + /** + * @notice method to get the address of ERC-677 link token. + * @return link token address. + */ + function getLinkToken() external returns (address); + + /** + * @notice method to get of all the ids of keepers registered by the robot operator which have not been cancelled. + * @return array of registered keeper ids. + */ + function getKeepersList() external returns (uint256[] memory); +} diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IRootsConsumer.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IRootsConsumer.sol new file mode 100644 index 000000000..a526d1319 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IRootsConsumer.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * @title IRootsConsumer + * @author BGD Labs + * @notice Defines the interface for the contract to fetch api response to register storage roots. + **/ +interface IRootsConsumer { + /** + * @notice Emitted when we get a response from chainlink api and the storage roots are registered to the data warehouse. + * @param requestId request id received by chainlink. + * @param blockHash block hash for which roots have beeen registered. + */ + event RootsRegisteredFulfilled(bytes32 indexed requestId, bytes32 indexed blockHash); + + /** + * @notice Emitted when we set a new api url to fetch the roots data. + * @param newApiUrl url of the new chainlink api request. + */ + event ApiUrlSet(string indexed newApiUrl); + + /** + * @notice Emitted when we set a new jobId of the chainlink operator. + * @param newJobId jobId which has been set. + */ + event JobIdSet(bytes32 indexed newJobId); + + /** + * @notice Emitted when we set a new fee to pay for the chainlink api request. + * @param newFee fee set for the api request. + */ + event FeeSet(uint256 indexed newFee); + + /** + * @notice Emitted when we set a new chainlink operator. + * @param newOperator address of the chainlink operator. + */ + event OperatorSet(address indexed newOperator); + + /** + * @notice Emitted when the link withdraw address has been changed of the consumer. + * @param newWithdrawAddress address of the new withdraw address where link will be withdrawn to. + */ + event WithdrawAddressSet(address indexed newWithdrawAddress); + + /** + * @notice Emitted when we set a new robot keeper. + * @param newRobotKeeper address of the new robot keeper. + */ + event RobotKeeperSet(address indexed newRobotKeeper); + + /** + * @notice Emitted when we send a request by the keeper to register the roots. + * @param blockHash blockHash for which the roots need to be registered. + * @param requestUrl url to request data needed to register the roots. + * @param fee fee paid to the chainlink operator for the request. + */ + event OperatorRequestSent( + bytes32 indexed blockHash, + string indexed requestUrl, + uint256 indexed fee + ); + + /** + * @notice method to request data needed to register roots via chainlink api. + * @param blockHash block hash for which roots needs to be registered. + **/ + function requestSubmitRoots(bytes32 blockHash) external; + + /** + * @notice method called by chainlink node operator containing the api response as encoded data, used for registering roots. + * @param requestId request id received by chainlink. + * @param response encoded data received as the api response which is used to register the roots. + **/ + function fulfillRegisterRoots(bytes32 requestId, bytes calldata response) external; + + /** + * @notice method called by the owner / robot guardian to change the chainlink operator. + * @param chainlinkOperator new operator for api requests. + **/ + function setOperator(address chainlinkOperator) external; + + /** + * @notice method called by the owner / robot guardian to change the fee paid to the operator. + * @param fee new fee paid to the operator. + **/ + function setFee(uint256 fee) external; + + /** + * @notice method called by the owner / robot guardian to change the api url we use to fetch data to register roots. + * @param api_url new api url to set. + **/ + function setApiUrl(string memory api_url) external; + + /** + * @notice method called by the owner / robot guardian to change the jobId of the operator. + * @param jobId new job id of the operator. + **/ + function setJobId(bytes32 jobId) external; + + /** + * @notice method called by owner / robot guardian to set the robot keeper which can request to submit roots. + * @param robotKeeper new address of the robot keeper to set. + **/ + function setRobotKeeper(address robotKeeper) external; + + /** + * @notice method to get the fee to be paid to the chainlink operator. + * @return operator fee. + */ + function getFee() external view returns (uint256); + + /** + * @notice method to get the job id of the chainlink operator. + * @return job id. + */ + function getJobId() external view returns (bytes32); + + /** + * @notice method to get the api url which returns the data to register storage roots. + * @return url of the backend api. + */ + function getApiUrl() external view returns (string memory); + + /** + * @notice method to get the the robot keeper which can request to submit roots. + * @return address of the robot keeeper contract. + */ + function getRobotKeeper() external view returns (address); + + /** + * @notice method to get the address of the data warehouse contract. + * @return address of the data warehouse contract. + */ + function DATA_WAREHOUSE() external view returns (address); +} From 8999e10b24270b8c40f14f66939ff01278af5919 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 23 Apr 2024 13:48:39 +0530 Subject: [PATCH 2/9] fix: test on arbitrum --- ...sToChainlinkAutomationV2_20240422_after.md | 18 +-- ...botsToChainlinkAutomationV2_20240422.t.sol | 16 +- .../interfaces/ArbSys.sol | 139 ++++++++++++++++++ 3 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/ArbSys.sol diff --git a/diffs/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md b/diffs/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md index c225b99a9..2459aa6ac 100644 --- a/diffs/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md +++ b/diffs/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_before_AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_after.md @@ -9,7 +9,7 @@ | liquidityIndex | 1.004 | 1.004 | | variableBorrowIndex | 1.03 | 1.03 | | currentLiquidityRate | 0.002 % | 0.002 % | -| currentVariableBorrowRate | 0.205 % | 0.205 % | +| currentVariableBorrowRate | 0.202 % | 0.202 % | ## Raw diff @@ -19,20 +19,20 @@ "reserves": { "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4": { "currentLiquidityRate": { - "from": "21519899216131949746774", - "to": "21520920172477038470997" + "from": "20985901007959518447306", + "to": "20986891757668837645354" }, "currentVariableBorrowRate": { - "from": "2045586675646185482544796", - "to": "2045635198873576104131496" + "from": "2020047490198880263355387", + "to": "2020095173113288571012529" }, "liquidityIndex": { - "from": "1003748294487317650250818674", - "to": "1003748294984590865323782988" + "from": "1003748460436427781600991452", + "to": "1003748460849222735985294419" }, "variableBorrowIndex": { - "from": "1030010588256949865469612818", - "to": "1030010636762295022112692520" + "from": "1030014561085096814904145780", + "to": "1030014601859425605006587904" } } } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol index 52acfe64a..38d5d59b2 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol'; import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; import {AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {ArbSys} from './interfaces/ArbSys.sol'; /** * @dev Test for AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 @@ -11,13 +12,26 @@ import {AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422} from './Aa */ contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_Test is ProtocolV3TestBase { AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 internal proposal; + address public constant ARB_SYS = 0x0000000000000000000000000000000000000064; event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); event KeeperCancelled(uint256 indexed id, address indexed upkeep); function setUp() public { - vm.createSelectFork(vm.rpcUrl('arbitrum'), 203931041); + uint256 blockNumber = 203936337; + vm.createSelectFork(vm.rpcUrl('arbitrum'), blockNumber); proposal = new AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422(); + + vm.mockCall( + ARB_SYS, + abi.encodeWithSelector(ArbSys.arbBlockNumber.selector), + abi.encode(blockNumber) + ); + vm.mockCall( + ARB_SYS, + abi.encodeWithSelector(ArbSys.arbBlockHash.selector, blockNumber - 1), + abi.encode(0xbe6f5dfa9ce3324bd677f5195ecd8d1a258cbf3800f24621d0e0d2724224704f) + ); } /** diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/ArbSys.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/ArbSys.sol new file mode 100644 index 000000000..c7d285a97 --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/ArbSys.sol @@ -0,0 +1,139 @@ +// Copyright 2021-2022, Offchain Labs, Inc. +// For license information, see https://github.com/nitro/blob/master/LICENSE +// SPDX-License-Identifier: BUSL-1.1 + +pragma solidity >=0.4.21 <0.9.0; + +/** + * @title System level functionality + * @notice For use by contracts to interact with core L2-specific functionality. + * Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064. + */ +interface ArbSys { + /** + * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0) + * @return block number as int + */ + function arbBlockNumber() external view returns (uint256); + + /** + * @notice Get Arbitrum block hash (reverts unless currentBlockNum-256 <= arbBlockNum < currentBlockNum) + * @return block hash + */ + function arbBlockHash(uint256 arbBlockNum) external view returns (bytes32); + + /** + * @notice Gets the rollup's unique chain identifier + * @return Chain identifier as int + */ + function arbChainID() external view returns (uint256); + + /** + * @notice Get internal version number identifying an ArbOS build + * @return version number as int + */ + function arbOSVersion() external view returns (uint256); + + /** + * @notice Returns 0 since Nitro has no concept of storage gas + * @return uint 0 + */ + function getStorageGasAvailable() external view returns (uint256); + + /** + * @notice (deprecated) check if current call is top level (meaning it was triggered by an EoA or a L1 contract) + * @dev this call has been deprecated and may be removed in a future release + * @return true if current execution frame is not a call by another L2 contract + */ + function isTopLevelCall() external view returns (bool); + + /** + * @notice map L1 sender contract address to its L2 alias + * @param sender sender address + * @param unused argument no longer used + * @return aliased sender address + */ + function mapL1SenderContractAddressToL2Alias( + address sender, + address unused + ) external pure returns (address); + + /** + * @notice check if the caller (of this caller of this) is an aliased L1 contract address + * @return true iff the caller's address is an alias for an L1 contract address + */ + function wasMyCallersAddressAliased() external view returns (bool); + + /** + * @notice return the address of the caller (of this caller of this), without applying L1 contract address aliasing + * @return address of the caller's caller, without applying L1 contract address aliasing + */ + function myCallersAddressWithoutAliasing() external view returns (address); + + /** + * @notice Send given amount of Eth to dest from sender. + * This is a convenience function, which is equivalent to calling sendTxToL1 with empty data. + * @param destination recipient address on L1 + * @return unique identifier for this L2-to-L1 transaction. + */ + function withdrawEth(address destination) external payable returns (uint256); + + /** + * @notice Send a transaction to L1 + * @dev it is not possible to execute on the L1 any L2-to-L1 transaction which contains data + * to a contract address without any code (as enforced by the Bridge contract). + * @param destination recipient address on L1 + * @param data (optional) calldata for L1 contract call + * @return a unique identifier for this L2-to-L1 transaction. + */ + function sendTxToL1(address destination, bytes calldata data) external payable returns (uint256); + + /** + * @notice Get send Merkle tree state + * @return size number of sends in the history + * @return root root hash of the send history + * @return partials hashes of partial subtrees in the send history tree + */ + function sendMerkleTreeState() + external + view + returns (uint256 size, bytes32 root, bytes32[] memory partials); + + /** + * @notice creates a send txn from L2 to L1 + * @param position = (level << 192) + leaf = (0 << 192) + leaf = leaf + */ + event L2ToL1Tx( + address caller, + address indexed destination, + uint256 indexed hash, + uint256 indexed position, + uint256 arbBlockNum, + uint256 ethBlockNum, + uint256 timestamp, + uint256 callvalue, + bytes data + ); + + /// @dev DEPRECATED in favour of the new L2ToL1Tx event above after the nitro upgrade + event L2ToL1Transaction( + address caller, + address indexed destination, + uint256 indexed uniqueId, + uint256 indexed batchNumber, + uint256 indexInBatch, + uint256 arbBlockNum, + uint256 ethBlockNum, + uint256 timestamp, + uint256 callvalue, + bytes data + ); + + /** + * @notice logs a merkle branch for proof synthesis + * @param reserved an index meant only to align the 4th index with L2ToL1Transaction's 4th event + * @param hash the merkle hash + * @param position = (level << 192) + leaf + */ + event SendMerkleUpdate(uint256 indexed reserved, bytes32 indexed hash, uint256 indexed position); +} From 2bdd894015418bb5be101b1a1728f2430066386e Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 23 Apr 2024 14:22:35 +0530 Subject: [PATCH 3/9] test: comment regarading the abrPreCompile issue --- ...3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol index 38d5d59b2..bc4959a04 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -22,6 +22,7 @@ contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pr vm.createSelectFork(vm.rpcUrl('arbitrum'), blockNumber); proposal = new AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422(); + // https://github.com/foundry-rs/foundry/issues/5085 vm.mockCall( ARB_SYS, abi.encodeWithSelector(ArbSys.arbBlockNumber.selector), From 836dfcfa54983da09852a5b0161102e9d18a844f Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 15 May 2024 17:36:40 +0530 Subject: [PATCH 4/9] Update src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md Co-authored-by: Ernesto Boado --- .../MigrateRobotsToChainlinkAutomationV2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md index 79b1418a8..d237dd6ef 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md @@ -10,7 +10,7 @@ Proposal to migrate existing Aave robots from chainlink automation `v1.2` to `v2 ## Motivation -With the release of Chainlink automation `v2.1`, we think its a good idea to update our existing infrastructure to the latest `v2.1` version. +With the release of Chainlink automation `v2.1`, we think its a good idea to update the Aave Robot existing infrastructure to the latest `v2.1` version. In addition, as an effort to reduce the cost spent in gas in times of high gas prices, we also introduce gas-capped robots on mainnet which will be activated via this proposal. ## Specification From 2b2a83a92de61037b8404e2655a8bdd12dc4589d Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 15 May 2024 17:36:47 +0530 Subject: [PATCH 5/9] Update src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md Co-authored-by: Ernesto Boado --- .../MigrateRobotsToChainlinkAutomationV2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md index d237dd6ef..199799162 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md @@ -15,7 +15,7 @@ In addition, as an effort to reduce the cost spent in gas in times of high gas p ## Specification -For the migration, the robots registered on the previous robot operator contract will be cancelled and new robots will be registered using an updated robot operator contract which is compatible with the newer version of chainlink automation `v2.1`. +For the migration, the robots registered on the previous robot operator contract will be cancelled and new robots will be registered using an updated robot operator contract, compatible with the newer version of chainlink automation `v2.1`. The robots will be cancelled by calling the `cancel()` method by the payload on the previous robot operator contract, and after the delay has passed anyone could call the permissionless method `withdrawLink()` on the robot operator contract to withdraw the unused funds on the previous robots to the collector. From 1a62fd6c295fd2948b2e5371284d971010d4b434 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 21 May 2024 20:43:15 +0530 Subject: [PATCH 6/9] feat: static a token robot --- ...RobotsToChainlinkAutomationV2_20240422.sol | 2 +- ...RobotsToChainlinkAutomationV2_20240422.sol | 2 +- ...RobotsToChainlinkAutomationV2_20240422.sol | 21 +++++-- ...botsToChainlinkAutomationV2_20240422.t.sol | 8 ++- ...RobotsToChainlinkAutomationV2_20240422.sol | 55 ++++++++++++++++--- ...botsToChainlinkAutomationV2_20240422.t.sol | 24 +++++++- ...RobotsToChainlinkAutomationV2_20240422.sol | 46 +++++++++++----- ...botsToChainlinkAutomationV2_20240422.t.sol | 9 ++- ...RobotsToChainlinkAutomationV2_20240422.sol | 31 ++++++++--- ...botsToChainlinkAutomationV2_20240422.t.sol | 13 +++-- ...RobotsToChainlinkAutomationV2_20240422.sol | 25 +++++++-- ...botsToChainlinkAutomationV2_20240422.t.sol | 9 ++- .../MigrateRobotsToChainlinkAutomationV2.md | 43 +++++++++------ .../interfaces/IAaveCLRobotOperator.sol | 6 +- 14 files changed, 228 insertions(+), 66 deletions(-) diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol index 807eb94f4..953d1c3b7 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -8,7 +8,7 @@ import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; * @title Migrate Robots to Chainlink Automation v2 * @author BGD Labs (@bgdlabs) * @notice This payload should be executed before the payload for registering new robots. - * - Discussion: TODO + * - Discussion: https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/36 */ contract AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { address public constant OLD_ROBOT_OPERATOR = 0x7A9ff54A6eE4a21223036890bB8c4ea2D62c686b; diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol index d89ded7ba..06243a7a7 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -8,7 +8,7 @@ import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; * @title Migrate Robots to Chainlink Automation v2 * @author BGD Labs (@bgdlabs) * @notice This payload should be executed before the payload for registering new robots. - * - Discussion: TODO + * - Discussion: https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/36 */ contract AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { address public constant OLD_ROBOT_OPERATOR = 0x4e8984D11A47Ff89CD67c7651eCaB6C00a74B4A9; diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol index 755e2f9c9..e09390644 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -11,7 +11,7 @@ import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; /** * @title Migrate Robots to Chainlink Automation v2 * @author BGD Labs (@bgdlabs) - * - Discussion: TODO + * - Discussion: https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/36 */ contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { using SafeERC20 for IERC20; @@ -21,9 +21,12 @@ contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos uint256 public constant OLD_EXECUTION_CHAIN_ROBOT_ID = 78329451080216164099529400539433108989111820950862041749656351555695961643082; - address public constant ROBOT_OPERATOR = 0xAa589e4c7539e8D7465c36578098499F0b2BBd12; + address public constant ROBOT_OPERATOR = 0xaa944aD95e51CB83C1f35FAEEDfC7d2c31B0BB4d; address public constant EXECUTION_CHAIN_ROBOT_ADDRESS = 0x64093fe5f8Cf62aFb4377cf7EF4373537fe9155B; + address public constant STATIC_A_TOKEN_ROBOT_ADDRESS = 0x0451f67bA61966C346daBAbB50a30Cc6A9A67C69; + + uint256 public constant STATIC_A_TOKEN_ROBOT_LINK_AMOUNT = 35 ether; uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; function execute() external { @@ -33,7 +36,7 @@ contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos AaveV3Arbitrum.COLLECTOR.transfer( AaveV3ArbitrumAssets.LINK_A_TOKEN, address(this), - EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + STATIC_A_TOKEN_ROBOT_LINK_AMOUNT ); AaveV3Arbitrum.POOL.withdraw( AaveV3ArbitrumAssets.LINK_UNDERLYING, @@ -48,8 +51,18 @@ contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos IAaveCLRobotOperator(ROBOT_OPERATOR).register( 'Execution Chain Robot', EXECUTION_CHAIN_ROBOT_ADDRESS, + '', 5_000_000, - linkBalance.toUint96(), + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'StaticAToken Rewards Robot', + STATIC_A_TOKEN_ROBOT_ADDRESS, + '', + 1_000_000, + IERC20(AaveV3ArbitrumAssets.LINK_UNDERLYING).balanceOf(address(this)).toUint96(), 0, '' ); diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol index bc4959a04..2ce54bc36 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -18,7 +18,7 @@ contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pr event KeeperCancelled(uint256 indexed id, address indexed upkeep); function setUp() public { - uint256 blockNumber = 203936337; + uint256 blockNumber = 213434099; vm.createSelectFork(vm.rpcUrl('arbitrum'), blockNumber); proposal = new AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422(); @@ -61,6 +61,12 @@ contract AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pr proposal.EXECUTION_CHAIN_ROBOT_ADDRESS(), uint96(proposal.EXECUTION_CHAIN_ROBOT_LINK_AMOUNT()) ); + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.STATIC_A_TOKEN_ROBOT_ADDRESS(), + uint96(proposal.STATIC_A_TOKEN_ROBOT_LINK_AMOUNT()) + ); executePayload(vm, address(proposal)); } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol index c39aca218..bb7b21353 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -13,36 +13,47 @@ import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; * @author BGD Labs (@bgdlabs) * @notice This payload should be executed after the payload for cancelling old robots has been executed and link tokens * have been transferred to the collector by calling the `withdrawLink()` method on the old operator contract. - * - Discussion: TODO + * - Discussion: https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/36 */ contract AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { using SafeERC20 for IERC20; using SafeCast for uint256; - address public constant ROBOT_OPERATOR = 0x023640D7CDa2E2063546A45005393756B9b4ac9D; + address public constant ROBOT_OPERATOR = 0x06d958772304e7220fc3E463756CE01Ed0D24db2; address public constant EXECUTION_CHAIN_ROBOT_ADDRESS = 0x7B74938583Eb03e06042fcB651046BaF0bf15644; address public constant VOTING_CHAIN_ROBOT_ADDRESS = 0x10E49034306EaA663646773C04b7B67E81eD0D52; + address public constant STATIC_A_TOKEN_ROBOT_ADDRESS = 0x8aD3f00e91F0a3Ad8b0dF897c19EC345EaB761c4; + + address public constant PROOF_OF_RESERVE_ROBOT_ADDRESS = + 0x7aE2930B50CFEbc99FE6DB16CE5B9C7D8d09332C; + address public constant PROOF_OF_RESERVE_EXECUTOR_V2 = 0x7fc3FCb14eF04A48Bb0c12f0c39CD74C249c37d8; + address public constant PROOF_OF_RESERVE_EXECUTOR_V3 = 0xab22988D93d5F942fC6B6c6Ea285744809D1d9Cc; uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; uint256 public constant VOTING_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; + uint256 public constant PROOF_OF_RESERVE_ROBOT_LINK_AMOUNT = 15 ether; + uint256 public constant STATIC_A_TOKEN_ROBOT_LINK_AMOUNT = 20 ether; function execute() external { + uint256 totalLinkAmount = EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + + VOTING_CHAIN_ROBOT_LINK_AMOUNT + + (PROOF_OF_RESERVE_ROBOT_LINK_AMOUNT * 2) + + STATIC_A_TOKEN_ROBOT_LINK_AMOUNT; + AaveV3Avalanche.COLLECTOR.transfer( AaveV3AvalancheAssets.LINKe_UNDERLYING, address(this), - EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + VOTING_CHAIN_ROBOT_LINK_AMOUNT + totalLinkAmount ); - IERC20(AaveV3AvalancheAssets.LINKe_UNDERLYING).forceApprove( - ROBOT_OPERATOR, - EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + VOTING_CHAIN_ROBOT_LINK_AMOUNT - ); + IERC20(AaveV3AvalancheAssets.LINKe_UNDERLYING).forceApprove(ROBOT_OPERATOR, totalLinkAmount); // register new robots IAaveCLRobotOperator(ROBOT_OPERATOR).register( 'Execution Chain Robot', EXECUTION_CHAIN_ROBOT_ADDRESS, + '', 5_000_000, EXECUTION_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), 0, @@ -51,10 +62,40 @@ contract AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropo IAaveCLRobotOperator(ROBOT_OPERATOR).register( 'Voting Chain Robot', VOTING_CHAIN_ROBOT_ADDRESS, + '', 5_000_000, VOTING_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), 0, '' ); + + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Proof Of Reserve Robot V2', + PROOF_OF_RESERVE_ROBOT_ADDRESS, + abi.encode(PROOF_OF_RESERVE_EXECUTOR_V2), + 2_500_000, + PROOF_OF_RESERVE_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Proof Of Reserve Robot V3', + PROOF_OF_RESERVE_ROBOT_ADDRESS, + abi.encode(PROOF_OF_RESERVE_EXECUTOR_V3), + 2_500_000, + PROOF_OF_RESERVE_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'StaticAToken Rewards Robot', + STATIC_A_TOKEN_ROBOT_ADDRESS, + '', + 1_000_000, + STATIC_A_TOKEN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); } } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol index 52f66f5d6..2fc3e446d 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -19,7 +19,7 @@ contract AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_Test is P event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); function setUp() public { - vm.createSelectFork(vm.rpcUrl('avalanche'), 44512842); + vm.createSelectFork(vm.rpcUrl('avalanche'), 45718364); proposal = new AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422(); cancelRobotsProposal = new AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422(); @@ -39,7 +39,7 @@ contract AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_Test is P /** * @dev executes the generic test suite including e2e and config snapshots */ - function test_defaultProposalExecutionX() public { + function test_defaultProposalExecution() public { defaultTest( 'AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422', AaveV3Avalanche.POOL, @@ -62,6 +62,26 @@ contract AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422_Test is P uint96(proposal.VOTING_CHAIN_ROBOT_LINK_AMOUNT()) ); + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.PROOF_OF_RESERVE_ROBOT_ADDRESS(), + uint96(proposal.PROOF_OF_RESERVE_ROBOT_LINK_AMOUNT()) + ); + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.PROOF_OF_RESERVE_ROBOT_ADDRESS(), + uint96(proposal.PROOF_OF_RESERVE_ROBOT_LINK_AMOUNT()) + ); + + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.STATIC_A_TOKEN_ROBOT_ADDRESS(), + uint96(proposal.STATIC_A_TOKEN_ROBOT_LINK_AMOUNT()) + ); + executePayload(vm, address(proposal)); } } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol index 140e69a9f..ecd6c57b4 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -7,12 +7,12 @@ import {IRootsConsumer} from './interfaces/IRootsConsumer.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; -import {AaveV2Ethereum, AaveV2EthereumAssets} from 'aave-address-book/AaveV2Ethereum.sol'; +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; /** * @title Migrate Robots to Chainlink Automation v2 * @author BGD Labs (@bgdlabs) - * - Discussion: TODO + * - Discussion: https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/36 */ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { using SafeERC20 for IERC20; @@ -30,7 +30,7 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos uint256 public constant OLD_GSM_SWAP_FREEZE_USDT_ROBOT_ID = 29419557335377754353590946220126755014551271053492007946914462953700619858182; - address public constant ROBOT_OPERATOR = 0x737806fe47FDBDEcBcB82dF7b89AA3D74AdadF62; + address public constant ROBOT_OPERATOR = 0x1cDF8879eC8bE012bA959EB515b11008E0cb6323; address public constant ROOTS_CONSUMER = 0x2fA6F0A65886123AFD24A575aE4554d0FCe8B577; address public constant GSM_SWAP_FREEZE_USDC_ROBOT_ADDRESS = @@ -43,12 +43,15 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos 0x7Ed0A6A294Cf085c90917c0ee1aa34e795932558; address public constant GAS_CAPPED_GOVERNANCE_CHAIN_ROBOT_ADDRESS = 0x1996c281235D99bB3c6B8d2afbEb8ac6c7A39C11; + address public constant GAS_CAPPED_STATIC_A_TOKEN_ROBOT_ADDRESS = + 0xda82148a3944BBe442116f41cDb329b0edF11d41; uint256 public constant GSM_SWAP_FREEZE_USDC_ROBOT_LINK_AMOUNT = 80 ether; uint256 public constant GSM_SWAP_FREEZE_USDT_ROBOT_LINK_AMOUNT = 80 ether; uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 1500 ether; uint256 public constant GOVERNANCE_CHAIN_ROBOT_LINK_AMOUNT = 2500 ether; uint256 public constant VOTING_CHAIN_ROBOT_LINK_AMOUNT = 400 ether; + uint256 public constant STATIC_A_TOKEN_ROBOT_LINK_AMOUNT = 200 ether; function execute() external { // cancel previous robots @@ -62,42 +65,46 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos GOVERNANCE_CHAIN_ROBOT_LINK_AMOUNT + VOTING_CHAIN_ROBOT_LINK_AMOUNT + GSM_SWAP_FREEZE_USDC_ROBOT_LINK_AMOUNT + - GSM_SWAP_FREEZE_USDT_ROBOT_LINK_AMOUNT; + GSM_SWAP_FREEZE_USDT_ROBOT_LINK_AMOUNT + + STATIC_A_TOKEN_ROBOT_LINK_AMOUNT; - AaveV2Ethereum.COLLECTOR.transfer( - AaveV2EthereumAssets.LINK_A_TOKEN, + AaveV3Ethereum.COLLECTOR.transfer( + AaveV3EthereumAssets.LINK_A_TOKEN, address(this), totalLinkAmount ); - AaveV2Ethereum.POOL.withdraw( - AaveV2EthereumAssets.LINK_UNDERLYING, + AaveV3Ethereum.POOL.withdraw( + AaveV3EthereumAssets.LINK_UNDERLYING, type(uint256).max, address(this) ); - uint256 linkBalance = IERC20(AaveV2EthereumAssets.LINK_UNDERLYING).balanceOf(address(this)); - IERC20(AaveV2EthereumAssets.LINK_UNDERLYING).forceApprove(ROBOT_OPERATOR, linkBalance); + uint256 linkBalance = IERC20(AaveV3EthereumAssets.LINK_UNDERLYING).balanceOf(address(this)); + IERC20(AaveV3EthereumAssets.LINK_UNDERLYING).forceApprove(ROBOT_OPERATOR, linkBalance); // register new robots IAaveCLRobotOperator(ROBOT_OPERATOR).register( - 'Execution Chain Robot', + 'Gas Capped Execution Chain Robot', GAS_CAPPED_EXECUTION_CHAIN_ROBOT_ADDRESS, + '', 5_000_000, EXECUTION_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), 0, '' ); IAaveCLRobotOperator(ROBOT_OPERATOR).register( - 'Governance Chain Robot', + 'Gas Capped Governance Chain Robot', GAS_CAPPED_GOVERNANCE_CHAIN_ROBOT_ADDRESS, + '', 5_000_000, GOVERNANCE_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), 0, '' ); IAaveCLRobotOperator(ROBOT_OPERATOR).register( - 'Voting Chain Robot', + 'Gas Capped Voting Chain Robot', GAS_CAPPED_VOTING_CHAIN_ROBOT_ADDRESS, + '', 5_000_000, VOTING_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), 0, @@ -106,6 +113,7 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos IAaveCLRobotOperator(ROBOT_OPERATOR).register( 'GHO GSM USDC OracleSwapFreezer', GSM_SWAP_FREEZE_USDC_ROBOT_ADDRESS, + '', 150_000, GSM_SWAP_FREEZE_USDC_ROBOT_LINK_AMOUNT.toUint96(), 0, @@ -114,8 +122,18 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos IAaveCLRobotOperator(ROBOT_OPERATOR).register( 'GHO GSM USDT OracleSwapFreezer', GSM_SWAP_FREEZE_USDT_ROBOT_ADDRESS, + '', 150_000, - IERC20(AaveV2EthereumAssets.LINK_UNDERLYING).balanceOf(address(this)).toUint96(), + GSM_SWAP_FREEZE_USDT_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'Gas Capped StaticAToken Rewards Robot', + GAS_CAPPED_STATIC_A_TOKEN_ROBOT_ADDRESS, + '', + 1_000_000, + IERC20(AaveV3EthereumAssets.LINK_UNDERLYING).balanceOf(address(this)).toUint96(), 0, '' ); diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol index 201e46443..b30a04ad3 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -24,7 +24,7 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pr 0x011824f238AEE05329213d5Ae029e899e5412343; function setUp() public { - vm.createSelectFork(vm.rpcUrl('mainnet'), 19709151); + vm.createSelectFork(vm.rpcUrl('mainnet'), 19917667); proposal = new AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422(); } @@ -104,6 +104,13 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pr uint96(proposal.GSM_SWAP_FREEZE_USDT_ROBOT_LINK_AMOUNT()) ); + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.GAS_CAPPED_STATIC_A_TOKEN_ROBOT_ADDRESS(), + uint96(proposal.STATIC_A_TOKEN_ROBOT_LINK_AMOUNT()) + ); + executePayload(vm, address(proposal)); } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol index 9e286b3f4..5ab0b534c 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -11,7 +11,7 @@ import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; /** * @title Migrate Robots to Chainlink Automation v2 * @author BGD Labs (@bgdlabs) - * - Snapshot: TODO + * - Snapshot: https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/36 */ contract AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { using SafeERC20 for IERC20; @@ -21,9 +21,12 @@ contract AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos uint256 public constant OLD_EXECUTION_CHAIN_ROBOT_ID = 98991846084053478582099013231511635776224064505474556907242977329597039975307; - address public constant ROBOT_OPERATOR = 0x34F098B9B67B147d8a679476bc89982DdE525F8c; + address public constant ROBOT_OPERATOR = 0x55Cf9583D7D30DC4936bAee1f747591dBECe5df7; address public constant EXECUTION_CHAIN_ROBOT_ADDRESS = 0xa0195539e21A6553243344A3BE6b874B5d3EC7b9; + address public constant STATIC_A_TOKEN_ROBOT_ADDRESS = 0x861Be72d464b6F1C99880B9bE476D40e8F9b5Bce; + + uint256 public constant STATIC_A_TOKEN_ROBOT_LINK_AMOUNT = 30 ether; uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; function execute() external { @@ -31,24 +34,38 @@ contract AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_EXECUTION_CHAIN_ROBOT_ID); AaveV3Optimism.COLLECTOR.transfer( - AaveV3OptimismAssets.LINK_UNDERLYING, + AaveV3OptimismAssets.LINK_A_TOKEN, address(this), - EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + STATIC_A_TOKEN_ROBOT_LINK_AMOUNT ); - IERC20(AaveV3OptimismAssets.LINK_UNDERLYING).forceApprove( - ROBOT_OPERATOR, - EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + AaveV3Optimism.POOL.withdraw( + AaveV3OptimismAssets.LINK_UNDERLYING, + type(uint256).max, + address(this) ); + uint256 linkBalance = IERC20(AaveV3OptimismAssets.LINK_UNDERLYING).balanceOf(address(this)); + IERC20(AaveV3OptimismAssets.LINK_UNDERLYING).forceApprove(ROBOT_OPERATOR, linkBalance); + // register new robot IAaveCLRobotOperator(ROBOT_OPERATOR).register( 'Execution Chain Robot', EXECUTION_CHAIN_ROBOT_ADDRESS, + '', 5_000_000, EXECUTION_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), 0, '' ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'StaticAToken Rewards Robot', + STATIC_A_TOKEN_ROBOT_ADDRESS, + '', + 1_000_000, + STATIC_A_TOKEN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); } } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol index a7e0da940..726263ddc 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -2,9 +2,7 @@ pragma solidity ^0.8.0; import {AaveV3Optimism} from 'aave-address-book/AaveV3Optimism.sol'; - -import 'forge-std/Test.sol'; -import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/ProtocolV3TestBase.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; import {AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; /** @@ -18,7 +16,7 @@ contract AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pr event KeeperCancelled(uint256 indexed id, address indexed upkeep); function setUp() public { - vm.createSelectFork(vm.rpcUrl('optimism'), 119084285); + vm.createSelectFork(vm.rpcUrl('optimism'), 120310846); proposal = new AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422(); } @@ -49,6 +47,13 @@ contract AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pr uint96(proposal.EXECUTION_CHAIN_ROBOT_LINK_AMOUNT()) ); + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.STATIC_A_TOKEN_ROBOT_ADDRESS(), + uint96(proposal.STATIC_A_TOKEN_ROBOT_LINK_AMOUNT()) + ); + executePayload(vm, address(proposal)); } } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol index f4cddcf93..6505d45de 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -13,37 +13,44 @@ import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; * @author BGD Labs (@bgdlabs) * @notice This payload should be executed after the payload for cancelling old robots has been executed and link tokens * have been transferred to the collector by calling the `withdrawLink()` method on the old operator contract. - * - Discussion: TODO + * - Discussion: https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/36 */ contract AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposalGenericExecutor { using SafeERC20 for IERC20; using SafeCast for uint256; address public constant LINK_TOKEN = 0xb0897686c545045aFc77CF20eC7A532E3120E0F1; - address public constant ROBOT_OPERATOR = 0x4F341c371ab7E2F34A4d3EAd5b2C30F0A6BDC7d0; + address public constant ROBOT_OPERATOR = 0xB4C212f5cD17E200019b07e6B1fDf124d35DBCf5; address public constant EXECUTION_CHAIN_ROBOT_ADDRESS = 0x249396a890F89D47F89326d7EE116b1d374Fb3A9; address public constant VOTING_CHAIN_ROBOT_ADDRESS = 0xbe7998712402B6A63975515A532Ce503437998b7; + address public constant STATIC_A_TOKEN_ROBOT_ADDRESS = 0x855FbD0D57fF5B1e8263e3cCDf3384545fbaF863; uint256 public constant EXECUTION_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; uint256 public constant VOTING_CHAIN_ROBOT_LINK_AMOUNT = 45 ether; + uint256 public constant STATIC_A_TOKEN_ROBOT_LINK_AMOUNT = 25 ether; function execute() external { AaveV3Polygon.COLLECTOR.transfer( LINK_TOKEN, address(this), - EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + VOTING_CHAIN_ROBOT_LINK_AMOUNT + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + + VOTING_CHAIN_ROBOT_LINK_AMOUNT + + STATIC_A_TOKEN_ROBOT_LINK_AMOUNT ); IERC20(LINK_TOKEN).forceApprove( ROBOT_OPERATOR, - EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + VOTING_CHAIN_ROBOT_LINK_AMOUNT + EXECUTION_CHAIN_ROBOT_LINK_AMOUNT + + VOTING_CHAIN_ROBOT_LINK_AMOUNT + + STATIC_A_TOKEN_ROBOT_LINK_AMOUNT ); // register new robots IAaveCLRobotOperator(ROBOT_OPERATOR).register( 'Execution Chain Robot', EXECUTION_CHAIN_ROBOT_ADDRESS, + '', 5_000_000, EXECUTION_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), 0, @@ -52,10 +59,20 @@ contract AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422 is IProposa IAaveCLRobotOperator(ROBOT_OPERATOR).register( 'Voting Chain Robot', VOTING_CHAIN_ROBOT_ADDRESS, + '', 5_000_000, VOTING_CHAIN_ROBOT_LINK_AMOUNT.toUint96(), 0, '' ); + IAaveCLRobotOperator(ROBOT_OPERATOR).register( + 'StaticAToken Rewards Robot', + STATIC_A_TOKEN_ROBOT_ADDRESS, + '', + 1_000_000, + STATIC_A_TOKEN_ROBOT_LINK_AMOUNT.toUint96(), + 0, + '' + ); } } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol index 08b9edf8b..4a5031c9e 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -18,7 +18,7 @@ contract AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pro event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); function setUp() public { - vm.createSelectFork(vm.rpcUrl('polygon'), 56113531); + vm.createSelectFork(vm.rpcUrl('polygon'), 57189258); proposal = new AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422(); cancelRobotsProposal = new AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422(); @@ -62,6 +62,13 @@ contract AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pro uint96(proposal.VOTING_CHAIN_ROBOT_LINK_AMOUNT()) ); + vm.expectEmit(false, true, true, true); + emit KeeperRegistered( + uint256(0), + proposal.STATIC_A_TOKEN_ROBOT_ADDRESS(), + uint96(proposal.STATIC_A_TOKEN_ROBOT_LINK_AMOUNT()) + ); + executePayload(vm, address(proposal)); } } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md index 199799162..a07247ff0 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md @@ -1,18 +1,20 @@ --- title: "Migrate Robots to Chainlink Automation v2" author: "BGD Labs (@bgdlabs)" -discussions: "" +discussions: "https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/36" --- ## Simple Summary -Proposal to migrate existing Aave robots from chainlink automation `v1.2` to `v2.1`. For governance v3 robots on ethereum, we also introduce gas-capped robots in order to limit execution based on network gas price. +Proposal to migrate existing Aave robots from chainlink automation `v1.2` to `v2.1`. For governance v3 robots on ethereum, we introduce gas-capped robots in order to limit execution based on network gas price. We also activate robots for refreshing liquidity mining rewards for static-a-tokens. ## Motivation With the release of Chainlink automation `v2.1`, we think its a good idea to update the Aave Robot existing infrastructure to the latest `v2.1` version. In addition, as an effort to reduce the cost spent in gas in times of high gas prices, we also introduce gas-capped robots on mainnet which will be activated via this proposal. +Currently when a liquidity mining reward is added after static-a-token creation, it needs to be registered manually on the token via the permissionless `refreshRewardTokens()` method. As this process is not currently automated users might be missing out on rewards until the method is called, so now we introduce the robot for static-a-token to automate this process. + ## Specification For the migration, the robots registered on the previous robot operator contract will be cancelled and new robots will be registered using an updated robot operator contract, compatible with the newer version of chainlink automation `v2.1`. @@ -21,29 +23,36 @@ The robots will be cancelled by calling the `cancel()` method by the payload on On the newer robot operator, the payload will call the `register()` method to register the keepers with the newer chainlink automation registry supporting `v2.1`. -_Note: All aave governance v3 robots along with robots used for gsm swap freeze will be migrated via this proposal_ +_Note: All aave governance v3 robots along with robots used for gsm swap freeze and Proof of Reserve will be migrated via this proposal and will use the same contract as before except the one's mentioned below_ | | Deployed AaveCLRobotOperator | | --------- | -------------------------------------------------------------------------------------------------------------------------------- | -| Mainnet | [0x737806fe47FDBDEcBcB82dF7b89AA3D74AdadF62](https://etherscan.io/address/0x737806fe47FDBDEcBcB82dF7b89AA3D74AdadF62) | -| Polygon | [0x4F341c371ab7E2F34A4d3EAd5b2C30F0A6BDC7d0](https://polygonscan.com/address/0x4F341c371ab7E2F34A4d3EAd5b2C30F0A6BDC7d0) | -| Avalanche | [0x023640D7CDa2E2063546A45005393756B9b4ac9D](https://snowscan.xyz/address/0x023640D7CDa2E2063546A45005393756B9b4ac9D) | -| Optimism | [0x34F098B9B67B147d8a679476bc89982DdE525F8c](https://optimistic.etherscan.io/address/0x34F098B9B67B147d8a679476bc89982DdE525F8c) | -| Arbitrum | [0xAa589e4c7539e8D7465c36578098499F0b2BBd12](https://arbiscan.io/address/0xAa589e4c7539e8D7465c36578098499F0b2BBd12) | -| Base | [0xBAC282927CE0cFD1698C5853dCED2eEf9F62a8bb](https://basescan.org/address/0xBAC282927CE0cFD1698C5853dCED2eEf9F62a8bb) | -| BNB | [0xf092900FC8D4962412eC784d7Fbc92a1F69c47bC](https://bscscan.com/address/0xf092900FC8D4962412eC784d7Fbc92a1F69c47bC) | - -| | Deployed Gas Capped Robots | -| --------------------------- | --------------------------------------------------------------------------------------------------------------------- | -| Gas Capped Governance Robot | [0x1996c281235D99bB3c6B8d2afbEb8ac6c7A39C11](https://etherscan.io/address/0x1996c281235D99bB3c6B8d2afbEb8ac6c7A39C11) | -| Gas Capped Voting Robot | [0x7Ed0A6A294Cf085c90917c0ee1aa34e795932558](https://etherscan.io/address/0x7Ed0A6A294Cf085c90917c0ee1aa34e795932558) | -| Gas Capped Execution Robot | [0xBa37F9eDC52f57caFA3a13ddfD655797Cc4FE257](https://etherscan.io/address/0xBa37F9eDC52f57caFA3a13ddfD655797Cc4FE257) | +| Mainnet | [0x1cDF8879eC8bE012bA959EB515b11008E0cb6323](https://etherscan.io/address/0x1cDF8879eC8bE012bA959EB515b11008E0cb6323) | +| Polygon | [0xB4C212f5cD17E200019b07e6B1fDf124d35DBCf5](https://polygonscan.com/address/0xB4C212f5cD17E200019b07e6B1fDf124d35DBCf5) | +| Avalanche | [0x06d958772304e7220fc3E463756CE01Ed0D24db2](https://snowscan.xyz/address/0x06d958772304e7220fc3E463756CE01Ed0D24db2) | +| Optimism | [0x55Cf9583D7D30DC4936bAee1f747591dBECe5df7](https://optimistic.etherscan.io/address/0x55Cf9583D7D30DC4936bAee1f747591dBECe5df7) | +| Arbitrum | [0xaa944aD95e51CB83C1f35FAEEDfC7d2c31B0BB4d](https://arbiscan.io/address/0xaa944aD95e51CB83C1f35FAEEDfC7d2c31B0BB4d) | +| Base | [0x88db99eeBb390a2a4DcAC2E1DDb09c07E911C5C3](https://basescan.org/address/0x88db99eeBb390a2a4DcAC2E1DDb09c07E911C5C3) | +| BNB | [0x51Bd3d6011Dd0BD88Ee1bEA1a67be799A6A09D79](https://bscscan.com/address/0x51Bd3d6011Dd0BD88Ee1bEA1a67be799A6A09D79) | + +| | Deployed Robots | +| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| Mainnet Gas Capped Governance Robot | [0x1996c281235D99bB3c6B8d2afbEb8ac6c7A39C11](https://etherscan.io/address/0x1996c281235D99bB3c6B8d2afbEb8ac6c7A39C11) | +| Mainnet Gas Capped Voting Robot | [0x7Ed0A6A294Cf085c90917c0ee1aa34e795932558](https://etherscan.io/address/0x7Ed0A6A294Cf085c90917c0ee1aa34e795932558) | +| Mainnet Gas Capped Execution Robot | [0xBa37F9eDC52f57caFA3a13ddfD655797Cc4FE257](https://etherscan.io/address/0xBa37F9eDC52f57caFA3a13ddfD655797Cc4FE257) | +| Mainnet Gas Capped StaticAToken Rewards Robot | [0xda82148a3944BBe442116f41cDb329b0edF11d41](https://etherscan.io/address/0xda82148a3944BBe442116f41cDb329b0edF11d41) | +| Polygon StaticAToken Rewards Robot | [0x855FbD0D57fF5B1e8263e3cCDf3384545fbaF863](https://polygonscan.com/address/0x855FbD0D57fF5B1e8263e3cCDf3384545fbaF863) | +| Avalanche StaticAToken Rewards Robot | [0x8aD3f00e91F0a3Ad8b0dF897c19EC345EaB761c4](https://snowscan.xyz/address/0x8aD3f00e91F0a3Ad8b0dF897c19EC345EaB761c4) | +| Optimism StaticAToken Rewards Robot | [0x861Be72d464b6F1C99880B9bE476D40e8F9b5Bce](https://optimistic.etherscan.io/address/0x861Be72d464b6F1C99880B9bE476D40e8F9b5Bce) | +| Arbitrum StaticAToken Rewards Robot | [0x0451f67bA61966C346daBAbB50a30Cc6A9A67C69](https://arbiscan.io/address/0x0451f67bA61966C346daBAbB50a30Cc6A9A67C69) | +| Base StaticAToken Rewards Robot | [0xad87684D27e6e58F055E6878A9F11F8c52A5b0F5](https://basescan.org/address/0xad87684D27e6e58F055E6878A9F11F8c52A5b0F5) | +| BNB StaticAToken Rewards Robot | [0x020E452b463568f55BAc6Dc5aFC8F0B62Ea5f0f3](https://bscscan.com/address/0x020E452b463568f55BAc6Dc5aFC8F0B62Ea5f0f3) | ## References - Implementation: [AaveV2Polygon](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV2Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Polygon](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Optimism](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.sol), [AaveV3Arbitrum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.sol) - Tests: [AaveV2Polygon](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV2Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Polygon](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Avalanche](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Optimism](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol), [AaveV3Arbitrum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol) -- [Discussion](TODO) +- [Discussion](https://governance.aave.com/t/bgd-technical-maintenance-proposals/15274/36) ## Copyright diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol index 8b2317692..50c88477b 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol @@ -108,6 +108,7 @@ interface IAaveCLRobotOperator { * @notice method called by owner to register the automation robot keeper. * @param name name of keeper. * @param upkeepContract upkeepContract of the keeper. + * @param upkeepCheckData checkData of the keeper which get passed to the checkUpkeep. * @param gasLimit max gasLimit which the chainlink automation node can execute for the automation. * @param amountToFund amount of link to fund the keeper with. * @param triggerType type of robot keeper to register, 0 for conditional and 1 for event log based. @@ -115,12 +116,13 @@ interface IAaveCLRobotOperator { * @return chainlink id for the registered keeper. **/ function register( - string memory name, + string calldata name, address upkeepContract, + bytes calldata upkeepCheckData, uint32 gasLimit, uint96 amountToFund, uint8 triggerType, - bytes memory triggerConfig + bytes calldata triggerConfig ) external returns (uint256); /** From 0b97ef45bbccaabf5007936ec55880b9cd906ef9 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Wed, 22 May 2024 21:24:01 +0530 Subject: [PATCH 7/9] feat: refill ccc with 1 eth --- ...teRobotsToChainlinkAutomationV2_20240422.sol | 17 +++++++++++++++++ ...RobotsToChainlinkAutomationV2_20240422.t.sol | 9 +++++++++ .../MigrateRobotsToChainlinkAutomationV2.md | 2 ++ .../interfaces/IWETH.sol | 12 ++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IWETH.sol diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol index ecd6c57b4..3afffb26d 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol @@ -4,9 +4,11 @@ pragma solidity ^0.8.0; import {IProposalGenericExecutor} from 'aave-helpers/interfaces/IProposalGenericExecutor.sol'; import {IAaveCLRobotOperator} from './interfaces/IAaveCLRobotOperator.sol'; import {IRootsConsumer} from './interfaces/IRootsConsumer.sol'; +import {IWETH} from './interfaces/IWETH.sol'; import {IERC20} from 'solidity-utils/contracts/oz-common/interfaces/IERC20.sol'; import {SafeERC20} from 'solidity-utils/contracts/oz-common/SafeERC20.sol'; import {SafeCast} from 'solidity-utils/contracts/oz-common/SafeCast.sol'; +import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; /** @@ -18,6 +20,8 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos using SafeERC20 for IERC20; using SafeCast for uint256; + error FailedToSendETH(); + address public constant OLD_ROBOT_OPERATOR = 0x020E452b463568f55BAc6Dc5aFC8F0B62Ea5f0f3; uint256 public constant OLD_EXECUTION_CHAIN_ROBOT_ID = 103962992988872542945147446194468190544109628047207929929141163121857186570465; @@ -52,8 +56,21 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 is IPropos uint256 public constant GOVERNANCE_CHAIN_ROBOT_LINK_AMOUNT = 2500 ether; uint256 public constant VOTING_CHAIN_ROBOT_LINK_AMOUNT = 400 ether; uint256 public constant STATIC_A_TOKEN_ROBOT_LINK_AMOUNT = 200 ether; + uint256 public constant CROSS_CHAIN_CONTROLLER_ETH_AMOUNT = 1 ether; function execute() external { + // refill cross-chain-controller with ETH + AaveV3Ethereum.COLLECTOR.transfer( + AaveV3EthereumAssets.WETH_UNDERLYING, + address(this), + CROSS_CHAIN_CONTROLLER_ETH_AMOUNT + ); + IWETH(AaveV3EthereumAssets.WETH_UNDERLYING).withdraw(CROSS_CHAIN_CONTROLLER_ETH_AMOUNT); + (bool status, ) = GovernanceV3Ethereum.CROSS_CHAIN_CONTROLLER.call{ + value: CROSS_CHAIN_CONTROLLER_ETH_AMOUNT + }(''); + if (!status) revert FailedToSendETH(); + // cancel previous robots IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_GSM_SWAP_FREEZE_USDC_ROBOT_ID); IAaveCLRobotOperator(OLD_ROBOT_OPERATOR).cancel(OLD_GSM_SWAP_FREEZE_USDT_ROBOT_ID); diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol index b30a04ad3..fbf7e7e43 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.t.sol @@ -5,6 +5,7 @@ import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol'; import {IRootsConsumer} from './interfaces/IRootsConsumer.sol'; import {ProtocolV3TestBase} from 'aave-helpers/ProtocolV3TestBase.sol'; import {AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422} from './AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422.sol'; +import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; /** * @dev Test for AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422 @@ -122,4 +123,12 @@ contract AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422_Test is Pr proposal.GAS_CAPPED_VOTING_CHAIN_ROBOT_ADDRESS() ); } + + function test_crossChainControllerETHRefill() public { + uint256 beforeBalance = GovernanceV3Ethereum.CROSS_CHAIN_CONTROLLER.balance; + executePayload(vm, address(proposal)); + uint256 afterBalance = GovernanceV3Ethereum.CROSS_CHAIN_CONTROLLER.balance; + + assertEq(afterBalance - beforeBalance, proposal.CROSS_CHAIN_CONTROLLER_ETH_AMOUNT()); + } } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md index a07247ff0..255b38c88 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2.md @@ -23,6 +23,8 @@ The robots will be cancelled by calling the `cancel()` method by the payload on On the newer robot operator, the payload will call the `register()` method to register the keepers with the newer chainlink automation registry supporting `v2.1`. +The proposal also refills the cross-chain-controller contract (part of aDI) on mainnet with 1 ethereum from the collector. + _Note: All aave governance v3 robots along with robots used for gsm swap freeze and Proof of Reserve will be migrated via this proposal and will use the same contract as before except the one's mentioned below_ | | Deployed AaveCLRobotOperator | diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IWETH.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IWETH.sol new file mode 100644 index 000000000..98281d0ac --- /dev/null +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IWETH.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IWETH { + function deposit() external payable; + + function withdraw(uint256) external; + + function approve(address guy, uint256 wad) external returns (bool); + + function transferFrom(address src, address dst, uint256 wad) external returns (bool); +} From 78bcf0c136bb158514ee1564108c32f7cbb0f56c Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Thu, 23 May 2024 21:30:29 +0530 Subject: [PATCH 8/9] fix: deploy script --- ...botsToChainlinkAutomationV2_20240422.s.sol | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol index d834bbaf8..978e7285a 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/MigrateRobotsToChainlinkAutomationV2_20240422.s.sol @@ -26,14 +26,9 @@ contract DeployPolygon is PolygonScript { type(AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode ); - // compose action - IPayloadsControllerCore.ExecutionAction[] - memory actions = new IPayloadsControllerCore.ExecutionAction[](2); - actions[0] = GovV3Helpers.buildAction(payload0); - actions[1] = GovV3Helpers.buildAction(payload1); - // register action at payloadsController - GovV3Helpers.createPayload(actions); + GovV3Helpers.createPayload(GovV3Helpers.buildAction(payload0)); + GovV3Helpers.createPayload(GovV3Helpers.buildAction(payload1)); } } @@ -52,14 +47,9 @@ contract DeployAvalanche is AvalancheScript { type(AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode ); - // compose action - IPayloadsControllerCore.ExecutionAction[] - memory actions = new IPayloadsControllerCore.ExecutionAction[](2); - actions[0] = GovV3Helpers.buildAction(payload0); - actions[1] = GovV3Helpers.buildAction(payload1); - // register action at payloadsController - GovV3Helpers.createPayload(actions); + GovV3Helpers.createPayload(GovV3Helpers.buildAction(payload0)); + GovV3Helpers.createPayload(GovV3Helpers.buildAction(payload1)); } } @@ -136,49 +126,57 @@ contract DeployArbitrum is ArbitrumScript { contract CreateProposal is EthereumScript { function run() external { // create payloads - PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](5); + PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](7); // compose actions for validation IPayloadsControllerCore.ExecutionAction[] - memory actionsPolygon = new IPayloadsControllerCore.ExecutionAction[](2); - actionsPolygon[0] = GovV3Helpers.buildAction( + memory actionsPolygonOne = new IPayloadsControllerCore.ExecutionAction[](1); + actionsPolygonOne[0] = GovV3Helpers.buildAction( type(AaveV2Polygon_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode ); - actionsPolygon[1] = GovV3Helpers.buildAction( + payloads[0] = GovV3Helpers.buildPolygonPayload(vm, actionsPolygonOne); + + IPayloadsControllerCore.ExecutionAction[] + memory actionsPolygonTwo = new IPayloadsControllerCore.ExecutionAction[](1); + actionsPolygonTwo[0] = GovV3Helpers.buildAction( type(AaveV3Polygon_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode ); - payloads[0] = GovV3Helpers.buildPolygonPayload(vm, actionsPolygon); + payloads[1] = GovV3Helpers.buildPolygonPayload(vm, actionsPolygonTwo); IPayloadsControllerCore.ExecutionAction[] - memory actionsAvalanche = new IPayloadsControllerCore.ExecutionAction[](2); - actionsAvalanche[0] = GovV3Helpers.buildAction( + memory actionsAvalancheOne = new IPayloadsControllerCore.ExecutionAction[](1); + actionsAvalancheOne[0] = GovV3Helpers.buildAction( type(AaveV2Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode ); - actionsAvalanche[1] = GovV3Helpers.buildAction( + payloads[2] = GovV3Helpers.buildAvalanchePayload(vm, actionsAvalancheOne); + + IPayloadsControllerCore.ExecutionAction[] + memory actionsAvalancheTwo = new IPayloadsControllerCore.ExecutionAction[](1); + actionsAvalancheTwo[0] = GovV3Helpers.buildAction( type(AaveV3Avalanche_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode ); - payloads[1] = GovV3Helpers.buildAvalanchePayload(vm, actionsAvalanche); + payloads[3] = GovV3Helpers.buildAvalanchePayload(vm, actionsAvalancheTwo); IPayloadsControllerCore.ExecutionAction[] memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1); actionsEthereum[0] = GovV3Helpers.buildAction( type(AaveV3Ethereum_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode ); - payloads[2] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); + payloads[4] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); IPayloadsControllerCore.ExecutionAction[] memory actionsOptimism = new IPayloadsControllerCore.ExecutionAction[](1); actionsOptimism[0] = GovV3Helpers.buildAction( type(AaveV3Optimism_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode ); - payloads[3] = GovV3Helpers.buildOptimismPayload(vm, actionsOptimism); + payloads[5] = GovV3Helpers.buildOptimismPayload(vm, actionsOptimism); IPayloadsControllerCore.ExecutionAction[] memory actionsArbitrum = new IPayloadsControllerCore.ExecutionAction[](1); actionsArbitrum[0] = GovV3Helpers.buildAction( type(AaveV3Arbitrum_MigrateRobotsToChainlinkAutomationV2_20240422).creationCode ); - payloads[4] = GovV3Helpers.buildArbitrumPayload(vm, actionsArbitrum); + payloads[6] = GovV3Helpers.buildArbitrumPayload(vm, actionsArbitrum); // create proposal vm.startBroadcast(); From 098d9db5a8d6228d5c8ca72e02e8a116f34ff115 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 24 May 2024 19:10:06 +0530 Subject: [PATCH 9/9] chore: cleanup interfaces --- .../interfaces/ArbSys.sol | 115 ---------- .../interfaces/IAaveCLRobotOperator.sol | 210 ------------------ .../interfaces/IRootsConsumer.sol | 116 ---------- .../interfaces/IWETH.sol | 6 - 4 files changed, 447 deletions(-) diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/ArbSys.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/ArbSys.sol index c7d285a97..9bcca96c6 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/ArbSys.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/ArbSys.sol @@ -21,119 +21,4 @@ interface ArbSys { * @return block hash */ function arbBlockHash(uint256 arbBlockNum) external view returns (bytes32); - - /** - * @notice Gets the rollup's unique chain identifier - * @return Chain identifier as int - */ - function arbChainID() external view returns (uint256); - - /** - * @notice Get internal version number identifying an ArbOS build - * @return version number as int - */ - function arbOSVersion() external view returns (uint256); - - /** - * @notice Returns 0 since Nitro has no concept of storage gas - * @return uint 0 - */ - function getStorageGasAvailable() external view returns (uint256); - - /** - * @notice (deprecated) check if current call is top level (meaning it was triggered by an EoA or a L1 contract) - * @dev this call has been deprecated and may be removed in a future release - * @return true if current execution frame is not a call by another L2 contract - */ - function isTopLevelCall() external view returns (bool); - - /** - * @notice map L1 sender contract address to its L2 alias - * @param sender sender address - * @param unused argument no longer used - * @return aliased sender address - */ - function mapL1SenderContractAddressToL2Alias( - address sender, - address unused - ) external pure returns (address); - - /** - * @notice check if the caller (of this caller of this) is an aliased L1 contract address - * @return true iff the caller's address is an alias for an L1 contract address - */ - function wasMyCallersAddressAliased() external view returns (bool); - - /** - * @notice return the address of the caller (of this caller of this), without applying L1 contract address aliasing - * @return address of the caller's caller, without applying L1 contract address aliasing - */ - function myCallersAddressWithoutAliasing() external view returns (address); - - /** - * @notice Send given amount of Eth to dest from sender. - * This is a convenience function, which is equivalent to calling sendTxToL1 with empty data. - * @param destination recipient address on L1 - * @return unique identifier for this L2-to-L1 transaction. - */ - function withdrawEth(address destination) external payable returns (uint256); - - /** - * @notice Send a transaction to L1 - * @dev it is not possible to execute on the L1 any L2-to-L1 transaction which contains data - * to a contract address without any code (as enforced by the Bridge contract). - * @param destination recipient address on L1 - * @param data (optional) calldata for L1 contract call - * @return a unique identifier for this L2-to-L1 transaction. - */ - function sendTxToL1(address destination, bytes calldata data) external payable returns (uint256); - - /** - * @notice Get send Merkle tree state - * @return size number of sends in the history - * @return root root hash of the send history - * @return partials hashes of partial subtrees in the send history tree - */ - function sendMerkleTreeState() - external - view - returns (uint256 size, bytes32 root, bytes32[] memory partials); - - /** - * @notice creates a send txn from L2 to L1 - * @param position = (level << 192) + leaf = (0 << 192) + leaf = leaf - */ - event L2ToL1Tx( - address caller, - address indexed destination, - uint256 indexed hash, - uint256 indexed position, - uint256 arbBlockNum, - uint256 ethBlockNum, - uint256 timestamp, - uint256 callvalue, - bytes data - ); - - /// @dev DEPRECATED in favour of the new L2ToL1Tx event above after the nitro upgrade - event L2ToL1Transaction( - address caller, - address indexed destination, - uint256 indexed uniqueId, - uint256 indexed batchNumber, - uint256 indexInBatch, - uint256 arbBlockNum, - uint256 ethBlockNum, - uint256 timestamp, - uint256 callvalue, - bytes data - ); - - /** - * @notice logs a merkle branch for proof synthesis - * @param reserved an index meant only to align the 4th index with L2ToL1Transaction's 4th event - * @param hash the merkle hash - * @param position = (level << 192) + leaf - */ - event SendMerkleUpdate(uint256 indexed reserved, bytes32 indexed hash, uint256 indexed position); } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol index 50c88477b..c1e97a7e6 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IAaveCLRobotOperator.sol @@ -7,103 +7,6 @@ pragma solidity ^0.8.0; * @notice Defines the interface for the robot operator contract to perform admin actions on the automation keepers. **/ interface IAaveCLRobotOperator { - /** - * @dev Emitted when a keeper is registered using the operator contract. - * @param id id of the keeper registered. - * @param upkeep address of the keeper contract. - * @param amount amount of link the keeper has been registered with. - */ - event KeeperRegistered(uint256 indexed id, address indexed upkeep, uint96 indexed amount); - - /** - * @dev Emitted when a keeper is cancelled using the operator contract. - * @param id id of the keeper cancelled. - * @param upkeep address of the keeper contract. - */ - event KeeperCancelled(uint256 indexed id, address indexed upkeep); - - /** - * @dev Emitted when a keeper is already cancelled, and link is being withdrawn using the operator contract. - * @param id id of the keeper to withdraw link from. - * @param upkeep address of the keeper contract. - * @param to address where link needs to be withdrawn to. - */ - event LinkWithdrawn(uint256 indexed id, address indexed upkeep, address indexed to); - - /** - * @dev Emitted when a keeper is refilled using the operator contract. - * @param id id of the keeper which has been refilled. - * @param from address which refilled the keeper. - * @param amount amount of link which has been refilled for the keeper. - */ - event KeeperRefilled(uint256 indexed id, address indexed from, uint96 indexed amount); - - /** - * @dev Emitted when a keeper is paused using the operator contract. - * @param id id of the keeper which has been paused. - */ - event KeeperPaused(uint256 indexed id); - - /** - * @dev Emitted when a keeper is unpaused using the operator contract. - * @param id id of the keeper which has been unpaused. - */ - event KeeperUnpaused(uint256 indexed id); - - /** - * @dev Emitted when the link withdraw address has been changed of the keeper. - * @param newWithdrawAddress address of the new withdraw address where link will be withdrawn to. - */ - event WithdrawAddressSet(address indexed newWithdrawAddress); - - /** - * @dev Emitted when gas limit is configured using the operator contract. - * @param id id of the keeper for which gas limit has been configured. - * @param upkeep address of the keeper contract. - * @param gasLimit max gas limit which has been configured for the keeper. - */ - event GasLimitSet(uint256 indexed id, address indexed upkeep, uint32 indexed gasLimit); - - /** - * @dev Emitted when trigger config is configured for a log type robot using the operator contract. - * @param id id of the keeper for which trigger config has been configured. - */ - event TriggerConfigSet(uint256 indexed id); - - /** - * @dev Emitted when a new chainlink keeper registry is set on the operator contract. - * @param newKeeperRegistry address of the new chainlink keeper registry contract. - */ - event KeeperRegistrySet(address indexed newKeeperRegistry); - - /** - * @dev Emitted when a new chainlink keeper registrar is set on the operator contract. - * @param newKeeperRegistrar address of the new chainlink keeper registrar contract. - */ - event KeeperRegistrarSet(address indexed newKeeperRegistrar); - - /** - * @dev Emitted when a the keepers are migrated to a new chainlink keeper registry contract. - * @param ids array of ids all the chainlink keepers to migrate. - * @param newKeeperRegistry address of the new chainlink keeper registry contract to migrate to. - * @param newKeeperRegistrar address of the new chainlink keeper registrar contract associated with the registry. - */ - event KeepersMigrated( - uint256[] indexed ids, - address indexed newKeeperRegistry, - address indexed newKeeperRegistrar - ); - - /** - * @notice holds the keeper info registered via the operator. - * @param upkeep address of the keeper contract registered. - * @param name name of the registered keeper. - */ - struct KeeperInfo { - address upkeep; - string name; - } - /** * @notice method called by owner to register the automation robot keeper. * @param name name of keeper. @@ -125,13 +28,6 @@ interface IAaveCLRobotOperator { bytes calldata triggerConfig ) external returns (uint256); - /** - * @notice method called to refill the keeper. - * @param id - id of the chainlink registered keeper to refill. - * @param amount - amount of LINK to refill the keeper with. - **/ - function refillKeeper(uint256 id, uint96 amount) external; - /** * @notice method called by the owner to cancel the automation robot keeper. * @param id - id of the chainlink registered keeper to cancel. @@ -144,110 +40,4 @@ interface IAaveCLRobotOperator { * @param id - id of the chainlink registered keeper to withdraw funds of. **/ function withdrawLink(uint256 id) external; - - /** - * @notice method called by the owner to migrate the keepers to a newer version of chainlink automation. - * @param newRegistry address of the new chainlink registry to migrate the keepers to. - * @param newRegistrar address of the new associated chainlink registrar of the new registry. - **/ - function migrate(address newRegistry, address newRegistrar) external; - - /** - * @notice method called by owner / robot guardian to pause the upkeep robot keeper. - * @param id - id of the chainlink registered keeper to pause. - **/ - function pause(uint256 id) external; - - /** - * @notice method called by owner / robot guardian to unpause the upkeep robot keeper. - * @param id - id of the chainlink registered keeper to unpause. - **/ - function unpause(uint256 id) external; - - /** - * @notice method to check if the keeper is paused or not. - * @param id - id of the chainlink registered keeper to check. - * @return true if the keeper is paused, false otherwise. - **/ - function isPaused(uint256 id) external returns (bool); - - /** - * @notice method called by owner / robot guardian to set the max gasLimit of upkeep robot keeper. - * @param id - id of the chainlink registered keeper to set the gasLimit. - * @param gasLimit max gasLimit which the chainlink automation node can execute. - **/ - function setGasLimit(uint256 id, uint32 gasLimit) external; - - /** - * @notice method called by owner to set the withdraw address when withdrawing excess link from the automation robot keeeper. - * @param withdrawAddress withdraw address to withdaw link to. - **/ - function setWithdrawAddress(address withdrawAddress) external; - - /** - * @notice method called by owner / guardian to set the trigger configuration for event log type robots. - * @param id - id of the chainlink registered keeper to set the trigger config. - * @param triggerConfig encoded data containing the configuration - * Ex: - * abi.encode( - * address contractAddress, (address that will be emitting the log) - * uint8 filterSelector, (denoting which topics apply to filter ex 000, 101, 111...only last 3 bits apply) - * bytes32 topic0, (signature of the emitted event) - * bytes32 topic1, (filter on indexed topic 1) - * bytes32 topic2, (filter on indexed topic 2) - * bytes32 topic3 (filter on indexed topic 3) - * ); - **/ - function setTriggerConfig(uint256 id, bytes calldata triggerConfig) external; - - /** - * @notice method called by owner to set the address of chainlink keeper registry contract. - * @param newRegistry address of the new chainlink keeper registry contract to set. - */ - function setRegistry(address newRegistry) external; - - /** - * @notice method called by owner to set the address of chainlink keeper registrar contract. - * @param newRegistrar address of the new chainlink keeper registrar contract to set. - */ - function setRegistrar(address newRegistrar) external; - - /** - * @notice method to get the withdraw address for the robot operator contract. - * @return withdraw address to send excess link to. - **/ - function getWithdrawAddress() external view returns (address); - - /** - * @notice method to get the keeper information registered via the operator. - * @param id - id of the chainlink registered keeper. - * @return Struct containing the following information about the keeper: - * - uint256 chainlink id of the registered keeper. - * - string name of the registered keeper. - **/ - function getKeeperInfo(uint256 id) external view returns (KeeperInfo memory); - - /** - * @notice method to get the address of chainlink keeper registry contract. - * @return keeper registry address. - */ - function getRegistry() external returns (address); - - /** - * @notice method to get the address of chainlink keeper registrar contract. - * @return keeper registrar address. - */ - function getRegistrar() external returns (address); - - /** - * @notice method to get the address of ERC-677 link token. - * @return link token address. - */ - function getLinkToken() external returns (address); - - /** - * @notice method to get of all the ids of keepers registered by the robot operator which have not been cancelled. - * @return array of registered keeper ids. - */ - function getKeepersList() external returns (uint256[] memory); } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IRootsConsumer.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IRootsConsumer.sol index a526d1319..88773244c 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IRootsConsumer.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IRootsConsumer.sol @@ -7,131 +7,15 @@ pragma solidity ^0.8.0; * @notice Defines the interface for the contract to fetch api response to register storage roots. **/ interface IRootsConsumer { - /** - * @notice Emitted when we get a response from chainlink api and the storage roots are registered to the data warehouse. - * @param requestId request id received by chainlink. - * @param blockHash block hash for which roots have beeen registered. - */ - event RootsRegisteredFulfilled(bytes32 indexed requestId, bytes32 indexed blockHash); - - /** - * @notice Emitted when we set a new api url to fetch the roots data. - * @param newApiUrl url of the new chainlink api request. - */ - event ApiUrlSet(string indexed newApiUrl); - - /** - * @notice Emitted when we set a new jobId of the chainlink operator. - * @param newJobId jobId which has been set. - */ - event JobIdSet(bytes32 indexed newJobId); - - /** - * @notice Emitted when we set a new fee to pay for the chainlink api request. - * @param newFee fee set for the api request. - */ - event FeeSet(uint256 indexed newFee); - - /** - * @notice Emitted when we set a new chainlink operator. - * @param newOperator address of the chainlink operator. - */ - event OperatorSet(address indexed newOperator); - - /** - * @notice Emitted when the link withdraw address has been changed of the consumer. - * @param newWithdrawAddress address of the new withdraw address where link will be withdrawn to. - */ - event WithdrawAddressSet(address indexed newWithdrawAddress); - - /** - * @notice Emitted when we set a new robot keeper. - * @param newRobotKeeper address of the new robot keeper. - */ - event RobotKeeperSet(address indexed newRobotKeeper); - - /** - * @notice Emitted when we send a request by the keeper to register the roots. - * @param blockHash blockHash for which the roots need to be registered. - * @param requestUrl url to request data needed to register the roots. - * @param fee fee paid to the chainlink operator for the request. - */ - event OperatorRequestSent( - bytes32 indexed blockHash, - string indexed requestUrl, - uint256 indexed fee - ); - - /** - * @notice method to request data needed to register roots via chainlink api. - * @param blockHash block hash for which roots needs to be registered. - **/ - function requestSubmitRoots(bytes32 blockHash) external; - - /** - * @notice method called by chainlink node operator containing the api response as encoded data, used for registering roots. - * @param requestId request id received by chainlink. - * @param response encoded data received as the api response which is used to register the roots. - **/ - function fulfillRegisterRoots(bytes32 requestId, bytes calldata response) external; - - /** - * @notice method called by the owner / robot guardian to change the chainlink operator. - * @param chainlinkOperator new operator for api requests. - **/ - function setOperator(address chainlinkOperator) external; - - /** - * @notice method called by the owner / robot guardian to change the fee paid to the operator. - * @param fee new fee paid to the operator. - **/ - function setFee(uint256 fee) external; - - /** - * @notice method called by the owner / robot guardian to change the api url we use to fetch data to register roots. - * @param api_url new api url to set. - **/ - function setApiUrl(string memory api_url) external; - - /** - * @notice method called by the owner / robot guardian to change the jobId of the operator. - * @param jobId new job id of the operator. - **/ - function setJobId(bytes32 jobId) external; - /** * @notice method called by owner / robot guardian to set the robot keeper which can request to submit roots. * @param robotKeeper new address of the robot keeper to set. **/ function setRobotKeeper(address robotKeeper) external; - /** - * @notice method to get the fee to be paid to the chainlink operator. - * @return operator fee. - */ - function getFee() external view returns (uint256); - - /** - * @notice method to get the job id of the chainlink operator. - * @return job id. - */ - function getJobId() external view returns (bytes32); - - /** - * @notice method to get the api url which returns the data to register storage roots. - * @return url of the backend api. - */ - function getApiUrl() external view returns (string memory); - /** * @notice method to get the the robot keeper which can request to submit roots. * @return address of the robot keeeper contract. */ function getRobotKeeper() external view returns (address); - - /** - * @notice method to get the address of the data warehouse contract. - * @return address of the data warehouse contract. - */ - function DATA_WAREHOUSE() external view returns (address); } diff --git a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IWETH.sol b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IWETH.sol index 98281d0ac..43585e230 100644 --- a/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IWETH.sol +++ b/src/20240422_Multi_MigrateRobotsToChainlinkAutomationV2/interfaces/IWETH.sol @@ -2,11 +2,5 @@ pragma solidity ^0.8.0; interface IWETH { - function deposit() external payable; - function withdraw(uint256) external; - - function approve(address guy, uint256 wad) external returns (bool); - - function transferFrom(address src, address dst, uint256 wad) external returns (bool); }