diff --git a/src/controllers/GovernanceTimelock.sol b/src/controllers/GovernanceTimelock.sol index 25e4194..18c6bc8 100644 --- a/src/controllers/GovernanceTimelock.sol +++ b/src/controllers/GovernanceTimelock.sol @@ -54,13 +54,17 @@ contract GovernanceTimelock is IGovernanceTimelock { ////////////////////////////////////////////////////////////////*/ /// @param _admin is the address of admin contract that schedule txs - constructor(address _admin) { + /// @param _delay is the initial delay + constructor(address _admin, uint256 _delay) { if (_admin == address(0)) { revert Error.ZERO_ADDRESS_INPUT(); } + _checkDelay(_delay); admin = _admin; emit AdminUpdated(address(0), _admin); + + delay = _delay; } /*///////////////////////////////////////////////////////////////// @@ -130,13 +134,7 @@ contract GovernanceTimelock is IGovernanceTimelock { /// @inheritdoc IGovernanceTimelock function setDelay(uint256 _delay) external override onlySelf { - if (_delay < MINIMUM_DELAY) { - revert Error.INVALID_DELAY_MIN(); - } - - if (_delay > MAXIMUM_DELAY) { - revert Error.INVALID_DELAY_MAX(); - } + _checkDelay(_delay); uint256 oldDelay = delay; delay = _delay; @@ -155,4 +153,18 @@ contract GovernanceTimelock is IGovernanceTimelock { emit AdminUpdated(oldAdmin, _newAdmin); } + + /*///////////////////////////////////////////////////////////////// + PRIVATE/INTERNAL FUNCTIONS + ////////////////////////////////////////////////////////////////*/ + + function _checkDelay(uint256 _delay) internal pure { + if (_delay < MINIMUM_DELAY) { + revert Error.INVALID_DELAY_MIN(); + } + + if (_delay > MAXIMUM_DELAY) { + revert Error.INVALID_DELAY_MAX(); + } + } } diff --git a/test/Setup.t.sol b/test/Setup.t.sol index a264d6a..81f0f4b 100644 --- a/test/Setup.t.sol +++ b/test/Setup.t.sol @@ -29,6 +29,15 @@ abstract contract Setup is Test { /*/////////////////////////////////////////////////////////////// CONSTANTS //////////////////////////////////////////////////////////////*/ + /// @dev chain IDs + uint256 constant ETHEREUM_CHAIN_ID = 1; + uint256 constant BSC_CHAIN_ID = 56; + uint256 constant POLYGON_CHAIN_ID = 137; + + /// @dev common src and dst chain IDs + uint256 constant SRC_CHAIN_ID = ETHEREUM_CHAIN_ID; + uint256 constant DST_CHAIN_ID = POLYGON_CHAIN_ID; + /// @dev simulated caller address constant caller = address(10); address constant owner = address(420); @@ -54,10 +63,10 @@ abstract contract Setup is Test { //////////////////////////////////////////////////////////////*/ /// @notice configure all the chain ids we use for the tests (including src chain) /// id 0 represents src chain - uint256[] public ALL_CHAINS = [1, 56, 137]; + uint256[] public ALL_CHAINS = [ETHEREUM_CHAIN_ID, BSC_CHAIN_ID, POLYGON_CHAIN_ID]; /// @notice configure any new dst chains here - uint256[] public DST_CHAINS = [56, 137]; + uint256[] public DST_CHAINS = [BSC_CHAIN_ID, POLYGON_CHAIN_ID]; /// @notice configure all wormhole parameters in order of DST_CHAINS address[] public WORMHOLE_RELAYERS = [BSC_RELAYER, POLYGON_RELAYER]; @@ -255,7 +264,7 @@ abstract contract Setup is Test { address mmaReceiver = address(new MultiMessageReceiver{salt: _salt}()); contractAddress[chainId][bytes("MMA_RECEIVER")] = mmaReceiver; contractAddress[chainId][bytes("TIMELOCK")] = - address(address(new GovernanceTimelock{salt: _salt}(mmaReceiver))); + address(address(new GovernanceTimelock{salt: _salt}(mmaReceiver, 3 days))); } } diff --git a/test/integration-tests/GracePeriodExpiry.t.sol b/test/integration-tests/GracePeriodExpiry.t.sol index 906ece6..8bd13ed 100644 --- a/test/integration-tests/GracePeriodExpiry.t.sol +++ b/test/integration-tests/GracePeriodExpiry.t.sol @@ -17,22 +17,22 @@ import {GovernanceTimelock} from "src/controllers/GovernanceTimelock.sol"; contract GracePeriodExpiryTest is Setup { MockUniswapReceiver target; - /// @dev intializes the setup + /// @dev initializes the setup function setUp() public override { super.setUp(); - vm.selectFork(fork[137]); + vm.selectFork(fork[DST_CHAIN_ID]); target = new MockUniswapReceiver(); } function test_timelockCheck() public { - vm.selectFork(fork[1]); + vm.selectFork(fork[SRC_CHAIN_ID]); vm.startPrank(caller); /// send cross-chain message using MMA infra vm.recordLogs(); - MultiMessageSender(contractAddress[1][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( - 137, + MultiMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( + DST_CHAIN_ID, address(target), abi.encode(MockUniswapReceiver.setValue.selector, ""), 0, @@ -44,21 +44,21 @@ contract GracePeriodExpiryTest is Setup { vm.recordLogs(); /// simulate off-chain actors - _simulatePayloadDelivery(1, 137, logs); + _simulatePayloadDelivery(SRC_CHAIN_ID, DST_CHAIN_ID, logs); bytes32 msgId = _getMsgId(vm.getRecordedLogs()); - vm.selectFork(fork[137]); + vm.selectFork(fork[DST_CHAIN_ID]); vm.recordLogs(); /// execute the message and move it to governance timelock contract - MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).executeMessage(msgId); + MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]).executeMessage(msgId); (uint256 txId, address finalTarget, uint256 value, bytes memory data, uint256 eta) = _getExecParams(vm.getRecordedLogs()); - /// increment the time by 20 day (beyond expiry, delay) + /// increment the time by 21 day (beyond expiry, delay) /// @notice should revert here with TX_EXPIRED error - vm.warp(block.timestamp + 20 days); + vm.warp(block.timestamp + 21 days); vm.expectRevert(Error.TX_EXPIRED.selector); - GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).executeTransaction( + GovernanceTimelock(contractAddress[DST_CHAIN_ID][bytes("TIMELOCK")]).executeTransaction( txId, finalTarget, value, data, eta ); } diff --git a/test/integration-tests/MultiMessageAggregation.t.sol b/test/integration-tests/MultiMessageAggregation.t.sol index c4ac948..8085839 100644 --- a/test/integration-tests/MultiMessageAggregation.t.sol +++ b/test/integration-tests/MultiMessageAggregation.t.sol @@ -16,23 +16,23 @@ import {GovernanceTimelock} from "src/controllers/GovernanceTimelock.sol"; contract MultiMessageAggregationTest is Setup { MockUniswapReceiver target; - /// @dev intializes the setup + /// @dev initializes the setup function setUp() public override { super.setUp(); - vm.selectFork(fork[137]); + vm.selectFork(fork[DST_CHAIN_ID]); target = new MockUniswapReceiver(); } /// @dev just sends a message function test_mmaSendMessage() public { - vm.selectFork(fork[1]); + vm.selectFork(fork[SRC_CHAIN_ID]); vm.startPrank(caller); /// send cross-chain message using MMA infra vm.recordLogs(); - MultiMessageSender(contractAddress[1][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( - 137, + MultiMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( + DST_CHAIN_ID, address(target), abi.encode(MockUniswapReceiver.setValue.selector, ""), 0, @@ -44,19 +44,19 @@ contract MultiMessageAggregationTest is Setup { vm.recordLogs(); /// simulate off-chain actors - _simulatePayloadDelivery(1, 137, logs); + _simulatePayloadDelivery(SRC_CHAIN_ID, DST_CHAIN_ID, logs); bytes32 msgId = _getMsgId(vm.getRecordedLogs()); - vm.selectFork(fork[137]); + vm.selectFork(fork[DST_CHAIN_ID]); vm.recordLogs(); /// execute the message and move it to governance timelock contract - MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).executeMessage(msgId); + MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]).executeMessage(msgId); (uint256 txId, address finalTarget, uint256 value, bytes memory data, uint256 eta) = _getExecParams(vm.getRecordedLogs()); - /// increment the time by 2 day (delay time) - vm.warp(block.timestamp + 2 days); - GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).executeTransaction( + /// increment the time by 7 days (delay time) + vm.warp(block.timestamp + 7 days); + GovernanceTimelock(contractAddress[DST_CHAIN_ID][bytes("TIMELOCK")]).executeTransaction( txId, finalTarget, value, data, eta ); assertEq(target.i(), type(uint256).max); diff --git a/test/integration-tests/RemoteAdapterAdd.t.sol b/test/integration-tests/RemoteAdapterAdd.t.sol index 246d85c..7df4759 100644 --- a/test/integration-tests/RemoteAdapterAdd.t.sol +++ b/test/integration-tests/RemoteAdapterAdd.t.sol @@ -15,7 +15,7 @@ import {GovernanceTimelock} from "src/controllers/GovernanceTimelock.sol"; /// @dev scenario: admin updates sender adapters on dst chain using message from source chain /// @notice handles both single add and multiple add contract RemoteAdapterAdd is Setup { - /// @dev intializes the setup + /// @dev initializes the setup function setUp() public override { super.setUp(); } @@ -56,9 +56,9 @@ contract RemoteAdapterAdd is Setup { /// send cross-chain message using MMA infra vm.recordLogs(); - MultiMessageSender(contractAddress[1][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( - 137, - address(contractAddress[137][bytes("MMA_RECEIVER")]), + MultiMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( + DST_CHAIN_ID, + address(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]), abi.encodeWithSelector(MultiMessageReceiver.updateReceiverAdapters.selector, adaptersToAdd, operation), 0, block.timestamp + EXPIRATION_CONSTANT @@ -69,25 +69,25 @@ contract RemoteAdapterAdd is Setup { vm.recordLogs(); /// simulate off-chain actors - _simulatePayloadDelivery(1, 137, logs); + _simulatePayloadDelivery(SRC_CHAIN_ID, DST_CHAIN_ID, logs); bytes32 msgId = _getMsgId(vm.getRecordedLogs()); - vm.selectFork(fork[137]); + vm.selectFork(fork[DST_CHAIN_ID]); vm.recordLogs(); /// execute the message and move it to governance timelock contract - MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).executeMessage(msgId); + MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]).executeMessage(msgId); (uint256 txId, address finalTarget, uint256 value, bytes memory data, uint256 eta) = _getExecParams(vm.getRecordedLogs()); - /// increment the time by 2 day (delay time) - vm.warp(block.timestamp + 2 days); - GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).executeTransaction( + /// increment the time by 3 days (delay time) + vm.warp(block.timestamp + 3 days); + GovernanceTimelock(contractAddress[DST_CHAIN_ID][bytes("TIMELOCK")]).executeTransaction( txId, finalTarget, value, data, eta ); for (uint256 j; j < adaptersToAdd.length; ++j) { - bool isTrusted = - MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).isTrustedExecutor(adaptersToAdd[j]); + bool isTrusted = MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]) + .isTrustedExecutor(adaptersToAdd[j]); assert(isTrusted); } } diff --git a/test/integration-tests/RemoteAdapterRemove.t.sol b/test/integration-tests/RemoteAdapterRemove.t.sol index 818d7e4..5c033b5 100644 --- a/test/integration-tests/RemoteAdapterRemove.t.sol +++ b/test/integration-tests/RemoteAdapterRemove.t.sol @@ -15,7 +15,7 @@ import {GovernanceTimelock} from "src/controllers/GovernanceTimelock.sol"; /// @dev scenario: admin updates sender adapters on dst chain using message from source chain /// @notice handles both single add and multiple remove contract RemoteAdapterRemove is Setup { - /// @dev intializes the setup + /// @dev initializes the setup function setUp() public override { super.setUp(); } @@ -23,7 +23,7 @@ contract RemoteAdapterRemove is Setup { /// @dev just remove one adapter and assert function test_remoteRemoveReceiverAdapterSingle() public { address[] memory adaptersToRemove = new address[](1); - adaptersToRemove[0] = contractAddress[137]["AXELAR_RECEIVER_ADAPTER"]; + adaptersToRemove[0] = contractAddress[DST_CHAIN_ID]["AXELAR_RECEIVER_ADAPTER"]; /// true = add /// false = remove @@ -41,8 +41,8 @@ contract RemoteAdapterRemove is Setup { _updateDummy(); address[] memory adaptersToRemove = new address[](2); - adaptersToRemove[0] = contractAddress[137]["AXELAR_RECEIVER_ADAPTER"]; - adaptersToRemove[1] = contractAddress[137]["WORMHOLE_RECEIVER_ADAPTER"]; + adaptersToRemove[0] = contractAddress[DST_CHAIN_ID]["AXELAR_RECEIVER_ADAPTER"]; + adaptersToRemove[1] = contractAddress[DST_CHAIN_ID]["WORMHOLE_RECEIVER_ADAPTER"]; /// true = add /// false = remove @@ -61,9 +61,9 @@ contract RemoteAdapterRemove is Setup { /// send cross-chain message using MMA infra vm.recordLogs(); - MultiMessageSender(contractAddress[1][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( - 137, - address(contractAddress[137][bytes("MMA_RECEIVER")]), + MultiMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( + DST_CHAIN_ID, + address(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]), abi.encodeWithSelector( MultiMessageReceiver.updateQuorumAndReceiverAdapter.selector, newQuorum, adaptersToRemove, operation ), @@ -76,30 +76,30 @@ contract RemoteAdapterRemove is Setup { vm.recordLogs(); /// simulate off-chain actors - _simulatePayloadDelivery(1, 137, logs); + _simulatePayloadDelivery(SRC_CHAIN_ID, DST_CHAIN_ID, logs); bytes32 msgId = _getMsgId(vm.getRecordedLogs()); - vm.selectFork(fork[137]); + vm.selectFork(fork[DST_CHAIN_ID]); vm.recordLogs(); /// execute the message and move it to governance timelock contract - MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).executeMessage(msgId); + MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]).executeMessage(msgId); (uint256 txId, address finalTarget, uint256 value, bytes memory data, uint256 eta) = _getExecParams(vm.getRecordedLogs()); - /// increment the time by 2 day (delay time) - vm.warp(block.timestamp + 2 days); - GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).executeTransaction( + /// increment the time by 7 days (delay time) + vm.warp(block.timestamp + 7 days); + GovernanceTimelock(contractAddress[DST_CHAIN_ID][bytes("TIMELOCK")]).executeTransaction( txId, finalTarget, value, data, eta ); /// @dev validates quorum post update - uint256 currQuorum = MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).quorum(); + uint256 currQuorum = MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]).quorum(); assertEq(currQuorum, newQuorum); /// @dev validates adapters post update for (uint256 j; j < adaptersToRemove.length; ++j) { - bool isTrusted = - MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).isTrustedExecutor(adaptersToRemove[j]); + bool isTrusted = MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]) + .isTrustedExecutor(adaptersToRemove[j]); assert(!isTrusted); } } @@ -113,8 +113,10 @@ contract RemoteAdapterRemove is Setup { bool[] memory operation = new bool[](1); operation[0] = true; - vm.startPrank(contractAddress[137]["TIMELOCK"]); - MultiMessageReceiver(contractAddress[137]["MMA_RECEIVER"]).updateReceiverAdapters(newDummyAdapter, operation); + vm.startPrank(contractAddress[DST_CHAIN_ID]["TIMELOCK"]); + MultiMessageReceiver(contractAddress[DST_CHAIN_ID]["MMA_RECEIVER"]).updateReceiverAdapters( + newDummyAdapter, operation + ); vm.stopPrank(); } } diff --git a/test/integration-tests/RemoteSetQuorum.t.sol b/test/integration-tests/RemoteSetQuorum.t.sol index 18d089e..b119363 100644 --- a/test/integration-tests/RemoteSetQuorum.t.sol +++ b/test/integration-tests/RemoteSetQuorum.t.sol @@ -14,7 +14,7 @@ import {GovernanceTimelock} from "src/controllers/GovernanceTimelock.sol"; /// @dev scenario: admin updates quorum on dst chain using message from source chain contract RemoteQuorumUpdate is Setup { - /// @dev intializes the setup + /// @dev initializes the setup function setUp() public override { super.setUp(); } @@ -23,14 +23,14 @@ contract RemoteQuorumUpdate is Setup { function test_remoteQuorumUpdate() public { uint256 newQuorum = 1; - vm.selectFork(fork[1]); + vm.selectFork(fork[SRC_CHAIN_ID]); vm.startPrank(caller); /// send cross-chain message using MMA infra vm.recordLogs(); - MultiMessageSender(contractAddress[1][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( - 137, - address(contractAddress[137][bytes("MMA_RECEIVER")]), + MultiMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( + DST_CHAIN_ID, + address(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]), abi.encodeWithSelector(MultiMessageReceiver.updateQuorum.selector, newQuorum), 0, block.timestamp + EXPIRATION_CONSTANT @@ -42,26 +42,26 @@ contract RemoteQuorumUpdate is Setup { vm.recordLogs(); /// simulate off-chain actors - _simulatePayloadDelivery(1, 137, logs); + _simulatePayloadDelivery(SRC_CHAIN_ID, DST_CHAIN_ID, logs); bytes32 msgId = _getMsgId(vm.getRecordedLogs()); - vm.selectFork(fork[137]); + vm.selectFork(fork[DST_CHAIN_ID]); vm.recordLogs(); /// execute the message and move it to governance timelock contract - MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).executeMessage(msgId); + MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]).executeMessage(msgId); (uint256 txId, address finalTarget, uint256 value, bytes memory data, uint256 eta) = _getExecParams(vm.getRecordedLogs()); - uint256 oldQuorum = MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).quorum(); + uint256 oldQuorum = MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]).quorum(); assertEq(oldQuorum, 2); - /// increment the time by 2 day (delay time) - vm.warp(block.timestamp + 2 days); - GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).executeTransaction( + /// increment the time by 3 days (delay time) + vm.warp(block.timestamp + 3 days); + GovernanceTimelock(contractAddress[DST_CHAIN_ID][bytes("TIMELOCK")]).executeTransaction( txId, finalTarget, value, data, eta ); - uint256 currQuorum = MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).quorum(); + uint256 currQuorum = MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]).quorum(); assertEq(currQuorum, newQuorum); } } diff --git a/test/integration-tests/RemoteTimelockUpdate.t.sol b/test/integration-tests/RemoteTimelockUpdate.t.sol index 60eb9da..62bdd5d 100644 --- a/test/integration-tests/RemoteTimelockUpdate.t.sol +++ b/test/integration-tests/RemoteTimelockUpdate.t.sol @@ -14,7 +14,7 @@ import {GovernanceTimelock} from "src/controllers/GovernanceTimelock.sol"; /// @dev scenario: admin updates timelock delay on dst chain using message from source chain contract RemoteTimelockUpdate is Setup { - /// @dev intializes the setup + /// @dev initializes the setup function setUp() public override { super.setUp(); } @@ -23,14 +23,14 @@ contract RemoteTimelockUpdate is Setup { function test_remoteTimelockUpdate() public { uint256 newDelay = 19 days; - vm.selectFork(fork[1]); + vm.selectFork(fork[SRC_CHAIN_ID]); vm.startPrank(caller); /// send cross-chain message using MMA infra vm.recordLogs(); - MultiMessageSender(contractAddress[1][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( - 137, - address(contractAddress[137][bytes("TIMELOCK")]), + MultiMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( + POLYGON_CHAIN_ID, + address(contractAddress[POLYGON_CHAIN_ID][bytes("TIMELOCK")]), abi.encodeWithSelector(GovernanceTimelock.setDelay.selector, newDelay), 0, block.timestamp + EXPIRATION_CONSTANT @@ -42,26 +42,26 @@ contract RemoteTimelockUpdate is Setup { vm.recordLogs(); /// simulate off-chain actors - _simulatePayloadDelivery(1, 137, logs); + _simulatePayloadDelivery(ETHEREUM_CHAIN_ID, POLYGON_CHAIN_ID, logs); bytes32 msgId = _getMsgId(vm.getRecordedLogs()); - vm.selectFork(fork[137]); + vm.selectFork(fork[POLYGON_CHAIN_ID]); vm.recordLogs(); /// execute the message and move it to governance timelock contract - MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).executeMessage(msgId); + MultiMessageReceiver(contractAddress[POLYGON_CHAIN_ID][bytes("MMA_RECEIVER")]).executeMessage(msgId); (uint256 txId, address finalTarget, uint256 value, bytes memory data, uint256 eta) = _getExecParams(vm.getRecordedLogs()); - uint256 oldDelay = GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).delay(); - assertEq(oldDelay, GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).MINIMUM_DELAY()); + uint256 oldDelay = GovernanceTimelock(contractAddress[POLYGON_CHAIN_ID][bytes("TIMELOCK")]).delay(); + assertEq(oldDelay, 3 days); - /// increment the time by 2 day (delay time) - vm.warp(block.timestamp + 2 days); - GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).executeTransaction( + /// increment the time by 3 days (delay time) + vm.warp(block.timestamp + 3 days); + GovernanceTimelock(contractAddress[POLYGON_CHAIN_ID][bytes("TIMELOCK")]).executeTransaction( txId, finalTarget, value, data, eta ); - uint256 currDelay = GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).delay(); + uint256 currDelay = GovernanceTimelock(contractAddress[POLYGON_CHAIN_ID][bytes("TIMELOCK")]).delay(); assertEq(currDelay, newDelay); } } diff --git a/test/integration-tests/TimelockCheck.t.sol b/test/integration-tests/TimelockCheck.t.sol index 5227504..2b729e1 100644 --- a/test/integration-tests/TimelockCheck.t.sol +++ b/test/integration-tests/TimelockCheck.t.sol @@ -18,23 +18,23 @@ import {GovernanceTimelock} from "src/controllers/GovernanceTimelock.sol"; contract TimelockCheckTest is Setup { MockUniswapReceiver target; - /// @dev intializes the setup + /// @dev initializes the setup function setUp() public override { super.setUp(); - vm.selectFork(fork[137]); + vm.selectFork(fork[DST_CHAIN_ID]); target = new MockUniswapReceiver(); } /// @dev just sends a message function test_timelockCheck() public { - vm.selectFork(fork[1]); + vm.selectFork(fork[SRC_CHAIN_ID]); vm.startPrank(caller); /// send cross-chain message using MMA infra vm.recordLogs(); - MultiMessageSender(contractAddress[1][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( - 137, + MultiMessageSender(contractAddress[SRC_CHAIN_ID][bytes("MMA_SENDER")]).remoteCall{value: 2 ether}( + DST_CHAIN_ID, address(target), abi.encode(MockUniswapReceiver.setValue.selector, ""), 0, @@ -46,13 +46,13 @@ contract TimelockCheckTest is Setup { vm.recordLogs(); /// simulate off-chain actors - _simulatePayloadDelivery(1, 137, logs); + _simulatePayloadDelivery(SRC_CHAIN_ID, DST_CHAIN_ID, logs); bytes32 msgId = _getMsgId(vm.getRecordedLogs()); - vm.selectFork(fork[137]); + vm.selectFork(fork[DST_CHAIN_ID]); vm.recordLogs(); /// execute the message and move it to governance timelock contract - MultiMessageReceiver(contractAddress[137][bytes("MMA_RECEIVER")]).executeMessage(msgId); + MultiMessageReceiver(contractAddress[DST_CHAIN_ID][bytes("MMA_RECEIVER")]).executeMessage(msgId); (uint256 txId, address finalTarget, uint256 value, bytes memory data, uint256 eta) = _getExecParams(vm.getRecordedLogs()); @@ -60,13 +60,13 @@ contract TimelockCheckTest is Setup { /// @notice should revert here with TX_TIMELOCKED error vm.warp(block.timestamp + 1 days); vm.expectRevert(Error.TX_TIMELOCKED.selector); - GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).executeTransaction( + GovernanceTimelock(contractAddress[DST_CHAIN_ID][bytes("TIMELOCK")]).executeTransaction( txId, finalTarget, value, data, eta ); /// increment the time by 2 day (delay time) vm.warp(block.timestamp + 2 days); - GovernanceTimelock(contractAddress[137][bytes("TIMELOCK")]).executeTransaction( + GovernanceTimelock(contractAddress[DST_CHAIN_ID][bytes("TIMELOCK")]).executeTransaction( txId, finalTarget, value, data, eta ); assertEq(target.i(), type(uint256).max); diff --git a/test/unit-tests/GovernanceTimelock.t.sol b/test/unit-tests/GovernanceTimelock.t.sol index 57fb212..1f3ebe5 100644 --- a/test/unit-tests/GovernanceTimelock.t.sol +++ b/test/unit-tests/GovernanceTimelock.t.sol @@ -17,9 +17,6 @@ contract GovernanceTimelockTest is Setup { event DelayUpdated(uint256 oldDelay, uint256 newDelay); event AdminUpdated(address oldAdmin, address newAdmin); - uint256 constant SRC_CHAIN_ID = 1; - uint256 constant DST_CHAIN_ID = 137; - GovernanceTimelock timelock; address admin; @@ -37,14 +34,14 @@ contract GovernanceTimelockTest is Setup { function test_constructor() public { // checks existing setup assertEq(address(timelock.admin()), admin); - assertEq(timelock.delay(), timelock.MINIMUM_DELAY()); + assertEq(timelock.delay(), 3 days); assertEq(timelock.txCounter(), 0); } /// @dev cannot be called with zero address admin function test_constructor_zero_address_input() public { vm.expectRevert(Error.ZERO_ADDRESS_INPUT.selector); - new GovernanceTimelock(address(0)); + new GovernanceTimelock(address(0), 3 days); } /// @dev schedule transaction @@ -265,4 +262,34 @@ contract GovernanceTimelockTest is Setup { vm.expectRevert(Error.ZERO_TIMELOCK_ADMIN.selector); timelock.setAdmin(address(0)); } + + /// @dev sets delay via scheduled transaction + function test_set_delay_scheduled() public { + vm.startPrank(address(admin)); + + bytes memory data = abi.encodeWithSelector(GovernanceTimelock.setDelay.selector, 10 days); + timelock.scheduleTransaction(address(timelock), 0, data); + uint256 eta = block.timestamp + timelock.delay(); + + skip(3 days); + + timelock.executeTransaction(1, address(timelock), 0, data, eta); + + assertEq(timelock.delay(), 10 days); + } + + /// @dev sets admin via scheduled transaction + function test_set_admin_scheduled() public { + vm.startPrank(address(admin)); + + bytes memory data = abi.encodeWithSelector(GovernanceTimelock.setAdmin.selector, address(42)); + timelock.scheduleTransaction(address(timelock), 0, data); + uint256 eta = block.timestamp + timelock.delay(); + + skip(3 days); + + timelock.executeTransaction(1, address(timelock), 0, data, eta); + + assertEq(timelock.admin(), address(42)); + } } diff --git a/test/unit-tests/MultiMessageReceiver.t.sol b/test/unit-tests/MultiMessageReceiver.t.sol index 98ef5a7..b22881b 100644 --- a/test/unit-tests/MultiMessageReceiver.t.sol +++ b/test/unit-tests/MultiMessageReceiver.t.sol @@ -19,9 +19,6 @@ contract MultiMessageReceiverTest is Setup { ); event MessageExecuted(bytes32 indexed msgId, address target, uint256 nativeValue, uint256 nonce, bytes callData); - uint256 constant SRC_CHAIN_ID = 1; - uint256 constant DST_CHAIN_ID = 137; - MultiMessageReceiver receiver; address wormholeAdapterAddr; address axelarAdapterAddr; @@ -236,7 +233,7 @@ contract MultiMessageReceiverTest is Setup { receiver.receiveMessage( MessageLibrary.Message({ srcChainId: SRC_CHAIN_ID, - dstChainId: 56, + dstChainId: BSC_CHAIN_ID, target: address(0), nonce: 0, callData: bytes(""), @@ -273,7 +270,7 @@ contract MultiMessageReceiverTest is Setup { vm.expectRevert(Error.INVALID_SENDER_CHAIN_ID.selector); receiver.receiveMessage( MessageLibrary.Message({ - srcChainId: 56, + srcChainId: BSC_CHAIN_ID, dstChainId: DST_CHAIN_ID, target: address(42), nonce: 0, diff --git a/test/unit-tests/MultiMessageSender.t.sol b/test/unit-tests/MultiMessageSender.t.sol index 9d20d76..c672b49 100644 --- a/test/unit-tests/MultiMessageSender.t.sol +++ b/test/unit-tests/MultiMessageSender.t.sol @@ -30,9 +30,6 @@ contract MultiMessageSenderTest is Setup { event SenderAdapterUpdated(address senderAdapter, bool add); event ErrorSendMessage(address senderAdapter, MessageLibrary.Message message); - uint256 constant SRC_CHAIN_ID = 1; - uint256 constant DST_CHAIN_ID = 137; - MultiMessageSender sender; address receiver; IGAC gac;