Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: forwarder contract for metis #86

Merged
merged 16 commits into from
Apr 26, 2023
Merged
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
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ RPC_POLYGON=https://polygon-rpc.com
RPC_ARBITRUM=https://arb1.arbitrum.io/rpc
RPC_FANTOM=https://rpc.ftm.tools
RPC_HARMONY=https://api.harmony.one
RPC_METIS=https://andromeda.metis.io/

ETHERSCAN_API_KEY_MAINNET=
ETHERSCAN_API_KEY_POLYGON=
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ deploy-engine-opt :; forge script scripts/AaveV3ConfigEngine.s.sol:DeployEngine
deploy-engine-arb :; forge script scripts/AaveV3ConfigEngine.s.sol:DeployEngineArb --rpc-url arbitrum --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-engine-pol :; forge script scripts/AaveV3ConfigEngine.s.sol:DeployEnginePol --rpc-url polygon --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-engine-ava :; forge script scripts/AaveV3ConfigEngine.s.sol:DeployEngineAva --rpc-url avalanche --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-engine-met :; forge script scripts/AaveV3ConfigEngine.s.sol:DeployEngineMet --rpc-url metis --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-rates-factory-eth :; forge script scripts/V3RateStrategyFactory.s.sol:DeployRatesFactoryEth --rpc-url mainnet --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-rates-factory-pol :; forge script scripts/V3RateStrategyFactory.s.sol:DeployRatesFactoryPol --rpc-url polygon --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-rates-factory-opt :; forge script scripts/V3RateStrategyFactory.s.sol:DeployRatesFactoryOpt --rpc-url optimism --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-rates-factory-arb :; forge script scripts/V3RateStrategyFactory.s.sol:DeployRatesFactoryArb --rpc-url arbitrum --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-rates-factory-ava :; forge script scripts/V3RateStrategyFactory.s.sol:DeployRatesFactoryAva --rpc-url avalanche --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-rates-factory-met :; forge script scripts/V3RateStrategyFactory.s.sol:DeployRatesFactoryMet --rpc-url metis --broadcast --legacy --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-forwarder-pol :; forge script scripts/CrosschainForwarders.s.sol:DeployPol --rpc-url mainnet --broadcast --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-forwarder-opt :; forge script scripts/CrosschainForwarders.s.sol:DeployOpt --rpc-url mainnet --broadcast --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-forwarder-arb :; forge script scripts/CrosschainForwarders.s.sol:DeployArb --rpc-url mainnet --broadcast --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv
deploy-forwarder-met :; forge script scripts/CrosschainForwarders.s.sol:DeployMet --rpc-url mainnet --broadcast --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify -vvvv

# Utilities
download :; cast etherscan-source --chain ${chain} -d src/etherscan/${chain}_${address} ${address}
Expand Down
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ polygon = "${RPC_POLYGON}"
arbitrum = "${RPC_ARBITRUM}"
fantom = "${RPC_FANTOM}"
harmony = "${RPC_HARMONY}"
metis = "${RPC_METIS}"

