Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions scripts/CrosschainForwarders.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,28 @@ import {CrosschainForwarderOptimism} from '../src/crosschainforwarders/Crosschai
import {CrosschainForwarderArbitrum} from '../src/crosschainforwarders/CrosschainForwarderArbitrum.sol';
import {CrosschainForwarderMetis} from '../src/crosschainforwarders/CrosschainForwarderMetis.sol';

import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol';

contract DeployPol is EthereumScript {
function run() external broadcast {
new CrosschainForwarderPolygon();
new CrosschainForwarderPolygon(AaveGovernanceV2.POLYGON_BRIDGE_EXECUTOR);
}
}

contract DeployOpt is EthereumScript {
function run() external broadcast {
new CrosschainForwarderOptimism();
new CrosschainForwarderOptimism(AaveGovernanceV2.OPTIMISM_BRIDGE_EXECUTOR);
}
}

contract DeployArb is EthereumScript {
function run() external broadcast {
new CrosschainForwarderArbitrum();
new CrosschainForwarderArbitrum(AaveGovernanceV2.ARBITRUM_BRIDGE_EXECUTOR);
}
}

contract DeployMet is EthereumScript {
function run() external broadcast {
new CrosschainForwarderMetis();
new CrosschainForwarderMetis(AaveGovernanceV2.METIS_BRIDGE_EXECUTOR);
}
}
23 changes: 14 additions & 9 deletions src/crosschainforwarders/CrosschainForwarderArbitrum.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol';
import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol';
import {IInbox} from 'governance-crosschain-bridges/contracts/dependencies/arbitrum/interfaces/IInbox.sol';
import {IL2BridgeExecutor} from 'governance-crosschain-bridges/contracts/interfaces/IL2BridgeExecutor.sol';

