Arbitrum Timelock
Last updated
Last updated
This example showcases how FPS can be utilized for simulating proposals for the Arbitrum timelock on mainnet. Specifically, it upgrades the WETH gateway on L1. The proposal involves deploying a new implementation contract ARBITRUM_L1_WETH_GATEWAY_IMPLEMENTATION
and a governance action contract ARBITRUM_GAC_UPGRADE_WETH_GATEWAY
. Then, the timelock employs upgradeExecutor
to upgrade the WETH gateway. The proposer for the L1 timelock should always be the Arbitrum bridge.
The relevant contract can be found in the .
Let's review each of the overridden functions:
name()
: Defines the name of the proposal.
description()
: Provides a detailed description of the proposal.
deploy()
: This function demonstrates the deployment of a new MockUpgrade, which will be used as the new implementation for the WETH Gateway Proxy and a new GAC contract for the upgrade.
preBuildMock()
: Post-deployment mock actions, such as setting a new outBox
for Arbitrum bridge
using vm.store
foundry cheatcode.
build()
: Add actions to the proposal contract. In this example, ARBITRUM_L1_WETH_GATEWAY_PROXY
is upgraded to the new implementation. The actions should be written in solidity code and in the order they should be executed. Any calls (except to the Addresses object) will be recorded and stored as actions to execute in the run function. The caller
address is passed into buildModifier
; it will call the actions in build
. The caller is the Arbitrum timelock in this example. The buildModifier
is a necessary modifier for the build
function and will not work without it. For further reading, see the .
run()
: Sets up the environment for running the proposal, and executes all proposal actions. This sets addresses
, primaryForkId
, and timelock
and calls super.run()
to run the entire proposal. In this example, primaryForkId
is set to mainnet
and the fork for running the proposal is selected. Next, the addresses
object is set by reading the JSON file. The timelock contract to test is set using setTimelock
. This will be used to check onchain calldata and simulate the proposal. For further reading, see the .
simulate()
: Executes the proposal actions outlined in the build()
step. This function performs a call to _simulateActions
from the inherited TimelockProposal
contract. Internally, _simulateActions()
simulates a call to Timelock and with the calldata generated from the actions set up in the build step.
validate()
: Validates that the implementation is upgraded correctly.
All required addresses should be in the JSON file, including DEPLOYER_EOA
address, which will deploy the new contracts. If these do not align, the script execution will fail.
The script will output the following:
It is crucial to note that two new addresses have been added to the Addresses.sol
storage. These addresses are not included in the JSON files when proposal is run without the DO_UPDATE_ADDRESS_JSON
flag set to true.