[etherscan]
mainnet={key="${ETHERSCAN_API_KEY_MAINNET}",chainId=1}
Expand Down
2 changes: 1 addition & 1 deletion lib/aave-address-book
Submodule aave-address-book updated 67 files
+12 −0 CHANGELOG.md
+2 −4 README.md
+1 −1 package.json
+30 −0 scripts/config.ts
+2 −17 scripts/generator_v2.ts
+106 −78 scripts/generator_v3.ts
+7 −0 scripts/helpers.ts
+1 −0 src/AaveAddressBook.sol
+4 −0 src/AaveGovernanceV2.sol
+3 −0 src/AaveMisc.sol
+2 −3 src/AaveV2Avalanche.sol
+2 −3 src/AaveV2Ethereum.sol
+2 −3 src/AaveV2EthereumAMM.sol
+2 −3 src/AaveV2EthereumArc.sol
+2 −3 src/AaveV2Fuji.sol
+2 −3 src/AaveV2Goerli.sol
+2 −3 src/AaveV2Mumbai.sol
+2 −3 src/AaveV2Polygon.sol
+0 −58 src/AaveV3.sol
+5 −5 src/AaveV3Arbitrum.sol
+5 −5 src/AaveV3ArbitrumGoerli.sol
+9 −9 src/AaveV3Avalanche.sol
+17 −5 src/AaveV3Ethereum.sol
+5 −5 src/AaveV3Fantom.sol
+5 −5 src/AaveV3FantomTestnet.sol
+5 −5 src/AaveV3Fuji.sol
+5 −5 src/AaveV3Goerli.sol
+5 −5 src/AaveV3GoerliGho.sol
+5 −5 src/AaveV3Harmony.sol
+70 −0 src/AaveV3Metis.sol
+5 −5 src/AaveV3Mumbai.sol
+5 −5 src/AaveV3Optimism.sol
+5 −5 src/AaveV3OptimismGoerli.sol
+5 −5 src/AaveV3Polygon.sol
+5 −5 src/AaveV3ScrollAlpha.sol
+5 −5 src/AaveV3Sepolia.sol
+187 −0 src/common/ICollector.sol
+2 −6 src/test/AaveV2Ethereum.t.sol
+0 −8 src/test/AaveV2Misfits.t.sol
+2 −6 src/test/AaveV3Avalanche.t.sol
+1 −0 src/ts/AaveAddressBook.ts
+2 −0 src/ts/AaveGovernanceV2.ts
+0 −1 src/ts/AaveV2Avalanche.ts
+0 −1 src/ts/AaveV2Ethereum.ts
+0 −1 src/ts/AaveV2EthereumAMM.ts
+0 −1 src/ts/AaveV2EthereumArc.ts
+0 −1 src/ts/AaveV2Fuji.ts
+0 −1 src/ts/AaveV2Goerli.ts
+0 −1 src/ts/AaveV2Mumbai.ts
+1 −2 src/ts/AaveV2Polygon.ts
+1 −1 src/ts/AaveV3Arbitrum.ts
+1 −1 src/ts/AaveV3ArbitrumGoerli.ts
+1 −1 src/ts/AaveV3Avalanche.ts
+1 −1 src/ts/AaveV3Ethereum.ts
+1 −1 src/ts/AaveV3Fantom.ts
+1 −1 src/ts/AaveV3FantomTestnet.ts
+1 −1 src/ts/AaveV3Fuji.ts
+1 −1 src/ts/AaveV3Goerli.ts
+1 −1 src/ts/AaveV3GoerliGho.ts
+1 −1 src/ts/AaveV3Harmony.ts
+23 −0 src/ts/AaveV3Metis.ts
+1 −1 src/ts/AaveV3Mumbai.ts
+1 −1 src/ts/AaveV3Optimism.ts
+1 −1 src/ts/AaveV3OptimismGoerli.ts
+1 −1 src/ts/AaveV3Polygon.ts
+1 −1 src/ts/AaveV3ScrollAlpha.ts
+1 −1 src/ts/AaveV3Sepolia.ts
2 changes: 1 addition & 1 deletion lib/forge-std
37 changes: 32 additions & 5 deletions scripts/AaveV3ConfigEngine.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {AaveV3Optimism} from 'aave-address-book/AaveV3Optimism.sol';
import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol';
import {AaveV3Polygon} from 'aave-address-book/AaveV3Polygon.sol';
import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol';
import {AaveV3Metis} from 'aave-address-book/AaveV3Metis.sol';
import {IPool, IPoolConfigurator, IAaveOracle} from 'aave-address-book/AaveV3.sol';

library DeployEngineEthLib {
function deploy() internal returns (address) {
Expand All @@ -22,7 +24,7 @@ library DeployEngineEthLib {
AaveV3Ethereum.DEFAULT_VARIABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Ethereum.DEFAULT_STABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Ethereum.DEFAULT_INCENTIVES_CONTROLLER,
AaveV3Ethereum.COLLECTOR,
address(AaveV3Ethereum.COLLECTOR),
IV3RateStrategyFactory(AaveV3Ethereum.RATES_FACTORY)
)
);
Expand All @@ -41,7 +43,7 @@ library DeployEngineOptLib {
AaveV3Optimism.DEFAULT_VARIABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Optimism.DEFAULT_STABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Optimism.DEFAULT_INCENTIVES_CONTROLLER,
AaveV3Optimism.COLLECTOR,
address(AaveV3Optimism.COLLECTOR),
IV3RateStrategyFactory(AaveV3Optimism.RATES_FACTORY)
)
);
Expand All @@ -60,7 +62,7 @@ library DeployEngineArbLib {
AaveV3Arbitrum.DEFAULT_VARIABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Arbitrum.DEFAULT_STABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Arbitrum.DEFAULT_INCENTIVES_CONTROLLER,
AaveV3Arbitrum.COLLECTOR,
address(AaveV3Arbitrum.COLLECTOR),
IV3RateStrategyFactory(AaveV3Arbitrum.RATES_FACTORY)
)
);
Expand All @@ -79,7 +81,7 @@ library DeployEnginePolLib {
AaveV3Polygon.DEFAULT_VARIABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Polygon.DEFAULT_STABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Polygon.DEFAULT_INCENTIVES_CONTROLLER,
AaveV3Polygon.COLLECTOR,
address(AaveV3Polygon.COLLECTOR),
IV3RateStrategyFactory(AaveV3Polygon.RATES_FACTORY)
)
);
Expand All @@ -98,13 +100,32 @@ library DeployEngineAvaLib {
AaveV3Avalanche.DEFAULT_VARIABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Avalanche.DEFAULT_STABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Avalanche.DEFAULT_INCENTIVES_CONTROLLER,
AaveV3Avalanche.COLLECTOR,
address(AaveV3Avalanche.COLLECTOR),
IV3RateStrategyFactory(AaveV3Avalanche.RATES_FACTORY)
)
);
}
}