Expand All @@ -11,16 +9,15 @@ import {IL2BridgeExecutor} from 'governance-crosschain-bridges/contracts/interfa
* @author BGD Labs
* @notice You can **only** use this executor when the arbitrum payload has a `execute()` signature without parameters
* @notice You can **only** use this executor when the arbitrum payload is expected to be executed via `DELEGATECALL`
* @notice This contract assumes to be called via AAVE Governance V2
* @notice This contract will assume the SHORT_EXECUTOR will be topped up with enough funds to fund the short executor
* @notice This contract will assume the caller will be topped up with enough funds to fund the message relay
* @dev This executor is a generic wrapper to be used with Arbitrum Inbox (https://developer.offchainlabs.com/arbos/l1-to-l2-messaging)
* It encodes a parameterless `execute()` with delegate calls and a specified target.
* This encoded abi is then send to the Inbox to be synced executed on the arbitrum network.
* Once synced the ARBITRUM_BRIDGE_EXECUTOR will queue the execution of the payload.
*/
contract CrosschainForwarderArbitrum {
IInbox public constant INBOX = IInbox(0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f);
address public constant ARBITRUM_BRIDGE_EXECUTOR = AaveGovernanceV2.ARBITRUM_BRIDGE_EXECUTOR;
address public immutable ARBITRUM_BRIDGE_EXECUTOR;
address public constant ARBITRUM_GUARDIAN = 0xbbd9f90699c1FA0D7A65870D241DD1f1217c96Eb;

// amount of gwei to overpay on basefee for fast submission
Expand All @@ -37,6 +34,13 @@ contract CrosschainForwarderArbitrum {
*/
uint256 public constant L2_MAX_FEE_PER_GAS = 1 gwei;

/**
* @param bridgeExecutor The L2 executor
*/
constructor(address bridgeExecutor) {
ARBITRUM_BRIDGE_EXECUTOR = bridgeExecutor;
}

/**
* @dev returns the amount of gas needed for submitting the ticket
* @param bytesLength the payload bytes length (usually 580)
Expand All @@ -51,16 +55,17 @@ contract CrosschainForwarderArbitrum {
}

/**
* @dev checks if the short executor is topped up with enough eth for proposal execution
* @dev checks if the executor is topped up with enough eth for proposal execution
* with current basefee
* @param executor the address to check for sufficient gas
* @param bytesLength the payload bytes length (usually 580)
* @return bool indicating if the SHORT_EXECUTOR has sufficient funds
* @return bool indicating if the caller has sufficient funds
* @return uint256 the gas required for ticket creation and redemption
*/
function hasSufficientGasForExecution(uint256 bytesLength) public view returns (bool, uint256) {
function hasSufficientGasForExecution(address executor, uint256 bytesLength) public view returns (bool, uint256) {
(uint256 maxSubmission, uint256 maxRedemption) = getRequiredGas(bytesLength);
uint256 requiredGas = maxSubmission + maxRedemption;
return (AaveGovernanceV2.SHORT_EXECUTOR.balance >= requiredGas, requiredGas);
return (executor.balance >= requiredGas, requiredGas);
}

/**
Expand Down
15 changes: 10 additions & 5 deletions src/crosschainforwarders/CrosschainForwarderMetis.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveGovernanceV2} from 'aave-address-book/AaveGovernanceV2.sol';
import {ICrossDomainMessenger} from 'governance-crosschain-bridges/contracts/dependencies/optimism/interfaces/ICrossDomainMessenger.sol';
import {IL2BridgeExecutor} from 'governance-crosschain-bridges/contracts/interfaces/IL2BridgeExecutor.sol';

Expand All @@ -16,24 +15,30 @@ import {IL2BridgeExecutor} from 'governance-crosschain-bridges/contracts/interfa
contract CrosschainForwarderMetis {
/**
* @dev The L1 Cross Domain Messenger contract sends messages from L1 to L2, and relays messages
* from L2 onto L1. In this contract it's used by the governance SHORT_EXECUTOR to send the encoded L2 queuing over the bridge.
* from L2 onto L1. In this contract it's used to send the encoded L2 queuing over the bridge.
*/
address public constant L1_CROSS_DOMAIN_MESSENGER_ADDRESS =
0x081D1101855bD523bA69A9794e0217F0DB6323ff;

/**
* @dev The metis bridge executor is a L2 governance execution contract.
* This contract allows queuing of proposals by allow listed addresses (in this case the L1 short executor).
* https://andromeda-explorer.metis.io/address/0x8EC77963068474a45016938Deb95E603Ca82a029
* This contract allows queuing of proposals by allow listed addresses.
*/
address public constant METIS_BRIDGE_EXECUTOR = AaveGovernanceV2.METIS_BRIDGE_EXECUTOR;
address public immutable METIS_BRIDGE_EXECUTOR;

/**
* @dev The gas limit of the queue transaction by the L2CrossDomainMessenger on L2.
* The limit seems reasonable considering the queue transaction, as all gas limits are prepaid.
*/
uint32 public constant MAX_GAS_LIMIT = 5_000_000;

/**
* @param bridgeExecutor The L2 executor
*/
constructor(address bridgeExecutor) {
METIS_BRIDGE_EXECUTOR = bridgeExecutor;
}

/**
* @dev this function will be executed once the proposal passes the mainnet vote.
* @param l2PayloadContract the metis contract containing the `execute()` signature.
Expand Down
14 changes: 10 additions & 4 deletions src/crosschainforwarders/CrosschainForwarderOptimism.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,16 @@ interface ICanonicalTransactionChain {
contract CrosschainForwarderOptimism {
/**
* @dev The L1 Cross Domain Messenger contract sends messages from L1 to L2, and relays messages
* from L2 onto L1. In this contract it's used by the governance SHORT_EXECUTOR to send the encoded L2 queuing over the bridge.
* from L2 onto L1. In this contract it's used to send the encoded L2 queuing over the bridge.
*/
address public constant L1_CROSS_DOMAIN_MESSENGER_ADDRESS =
0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1;

/**
* @dev The optimism bridge executor is a L2 governance execution contract.
* This contract allows queuing of proposals by allow listed addresses (in this case the L1 short executor).
* https://optimistic.etherscan.io/address/0x7d9103572bE58FfE99dc390E8246f02dcAe6f611
* This contract allows queuing of proposals by allow listed addresses.
*/
address public constant OPTIMISM_BRIDGE_EXECUTOR = 0x7d9103572bE58FfE99dc390E8246f02dcAe6f611;
address public immutable OPTIMISM_BRIDGE_EXECUTOR;

/**
* @dev The CTC contract is an append only log of transactions which must be applied to the rollup state.
Expand All @@ -41,6 +40,13 @@ contract CrosschainForwarderOptimism {
ICanonicalTransactionChain public constant CANONICAL_TRANSACTION_CHAIN =
ICanonicalTransactionChain(0x5E4e65926BA27467555EB562121fac00D24E9dD2);

/**
* @param bridgeExecutor The L2 executor
*/
constructor(address bridgeExecutor) {
OPTIMISM_BRIDGE_EXECUTOR = bridgeExecutor;
}

/**
* @dev this function will be executed once the proposal passes the mainnet vote.
* @param l2PayloadContract the optimism contract containing the `execute()` signature.
Expand Down
9 changes: 8 additions & 1 deletion src/crosschainforwarders/CrosschainForwarderPolygon.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ import {IFxStateSender} from 'governance-crosschain-bridges/contracts/dependenci
*/
contract CrosschainForwarderPolygon {
address public constant FX_ROOT_ADDRESS = 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2;
address public constant POLYGON_BRIDGE_EXECUTOR = 0xdc9A35B16DB4e126cFeDC41322b3a36454B1F772;
address public immutable POLYGON_BRIDGE_EXECUTOR;

/**
* @param bridgeExecutor The executor
*/
constructor(address bridgeExecutor) {
POLYGON_BRIDGE_EXECUTOR = bridgeExecutor;
}

/**
* @dev this function will be executed once the proposal passes the mainnet vote.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ contract ArbitrumCrossChainForwarderTest is ProtocolV3TestBase {

function setUp() public {
mainnetFork = vm.createSelectFork(vm.rpcUrl('mainnet'), 16128510);
forwarder = new CrosschainForwarderArbitrum();
forwarder = new CrosschainForwarderArbitrum(ARBITRUM_BRIDGE_EXECUTOR);
arbitrumFork = vm.createSelectFork(vm.rpcUrl('arbitrum'), 76261612);
payloadWithEmit = new PayloadWithEmit();
}
Expand All @@ -48,10 +48,10 @@ contract ArbitrumCrossChainForwarderTest is ProtocolV3TestBase {
function testHasSufficientGas() public {
vm.selectFork(mainnetFork);
assertEq(AaveGovernanceV2.SHORT_EXECUTOR.balance, 0);
(bool hasEnoughGasBefore, ) = forwarder.hasSufficientGasForExecution(580);
(bool hasEnoughGasBefore, ) = forwarder.hasSufficientGasForExecution(AaveGovernanceV2.SHORT_EXECUTOR, 580);
assertEq(hasEnoughGasBefore, false);
deal(address(AaveGovernanceV2.SHORT_EXECUTOR), 0.001 ether);
(bool hasEnoughGasAfter, ) = forwarder.hasSufficientGasForExecution(580);
(bool hasEnoughGasAfter, ) = forwarder.hasSufficientGasForExecution(AaveGovernanceV2.SHORT_EXECUTOR, 580);
assertEq(hasEnoughGasAfter, true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ contract MetisCrossChainForwarderTest is ProtocolV3TestBase {

function setUp() public {
mainnetFork = vm.createSelectFork(vm.rpcUrl('mainnet'), 17093477);
forwarder = new CrosschainForwarderMetis();
forwarder = new CrosschainForwarderMetis(METIS_BRIDGE_EXECUTOR);
metisFork = vm.createSelectFork(vm.rpcUrl('metis'), 5428548);
payloadWithEmit = new PayloadWithEmit();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ contract OptimismCrossChainForwarderTest is ProtocolV3TestBase {

function setUp() public {
mainnetFork = vm.createSelectFork(vm.rpcUrl('mainnet'), 15783218);
forwarder = new CrosschainForwarderOptimism();
forwarder = new CrosschainForwarderOptimism(OPTIMISM_BRIDGE_EXECUTOR);
optimismFork = vm.createSelectFork(vm.rpcUrl('optimism'), 30264427);
payloadWithEmit = new PayloadWithEmit();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ contract PolygonCrossChainForwarderTest is ProtocolV3TestBase {

function setUp() public {
mainnetFork = vm.createSelectFork(vm.rpcUrl('mainnet'), 15275388);
forwarder = new CrosschainForwarderPolygon();
forwarder = new CrosschainForwarderPolygon(POLYGON_BRIDGE_EXECUTOR);
polygonFork = vm.createSelectFork(vm.rpcUrl('polygon'), 31507646);
payloadWithEmit = new PayloadWithEmit();
}
Expand Down