diff --git a/scripts/payloads/examples/Payload_AllowReceiverBridgeAdapters.s.sol b/scripts/payloads/examples/Payload_AllowReceiverBridgeAdapters.s.sol new file mode 100644 index 0000000..6f8e06d --- /dev/null +++ b/scripts/payloads/examples/Payload_AllowReceiverBridgeAdapters.s.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; + +import {ICrossChainReceiver} from 'adi/interfaces/ICrossChainReceiver.sol'; + +/** + * @notice Deploys a payload with a single function that allows new receiver bridge adapters. + * + * @dev Remember to update the receiver address and allowAdapterInputs array length and members. + * An example is provided. + * + * Run with: + * forge script scripts/create_payloads/Payload_AllowReceiverBridgeAdapters.s.s.sol --tc CreateReceiverAllowBridgeAdaptersPayload + */ +contract ReceiverAllowBridgeAdaptersPayload { + /// @dev Replace with the address of the CrossChainReceiver contract. + ICrossChainReceiver constant RECEIVER = ICrossChainReceiver(address(0)); + + function execute() external { + /// @dev Replace with the adapters and associated chain IDs. + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] + memory allowAdapterInputs = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](0); + // allowAdapterInputs[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ + // bridgeAdapter: address(0), + // chainIds: new uint256[](0) + // }); + + RECEIVER.allowReceiverBridgeAdapters(allowAdapterInputs); + } +} + +contract CreateReceiverAllowBridgeAdaptersPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + ReceiverAllowBridgeAdaptersPayload receiverAllowBridgeAdaptersPayload = new ReceiverAllowBridgeAdaptersPayload(); + console2.log( + 'ReceiverAllowBridgeAdaptersPayload deployed at %s on chain with chain ID %s', + address(receiverAllowBridgeAdaptersPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_ApproveForwarderSenders.s.sol b/scripts/payloads/examples/Payload_ApproveForwarderSenders.s.sol new file mode 100644 index 0000000..a6cd131 --- /dev/null +++ b/scripts/payloads/examples/Payload_ApproveForwarderSenders.s.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; + +import {ICrossChainForwarder} from 'adi/interfaces/ICrossChainForwarder.sol'; + +/** + * @notice Deploys a payload with a single function that approves forwarder senders. + * + * @dev Remember to update the sendersToApprove array length and members. + * + * Run with: + * forge script scripts/create_payloads/Payload_ApproveForwarderSenders.s.s.sol --tc CreateApproveForwarderSendersPayload + */ +contract ApproveForwarderSendersPayload { + /// @dev Replace with the address of the CrossChainForwarder contract. + ICrossChainForwarder constant FORWARDER = ICrossChainForwarder(address(0)); + + function execute() external { + /// @dev Replace with the senders to approve. + address[] memory sendersToApprove = new address[](0); + // sendersToApprove[0] = adress(0); + + FORWARDER.approveSenders(sendersToApprove); + } +} + +contract CreateApproveForwarderSendersPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + ApproveForwarderSendersPayload approveForwarderSendersPayload = new ApproveForwarderSendersPayload(); + console2.log( + 'ApproveForwarderSendersPayload deployed at %s on chain with chain ID %s', + address(approveForwarderSendersPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_DisableForwarderBridgeAdapters.s copy.sol b/scripts/payloads/examples/Payload_DisableForwarderBridgeAdapters.s copy.sol new file mode 100644 index 0000000..905419e --- /dev/null +++ b/scripts/payloads/examples/Payload_DisableForwarderBridgeAdapters.s copy.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; + +import {ICrossChainForwarder} from 'adi/interfaces/ICrossChainForwarder.sol'; + +/** + * @notice Deploys a payload with a single function that disables forwarder bridge adapters. + * + * @dev Remember to update the adaptersToDisable array length and members. + * + * Run with: + * forge script scripts/create_payloads/Payload_DisableForwarderBridgeAdapters.s.s.sol --tc CreateDisableForwarderBridgeAdaptersPayload + */ +contract DisableForwarderBridgeAdaptersPayload { + /// @dev Replace with the address of the CrossChainForwarder contract. + ICrossChainForwarder constant FORWARDER = ICrossChainForwarder(address(0)); + + function execute() external { + /// @dev Replace with the forwarder bridge adapters to disable. + ICrossChainForwarder.BridgeAdapterToDisable[] + memory adaptersToDisable = new ICrossChainForwarder.BridgeAdapterToDisable[](1); + // adaptersToDisable[0] = ICrossChainForwarder.BridgeAdapterToDisable({ + // bridgeAdapter: address(0), + // chainIds: new uint256[](0) + // }); + + FORWARDER.disableBridgeAdapters(adaptersToDisable); + } +} + +contract CreateDisableForwarderBridgeAdaptersPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + DisableForwarderBridgeAdaptersPayload disableForwarderBridgeAdaptersPayload = new DisableForwarderBridgeAdaptersPayload(); + console2.log( + 'DisableForwarderBridgeAdaptersPayload deployed at %s on chain with chain ID %s', + address(disableForwarderBridgeAdaptersPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_DisallowReceiverBridgeAdapters.s.sol b/scripts/payloads/examples/Payload_DisallowReceiverBridgeAdapters.s.sol new file mode 100644 index 0000000..50d60a4 --- /dev/null +++ b/scripts/payloads/examples/Payload_DisallowReceiverBridgeAdapters.s.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; + +import {ICrossChainReceiver} from 'adi/interfaces/ICrossChainReceiver.sol'; + +/** + * @notice Deploys a payload with a single function that disallows receiver bridge adapters. + * + * @dev Remember to update the receiver address and disallowAdapterInputs array length and members. + * An example is provided. + * + * Run with: + * forge script scripts/create_payloads/Payload_DisallowReceiverBridgeAdapters.s.s.sol --tc CreateReceiverDisallowBridgeAdaptersPayload + */ +contract ReceiverDisallowBridgeAdaptersPayload { + /// @dev Replace with the address of the CrossChainReceiver contract. + ICrossChainReceiver constant RECEIVER = ICrossChainReceiver(address(0)); + + function execute() external { + /// @dev Replace with the adapters and associated chain IDs. + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] + memory disallowAdapterInputs = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](0); + // disallowAdapterInputs[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ + // bridgeAdapter: address(0), + // chainIds: new uint256[](0) + // }); + + RECEIVER.disallowReceiverBridgeAdapters(disallowAdapterInputs); + } +} + +contract CreateReceiverDisallowBridgeAdaptersPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + ReceiverDisallowBridgeAdaptersPayload receiverDisallowBridgeAdaptersPayload = new ReceiverDisallowBridgeAdaptersPayload(); + console2.log( + 'ReceiverDisallowBridgeAdaptersPayload deployed at %s on chain with chain ID %s', + address(receiverDisallowBridgeAdaptersPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_Emergency.s.sol b/scripts/payloads/examples/Payload_Emergency.s.sol new file mode 100644 index 0000000..164723f --- /dev/null +++ b/scripts/payloads/examples/Payload_Emergency.s.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; +import {IEmergencyRegistry} from 'adi/emergency/interfaces/IEmergencyRegistry.sol'; + +/** + * @notice Deploys a payload with a single `execute()` function that enables emergency mode + * on the given chains. + * + * @dev Remember to update the emergency registry address and the emergencyChains array length and members. + * Examples are provided. + * + * Run with: + * forge script scripts/create_payloads/Payload_Emergency.s.sol --tc CreateEmergencyPayload + */ +contract EmergencyPayload { + /// @dev Replace with the address of the EmergencyRegistry contract. + IEmergencyRegistry constant EMERGENCY_REGISTRY = IEmergencyRegistry(address(0)); + + function execute() external { + /// @dev Replace with the chains to enable emergency mode on. + // Replace the "0" with the number of chains, then set each one like in the comment. + uint256[] memory emergencyChains = new uint256[](0); + // emergencyChains[0] = 1; + // emergencyChains[1] = 2; + + EMERGENCY_REGISTRY.setEmergency(emergencyChains); + } +} + +contract CreateEmergencyPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + EmergencyPayload emergencyPayload = new EmergencyPayload(); + console2.log( + 'EmergencyPayload deployed at %s on chain with chain ID %s', + address(emergencyPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_EnableForwarderBridgeAdapters.s.sol b/scripts/payloads/examples/Payload_EnableForwarderBridgeAdapters.s.sol new file mode 100644 index 0000000..fa72159 --- /dev/null +++ b/scripts/payloads/examples/Payload_EnableForwarderBridgeAdapters.s.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; + +import {ICrossChainForwarder} from 'adi/interfaces/ICrossChainForwarder.sol'; + +/** + * @notice Deploys a payload with a single function that enables forwarder bridge adapters. + * + * @dev Remember to update the adaptersToEnable array length and members. + * + * Run with: + * forge script scripts/create_payloads/Payload_EnableForwarderBridgeAdapters.s.s.sol --tc CreateEnableForwarderBridgeAdaptersPayload + */ +contract EnableForwarderBridgeAdaptersPayload { + /// @dev Replace with the address of the CrossChainForwarder contract. + ICrossChainForwarder constant FORWARDER = ICrossChainForwarder(address(0)); + + function execute() external { + /// @dev Replace with the forwarder bridge adapters to enable. + ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] + memory adaptersToEnable = new ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[](0); + // adaptersToEnable[0] = ICrossChainForwarder.ForwarderBridgeAdapterConfigInput({ + // currentChainBridgeAdapter: address(0), + // destinationBridgeAdapter: address(0), + // destinationChainId: 0 + // }); + + FORWARDER.enableBridgeAdapters(adaptersToEnable); + } +} + +contract CreateEnableForwarderBridgeAdaptersPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + EnableForwarderBridgeAdaptersPayload enableForwarderBridgeAdaptersPayload = new EnableForwarderBridgeAdaptersPayload(); + console2.log( + 'EnableForwarderBridgeAdaptersPayload deployed at %s on chain with chain ID %s', + address(enableForwarderBridgeAdaptersPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_MessageValidity.s.sol b/scripts/payloads/examples/Payload_MessageValidity.s.sol new file mode 100644 index 0000000..012cd2a --- /dev/null +++ b/scripts/payloads/examples/Payload_MessageValidity.s.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; + +import {ICrossChainReceiver} from 'adi/interfaces/ICrossChainReceiver.sol'; + +/** + * @notice Deploys a payload with a single function that updates receiver message validity timestamps. + * + * @dev Remember to update the receiver address and validityTimestampInputs array length and members. + * An example is provided. + * + * Run with: + * forge script scripts/create_payloads/Payload_MessageValidity.s.sol --tc CreateMessageValidityPayload + */ +contract MessageValidityPayload { + /// @dev Replace with the address of the CrossChainReceiver contract. + ICrossChainReceiver constant RECEIVER = ICrossChainReceiver(address(0)); + + function execute() external { + ICrossChainReceiver.ValidityTimestampInput[] + memory validityTimestampInputs = new ICrossChainReceiver.ValidityTimestampInput[](0); + // validityTimestampInputs[0] = ICrossChainReceiver.ValidityTimestampInput({ + // chainId: 1, + // validityTimestamp: 1 + // }); + + RECEIVER.updateMessagesValidityTimestamp(validityTimestampInputs); + } +} + +contract CreateMessageValidityPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + MessageValidityPayload messagesValidityPayload = new MessageValidityPayload(); + console2.log( + 'MessageValidityPayload deployed at %s on chain with chain ID %s', + address(messagesValidityPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_ReceiverConfirmations.s.sol b/scripts/payloads/examples/Payload_ReceiverConfirmations.s.sol new file mode 100644 index 0000000..fdafbbc --- /dev/null +++ b/scripts/payloads/examples/Payload_ReceiverConfirmations.s.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; + +import {ICrossChainReceiver} from 'adi/interfaces/ICrossChainReceiver.sol'; + +/** + * @notice Deploys a payload with a single function that updates receiver confirmations. + * + * @dev Remember to update the receiver address and confirmationInputs array length and members. + * An example is provided. + * + * Run with: + * forge script scripts/create_payloads/Payload_ReceiverConfirmations.s.sol --tc CreateReceiverConfirmationsPayload + */ +contract ReceiverConfirmationsPayload { + /// @dev Replace with the address of the CrossChainReceiver contract. + ICrossChainReceiver constant RECEIVER = ICrossChainReceiver(address(0)); + + function execute() external { + /// @dev Replace with the chain IDs and required confirmations. + ICrossChainReceiver.ConfirmationInput[] + memory confirmationInputs = new ICrossChainReceiver.ConfirmationInput[](0); + // confirmationInputs[0] = ICrossChainReceiver.ConfirmationInput({ + // chainId: 1, + // requiredConfirmations: 1 + // }); + + RECEIVER.updateConfirmations(confirmationInputs); + } +} + +contract CreateReceiverConfirmationsPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + ReceiverConfirmationsPayload receiverConfirmationsPayload = new ReceiverConfirmationsPayload(); + console2.log( + 'ReceiverConfirmationsPayload deployed at %s on chain with chain ID %s', + address(receiverConfirmationsPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_RemoveForwarderSenders.s.sol b/scripts/payloads/examples/Payload_RemoveForwarderSenders.s.sol new file mode 100644 index 0000000..ff23990 --- /dev/null +++ b/scripts/payloads/examples/Payload_RemoveForwarderSenders.s.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; + +import {ICrossChainForwarder} from 'adi/interfaces/ICrossChainForwarder.sol'; + +/** + * @notice Deploys a payload with a single function that removes forwarder senders. + * + * @dev Remember to update the sendersToRemove array length and members. + * + * Run with: + * forge script scripts/create_payloads/Payload_RemoveForwarderSenders.s.s.sol --tc CreateRemoveForwarderSendersPayload + */ +contract RemoveForwarderSendersPayload { + /// @dev Replace with the address of the CrossChainForwarder contract. + ICrossChainForwarder constant FORWARDER = ICrossChainForwarder(address(0)); + + function execute() external { + /// @dev Replace with the senders to remove. + address[] memory sendersToRemove = new address[](0); + // sendersToRemove[0] = adress(0); + + FORWARDER.removeSenders(sendersToRemove); + } +} + +contract CreateRemoveForwarderSendersPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + RemoveForwarderSendersPayload removeForwarderSendersPayload = new RemoveForwarderSendersPayload(); + console2.log( + 'RemoveForwarderSendersPayload deployed at %s on chain with chain ID %s', + address(removeForwarderSendersPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_SolveEmergency.s.sol b/scripts/payloads/examples/Payload_SolveEmergency.s.sol new file mode 100644 index 0000000..51cc012 --- /dev/null +++ b/scripts/payloads/examples/Payload_SolveEmergency.s.sol @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import 'forge-std/console2.sol'; +import {IEmergencyRegistry} from 'adi/emergency/interfaces/IEmergencyRegistry.sol'; + +import {ICrossChainReceiver} from 'adi/interfaces/ICrossChainReceiver.sol'; +import {ICrossChainForwarder} from 'adi/interfaces/ICrossChainForwarder.sol'; +import {ICrossChainControllerWithEmergencyMode} from 'adi/interfaces/ICrossChainControllerWithEmergencyMode.sol'; + +/** + * @notice Deploys a payload with a single function that solves the emergency. + * + * @dev Note that this should only be used to create the calldata necessary to pass to the + * controller, as the Guardian must solve the emergency, not governance. + * + * Remember to set the correct parameters, including the controller address and array lengths and members. + * Examples are provided. + * + * Run with: + * forge script scripts/create_payloads/Payload_SolveEmergency.s.sol --tc CreateSolveEmergencyPayload + */ +contract SolveEmergencyPayload { + /// @dev Replace with the address of the CrossChainControllerWithEmergencyMode contract. + ICrossChainControllerWithEmergencyMode constant CONTROLLER = + ICrossChainControllerWithEmergencyMode(address(0)); + + function execute() external { + /// @dev Replace the length and contents of all parameters. + + ICrossChainReceiver.ConfirmationInput[] + memory confirmationInputs = new ICrossChainReceiver.ConfirmationInput[](0); + // confirmationInputs[0] = ICrossChainReceiver.ConfirmationInput({ + // chainId: 1, + // requiredConfirmations: 1 + // }); + + ICrossChainReceiver.ValidityTimestampInput[] + memory validityTimestampInputs = new ICrossChainReceiver.ValidityTimestampInput[](0); + // validityTimestampInputs[0] = ICrossChainReceiver.ValidityTimestampInput({ + // chainId: 1, + // validityTimestamp: 1 + // }); + + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] + memory receiverBridgeAdaptersToAllow = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]( + 0 + ); + // receiverBridgeAdaptersToAllow[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ + // bridgeAdapter: address(0), + // chainIds: new uint256[](0) + // }); + + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] + memory receiverBridgeAdaptersToDisallow = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]( + 0 + ); + // receiverBridgeAdaptersToDisallow[0] = ICrossChainReceiver.ReceiverBridgeAdapterConfigInput({ + // bridgeAdapter: address(0), + // chainIds: new uint256[](0) + // }); + + address[] memory sendersToApprove = new address[](0); + address[] memory sendersToRemove = new address[](0); + + ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] + memory forwarderBridgeAdaptersToEnable = new ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[]( + 0 + ); + // forwarderBridgeAdaptersToEnable[0] = ICrossChainForwarder.ForwarderBridgeAdapterConfigInput({ + // currentChainBridgeAdapter: address(0), + // destinationBridgeAdapter: address(0), + // destinationChainId: 1 + // }); + + ICrossChainForwarder.BridgeAdapterToDisable[] + memory forwarderBridgeAdaptersToDisable = new ICrossChainForwarder.BridgeAdapterToDisable[]( + 0 + ); + // forwarderBridgeAdaptersToDisable[0] = ICrossChainForwarder.BridgeAdapterToDisable({ + // bridgeAdapter: address(0), + // chainIds: new uint256[](0) + // }); + + CONTROLLER.solveEmergency( + confirmationInputs, + validityTimestampInputs, + receiverBridgeAdaptersToAllow, + receiverBridgeAdaptersToDisallow, + sendersToApprove, + sendersToRemove, + forwarderBridgeAdaptersToEnable, + forwarderBridgeAdaptersToDisable + ); + } +} + +contract CreateSolveEmergencyPayload is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + SolveEmergencyPayload solveEmergencyPayload = new SolveEmergencyPayload(); + console2.log( + 'SolveEmergencyPayload deployed at %s on chain with chain ID %s', + address(solveEmergencyPayload), + block.chainid + ); + vm.stopBroadcast(); + } +} diff --git a/scripts/payloads/examples/Payload_SolveEmergencyPrePopulated.s.sol b/scripts/payloads/examples/Payload_SolveEmergencyPrePopulated.s.sol new file mode 100644 index 0000000..81b92ca --- /dev/null +++ b/scripts/payloads/examples/Payload_SolveEmergencyPrePopulated.s.sol @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import 'forge-std/Script.sol'; +import {ICrossChainReceiver} from 'adi/interfaces/ICrossChainReceiver.sol'; +import {ICrossChainForwarder} from 'adi/interfaces/ICrossChainForwarder.sol'; +import {ICrossChainControllerWithEmergencyMode} from 'adi/interfaces/ICrossChainControllerWithEmergencyMode.sol'; +import {ChainIds} from 'adi/libs/ChainIds.sol'; + +/// @dev Remember to set this before running the deployment script. +address constant CROSS_CHAIN_CONTROLLER = address(0); + +/** + * @notice Deploys a payload with a single function that solves the emergency using pre-populated default data. + * + * @dev Note that this should only be used to create the calldata necessary to pass to the + * controller, as the Guardian must solve the emergency, not governance. + * + * Remember to set the correct controller address above. + * + * This payload does the following on all chains: + * 1. Sets the validity timestamp to block.timestamp + * 2. Disallows all receiver bridge adapters + * 3. Disables all forwarder bridge adapters + * + * Run with: + * forge script scripts/create_payloads/Payload_SolveEmergencyPrePopulated.s.sol --tc CreateSolveEmergencyPayloadPrePopulated + */ +contract SolveEmergencyPayloadPrePopulated { + ICrossChainControllerWithEmergencyMode immutable CONTROLLER; + + uint256 constant CHAIN_IDS_COUNT = 9; + + constructor(address _controller) { + CONTROLLER = ICrossChainControllerWithEmergencyMode(_controller); + } + + function execute() external { + uint256[CHAIN_IDS_COUNT] memory chainIds = _chainIds(); + + /* --------------------------- Receiver Parameters -------------------------- */ + ICrossChainReceiver.ConfirmationInput[] + memory confirmationInputs = new ICrossChainReceiver.ConfirmationInput[](0); + + ICrossChainReceiver.ValidityTimestampInput[] // block.timestamp + memory validityTimestampInputs = _getValidityTimestamps(chainIds); + + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] + memory receiverBridgeAdaptersToAllow = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]( + 0 + ); + + // Disallow all adapters on all chains. + ( + address[][CHAIN_IDS_COUNT] memory receiverBridgeAdaptersPerChain, + uint256 receiverMaxAdapterCount + ) = _getReceiverBridgeAdaptersAndMaxCountPerChain(chainIds); + + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] + memory receiverBridgeAdaptersToDisallow = _getUniqueAdapters( + chainIds, + receiverBridgeAdaptersPerChain, + receiverMaxAdapterCount + ); + + /* -------------------------- Forwarder Parameters -------------------------- */ + + address[] memory sendersToApprove = new address[](0); + address[] memory sendersToRemove = new address[](0); + + ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] + memory forwarderBridgeAdaptersToEnable = new ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[]( + 0 + ); + + ( + address[][CHAIN_IDS_COUNT] memory forwarderBridgeAdaptersPerChain, + uint256 forwarderMaxAdapterCount + ) = _getForwarderBridgeAdaptersAndMaxCountPerChain(chainIds); + + ICrossChainForwarder.BridgeAdapterToDisable[] + memory forwarderBridgeAdaptersToDisable = _castToForwarderBridgeAdaptersToDisable( + _getUniqueAdapters(chainIds, forwarderBridgeAdaptersPerChain, forwarderMaxAdapterCount) + ); + + CONTROLLER.solveEmergency( + confirmationInputs, + validityTimestampInputs, + receiverBridgeAdaptersToAllow, + receiverBridgeAdaptersToDisallow, + sendersToApprove, + sendersToRemove, + forwarderBridgeAdaptersToEnable, + forwarderBridgeAdaptersToDisable + ); + } + + function _getReceiverBridgeAdaptersAndMaxCountPerChain( + uint256[CHAIN_IDS_COUNT] memory chainIds + ) internal view returns (address[][CHAIN_IDS_COUNT] memory, uint256) { + address[][CHAIN_IDS_COUNT] memory bridgeAdaptersPerChain; + uint256 maxAdapterCount; + for (uint256 i = 0; i < CHAIN_IDS_COUNT; ++i) { + bridgeAdaptersPerChain[i] = CONTROLLER.getReceiverBridgeAdaptersByChain(chainIds[i]); + maxAdapterCount += bridgeAdaptersPerChain[i].length; + } + return (bridgeAdaptersPerChain, maxAdapterCount); + } + + function _getForwarderBridgeAdaptersAndMaxCountPerChain( + uint256[CHAIN_IDS_COUNT] memory chainIds + ) internal view returns (address[][CHAIN_IDS_COUNT] memory, uint256) { + address[][CHAIN_IDS_COUNT] memory bridgeAdaptersPerChain; + uint256 maxAdapterCount; + for (uint256 i = 0; i < CHAIN_IDS_COUNT; ++i) { + ICrossChainForwarder.ChainIdBridgeConfig[] memory chainIdBridgeConfigs = CONTROLLER + .getForwarderBridgeAdaptersByChain(chainIds[i]); + + bridgeAdaptersPerChain[i] = new address[](chainIdBridgeConfigs.length); + + // Populate the bridge adapters per chain array + for (uint256 j = 0; j < chainIdBridgeConfigs.length; ++j) { + bridgeAdaptersPerChain[i][j] = chainIdBridgeConfigs[j].currentChainBridgeAdapter; + } + maxAdapterCount += bridgeAdaptersPerChain[i].length; + } + return (bridgeAdaptersPerChain, maxAdapterCount); + } + + function _getValidityTimestamps( + uint256[CHAIN_IDS_COUNT] memory chainIds + ) internal view returns (ICrossChainReceiver.ValidityTimestampInput[] memory) { + ICrossChainReceiver.ValidityTimestampInput[] + memory validityTimestampInputs = new ICrossChainReceiver.ValidityTimestampInput[]( + CHAIN_IDS_COUNT + ); + for (uint256 i = 0; i < CHAIN_IDS_COUNT; ++i) { + validityTimestampInputs[i] = ICrossChainReceiver.ValidityTimestampInput({ + chainId: chainIds[i], + validityTimestamp: uint120(block.timestamp) + }); + } + return validityTimestampInputs; + } + + function _getUniqueAdapters( + uint256[CHAIN_IDS_COUNT] memory chainIds, + address[][CHAIN_IDS_COUNT] memory bridgeAdaptersPerChain, + uint256 maxAdapterCount + ) internal pure returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory) { + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] + memory uniqueAdapters = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]( + maxAdapterCount + ); + uint256 realAdapterCount; + + for (uint256 i = 0; i < CHAIN_IDS_COUNT; ++i) { + for (uint256 j = 0; j < bridgeAdaptersPerChain[i].length; ++j) { + if (!_adapterExistsInArray(bridgeAdaptersPerChain[i][j], uniqueAdapters)) { + uniqueAdapters[realAdapterCount].bridgeAdapter = bridgeAdaptersPerChain[i][j]; + uniqueAdapters[realAdapterCount].chainIds = _getAdapterChainIds( + bridgeAdaptersPerChain[i][j], + chainIds, + bridgeAdaptersPerChain + ); + ++realAdapterCount; + } + } + } + + return _trimAdapterArray(uniqueAdapters, realAdapterCount); + } + + function _getAdapterChainIds( + address adapter, + uint256[CHAIN_IDS_COUNT] memory chainIds, + address[][CHAIN_IDS_COUNT] memory bridgeAdaptersPerChain + ) internal pure returns (uint256[] memory) { + uint256[] memory uniqueChainIds = new uint256[](CHAIN_IDS_COUNT); + uint256 realChainIdsCount; + + for (uint256 i = 0; i < CHAIN_IDS_COUNT; ++i) { + for (uint256 j = 0; j < bridgeAdaptersPerChain[i].length; ++j) { + if (bridgeAdaptersPerChain[i][j] == adapter) { + uniqueChainIds[realChainIdsCount] = chainIds[i]; + ++realChainIdsCount; + break; + } + } + } + + return _trimChainIdArray(uniqueChainIds, realChainIdsCount); + } + + function _castToForwarderBridgeAdaptersToDisable( + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory input + ) internal pure returns (ICrossChainForwarder.BridgeAdapterToDisable[] memory) { + ICrossChainForwarder.BridgeAdapterToDisable[] + memory output = new ICrossChainForwarder.BridgeAdapterToDisable[](input.length); + for (uint256 i = 0; i < input.length; ++i) { + output[i].bridgeAdapter = input[i].bridgeAdapter; + output[i].chainIds = input[i].chainIds; + } + return output; + } + + function _chainIds() internal pure returns (uint256[CHAIN_IDS_COUNT] memory) { + uint256[CHAIN_IDS_COUNT] memory chainIds; + chainIds[0] = ChainIds.ETHEREUM; + chainIds[1] = ChainIds.POLYGON; + chainIds[2] = ChainIds.AVALANCHE; + chainIds[3] = ChainIds.ARBITRUM; + chainIds[4] = ChainIds.OPTIMISM; + chainIds[5] = ChainIds.FANTOM; + chainIds[6] = ChainIds.HARMONY; + chainIds[7] = ChainIds.METIS; + chainIds[8] = ChainIds.BNB; + return chainIds; + } + + function _adapterExistsInArray( + address adapter, + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory array + ) internal pure returns (bool) { + for (uint256 i = 0; i < array.length; ++i) { + if (array[i].bridgeAdapter == adapter) { + return true; + } + } + return false; + } + + function _trimAdapterArray( + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory input, + uint256 length + ) internal pure returns (ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory) { + ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] + memory output = new ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[](length); + for (uint256 i = 0; i < length; ++i) { + output[i] = input[i]; + } + return output; + } + + function _trimChainIdArray( + uint256[] memory input, + uint256 length + ) internal pure returns (uint256[] memory) { + uint256[] memory output = new uint256[](length); + for (uint256 i = 0; i < length; ++i) { + output[i] = input[i]; + } + return output; + } +} + +contract CreateSolveEmergencyPayloadPrePopulated is Script { + function run() public { + vm.startBroadcast(vm.envUint('PRIVATE_KEY')); + SolveEmergencyPayloadPrePopulated solveEmergencyPayloadPrePopulated = new SolveEmergencyPayloadPrePopulated( + CROSS_CHAIN_CONTROLLER + ); + console2.log( + 'SolveEmergencyPayloadPrePopulated deployed at %s on chain with chain ID %s', + address(solveEmergencyPayloadPrePopulated), + block.chainid + ); + vm.stopBroadcast(); + } +}