library DeployEngineMetLib {
function deploy() internal returns (address) {
return
address(
new AaveV3ConfigEngine(
AaveV3Metis.POOL,
AaveV3Metis.POOL_CONFIGURATOR,
AaveV3Metis.ORACLE,
AaveV3Metis.DEFAULT_A_TOKEN_IMPL_REV_1,
AaveV3Metis.DEFAULT_VARIABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Metis.DEFAULT_STABLE_DEBT_TOKEN_IMPL_REV_1,
AaveV3Metis.DEFAULT_INCENTIVES_CONTROLLER,
address(AaveV3Metis.COLLECTOR),
IV3RateStrategyFactory(AaveV3Metis.RATES_FACTORY)
)
);
}
}

contract DeployEngineEth is EthereumScript {
function run() external broadcast {
DeployEngineEthLib.deploy();
Expand Down Expand Up @@ -134,3 +155,9 @@ contract DeployEngineAva is AvalancheScript {
DeployEngineAvaLib.deploy();
}
}

contract DeployEngineMet is MetisScript {
function run() external broadcast {
DeployEngineMetLib.deploy();
}
}
7 changes: 7 additions & 0 deletions scripts/CrosschainForwarders.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import '../src/ScriptUtils.sol';
import {CrosschainForwarderPolygon} from '../src/crosschainforwarders/CrosschainForwarderPolygon.sol';
import {CrosschainForwarderOptimism} from '../src/crosschainforwarders/CrosschainForwarderOptimism.sol';
import {CrosschainForwarderArbitrum} from '../src/crosschainforwarders/CrosschainForwarderArbitrum.sol';
import {CrosschainForwarderMetis} from '../src/crosschainforwarders/CrosschainForwarderMetis.sol';

contract DeployPol is EthereumScript {
function run() external broadcast {
Expand All @@ -23,3 +24,9 @@ contract DeployArb is EthereumScript {
new CrosschainForwarderArbitrum();
}
}

contract DeployMet is EthereumScript {
function run() external broadcast {
new CrosschainForwarderMetis();
}
}
18 changes: 18 additions & 0 deletions scripts/V3RateStrategyFactory.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {AaveV3Optimism} from 'aave-address-book/AaveV3Optimism.sol';
import {AaveV3Arbitrum} from 'aave-address-book/AaveV3Arbitrum.sol';
import {AaveV3Polygon} from 'aave-address-book/AaveV3Polygon.sol';
import {AaveV3Avalanche} from 'aave-address-book/AaveV3Avalanche.sol';
import {AaveV3Metis} from 'aave-address-book/AaveV3Metis.sol';
import {ITransparentProxyFactory} from 'solidity-utils/contracts/transparent-proxy/interfaces/ITransparentProxyFactory.sol';
import {V3RateStrategyFactory} from '../src/v3-config-engine/V3RateStrategyFactory.sol';

Expand Down Expand Up @@ -128,6 +129,17 @@ library DeployRatesFactoryAvaLib {
}
}

library DeployRatesFactoryMetLib {
function deploy() internal returns (address, address[] memory) {
return
DeployRatesFactoryLib._createAndSetupRatesFactory(
AaveV3Metis.POOL_ADDRESSES_PROVIDER,
AaveMisc.TRANSPARENT_PROXY_FACTORY_METIS,
AaveMisc.PROXY_ADMIN_METIS
);
}
}

contract DeployRatesFactoryEth is EthereumScript {
function run() external broadcast {
DeployRatesFactoryEthLib.deploy();
Expand Down Expand Up @@ -157,3 +169,9 @@ contract DeployRatesFactoryAva is AvalancheScript {
DeployRatesFactoryAvaLib.deploy();
}
}

contract DeployRatesFactoryMet is MetisScript {
function run() external broadcast {
DeployRatesFactoryMetLib.deploy();
}
}
10 changes: 9 additions & 1 deletion src/GovHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ library GovHelpers {
});
}

function buildMetis(address payloadAddress) internal pure returns (Payload memory) {
return
_buildL2({
forwarder: AaveGovernanceV2.CROSSCHAIN_FORWARDER_METIS,
payloadAddress: payloadAddress
});
}

function _buildL2(address forwarder, address payloadAddress)
private
pure
Expand Down Expand Up @@ -338,7 +346,7 @@ contract MockExecutor {
* @notice Non-standard functionality used to skip governance and just execute a payload.
*/
function execute(address payload) public {
(bool success, ) = address(payload).delegatecall(abi.encodeWithSignature('execute()'));
(bool success, ) = payload.delegatecall(abi.encodeWithSignature('execute()'));
require(success, 'PROPOSAL_EXECUTION_FAILED');
}

Expand Down
4 changes: 4 additions & 0 deletions src/ScriptUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ abstract contract FantomScript is WithChainIdValidation {
abstract contract HarmonyScript is WithChainIdValidation {
constructor() WithChainIdValidation(1666600000) {}
}

abstract contract MetisScript is WithChainIdValidation {
constructor() WithChainIdValidation(1088) {}
}
67 changes: 67 additions & 0 deletions src/crosschainforwarders/CrosschainForwarderMetis.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// 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';

/**
* @title A generic executor for proposals targeting the metis v3 pool
* @author BGD Labs
* @notice You can **only** use this executor when the metis payload has a `execute()` signature without parameters
* @notice You can **only** use this executor when the metis payload is expected to be executed via `DELEGATECALL`
* @notice The L2CrossDomainMessenger can **only** queue an action on metis with up to a max gas which is specified in `MAX_GAS_LIMIT`.
* It encodes and sends via the L2CrossDomainMessenger a message to queue for execution an action on L2, in the Aave METIS_BRIDGE_EXECUTOR.
*/
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.
*/
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
*/
address public constant METIS_BRIDGE_EXECUTOR = AaveGovernanceV2.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;

/**
* @dev this function will be executed once the proposal passes the mainnet vote.
* @param l2PayloadContract the metis contract containing the `execute()` signature.
*/
function execute(address l2PayloadContract) public {
address[] memory targets = new address[](1);
targets[0] = l2PayloadContract;
uint256[] memory values = new uint256[](1);
values[0] = 0;
string[] memory signatures = new string[](1);
signatures[0] = 'execute()';
bytes[] memory calldatas = new bytes[](1);
calldatas[0] = '';
bool[] memory withDelegatecalls = new bool[](1);
withDelegatecalls[0] = true;

bytes memory queue = abi.encodeWithSelector(
IL2BridgeExecutor.queue.selector,
targets,
values,
signatures,
calldatas,
withDelegatecalls
);
ICrossDomainMessenger(L1_CROSS_DOMAIN_MESSENGER_ADDRESS).sendMessage(
METIS_BRIDGE_EXECUTOR,
queue,
MAX_GAS_LIMIT
);
}
}
13 changes: 12 additions & 1 deletion src/crosschainforwarders/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## About

To simplify the process of creating a cross-chain proposal this repository contains opinionated `CrosschainForwarder` contracts for `Polygon`, `Optimism` and `Arbitrum` abstracting away the complexity of bridging & cross-chain gas calculations.
To simplify the process of creating a cross-chain proposal this repository contains opinionated `CrosschainForwarder` contracts for `Polygon`, `Optimism`, `Metis` and `Arbitrum` abstracting away the complexity of bridging & cross-chain gas calculations.
All the forwarders follow the same pattern. They expect a payload to be deployed on L2 and to be executed with a parameterless `execute()` signature and via `DELEGATECALL`.

![visualization](./bridge-listing.png)
Expand All @@ -17,6 +17,13 @@ Once the state is synced to `FX_CHILD` on Polygon network it will queue the payl
For a proposal to be executed on Optimism it needs to pass a mainnet governance proposal that sends an encoded payload via `sendMessage(address,bytes,uint32)` on [L1_CROSS_DOMAIN_MESSENGER](https://etherscan.io/address/0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1)(mainnet) to [L2_CROSS_DOMAIN_MESSENGER](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000007#code)(Optimism).
Once the state is `L2_CROSS_DOMAIN_MESSENGER` on Optimism it will queue the payload on [OPTIMISM_BRIDGE_EXECUTOR](https://optimistic.etherscan.io/address/0x7d9103572bE58FfE99dc390E8246f02dcAe6f611).

### Metis

Similar to Optimism, for a proposal to be executed on Metis it needs to pass a mainnet governance proposal that sends an encoded payload via `sendMessage(address,bytes,uint32)` on [L1_CROSS_DOMAIN_MESSENGER](https://etherscan.io/address/0x081D1101855bD523bA69A9794e0217F0DB6323ff)(mainnet) to [L2_CROSS_DOMAIN_MESSENGER](https://andromeda-explorer.metis.io/address/0x4200000000000000000000000000000000000007)(Metis).
Once the state is `L2_CROSS_DOMAIN_MESSENGER` on Metis it will queue the payload on [METIS_BRIDGE_EXECUTOR](https://andromeda-explorer.metis.io/address/0x8EC77963068474a45016938Deb95E603Ca82a029).

Caveat: Opposed to the other messenger like on Optimism, using the Metis messenger requires a whitelist by the Metis team. The [SHORT_EXECUTOR](https://etherscan.io/address/0xEE56e2B3D491590B5b31738cC34d5232F378a8D5) has been whitelisted to use the messenger. Also, the gas to queue the payload by the messenger has been hardcoded to 5 million, which seems reasonable considering the queue transaction. Unlike Optimism, the Metis messenger has no limit on gas, and everything is prepaid.

### Arbitrum

For a proposal to be executed on Arbitrum it needs to pass a mainnet governance proposal that sends an encoded payload via `unsafeCreateRetryableTicket{value: uint256}(address,uint256,uint256,address,address,uint256,uint256,bytes)` on [INBOX](https://etherscan.io/address/0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f)(mainnet). The Arbitrum bridge will then call the bridged calldata via the L2_ALIAS of the mainnet `msg.sender` (in this case is the aliased mainnet governance executor) which will queue the payload on [ARBITRUM_BRIDGE_EXECUTOR](https://arbiscan.io/address/0x7d9103572bE58FfE99dc390E8246f02dcAe6f611).
Expand All @@ -31,6 +38,7 @@ You can check if you need to top-up the SHORT_EXECUTOR by calling `getRequiredGa

- [CrosschainForwarderPolygon](https://etherscan.io/address/0x158a6bc04f0828318821bae797f50b0a1299d45b#code)
- [CrosschainForwarderOptimism](https://etherscan.io/address/0x5f5c02875a8e9b5a26fbd09040abcfdeb2aa6711#code)
- [CrosschainForwarderMetis](https://etherscan.io/address/0x2fE52eF191F0BE1D98459BdaD2F1d3160336C08f#code)
- [CrosschainForwarderArbitrum](https://etherscan.io/address/0x2e2B1F112C4D79A9D22464F0D345dE9b792705f1#code)

## References
Expand All @@ -41,6 +49,9 @@ You can check if you need to top-up the SHORT_EXECUTOR by calling `getRequiredGa
- [OptimismBridge: L1CrossDomainMessenger](https://etherscan.io/address/0x25ace71c97b33cc4729cf772ae268934f7ab5fa1#readProxyContract)
- [OptimismBridge: OptimismBridgeExecutor](https://optimistic.etherscan.io/address/0x7d9103572be58ffe99dc390e8246f02dcae6f611#code)

- [MetisBridge: L1CrossDomainMessenger](https://etherscan.io/address/0x081D1101855bD523bA69A9794e0217F0DB6323ff#code)
- [MetisBridge: MetisBridgeExecutor](https://andromeda-explorer.metis.io/address/0x8EC77963068474a45016938Deb95E603Ca82a029/contracts#address-tabs)

- [ArbitrumBridge: Inbox](https://etherscan.io/address/0x4dbd4fc535ac27206064b68ffcf827b0a60bab3f#code)
- [ArtitrumBridge: ArbitrumBridgeExecutor](https://arbiscan.io/address/0x7d9103572be58ffe99dc390e8246f02dcae6f611#code)

Expand Down
Loading