Skip to content

Latest commit

 

History

History
357 lines (284 loc) · 20.1 KB

timelock.org

File metadata and controls

357 lines (284 loc) · 20.1 KB

By default the Kurtosis CDK package will deploy a timelock contract that can be used as an admin. For the sake of simplified testing, we don’t configure the timelock as the primary admin of the rollup manager. We want to show how you could use the timelock in order to get a better understanding.

Assuming that you’ve already full spun up your network, let’s get the details of our deployment.

kurtosis service exec cdk-v1 contracts-001 'cat /opt/zkevm/combined.json'
The command was successfully executed and returned '0'. Output was:
{
  "polygonRollupManagerAddress": "0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2",
  "polygonZkEVMBridgeAddress": "0xD71f8F956AD979Cc2988381B8A743a2fE280537D",
  "polygonZkEVMGlobalExitRootAddress": "0x1f7ad7caA53e35b4f0D138dC5CBF91aC108a2674",
  "polTokenAddress": "0xEdE9cf798E0fE25D35469493f43E88FeA4a5da0E",
  "zkEVMDeployerContract": "0xe5CF69183CFCF0571E733D59a1a53d4E6ceD6E85",
  "deployerAddress": "0xE34aaF64b29273B7D567FCFc40544c014EEe9970",
  "timelockContractAddress": "0x07783C37CAAFe0f05C4105250C032062A83F7AC2",
  "deploymentRollupManagerBlockNumber": 19,
  "upgradeToULxLyBlockNumber": 19,
  "admin": "0xE34aaF64b29273B7D567FCFc40544c014EEe9970",
  "trustedAggregator": "0xCae5b68Ff783594bDe1b93cdE627c741722c4D4d",
  "proxyAdminAddress": "0xB93b2fD69CE28f0DB91842aBFa40720d7e2B8fd7",
  "salt": "0x0000000000000000000000000000000000000000000000000000000000000001",
  "polygonDataCommitteeAddress": "0x5A6896A98c4B7C7E8f16d177C719a1d856b9154c",
  "firstBatchData": {
    "transactions": "0xf9010380808401c9c38094d71f8f956ad979cc2988381b8a743a2fe280537d80b8e4f811bff7000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005ca1ab1e0000000000000000000000000000000000000000000000000000000005ca1ab1e1bff",
    "globalExitRoot": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5",
    "timestamp": 1713829086,
    "sequencer": "0x5b06837A43bdC3dD9F114558DAf4B26ed49842Ed"
  },
  "genesis": "0xd619a27d32e3050f2265a3f58dd74c8998572812da4874aa052f0886d0dfaf47",
  "createRollupBlockNumber": 23,
  "rollupAddress": "0x1Fe038B54aeBf558638CA51C91bC8cCa06609e91",
  "verifierAddress": "0xf22E2B040B639180557745F47aB97dFA95B1e22a",
  "consensusContract": "PolygonValidiumEtrog",
  "polygonZkEVMGlobalExitRootL2Address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa"
}

In this case, it looks like my timelock is deployed at 0x07783C37CAAFe0f05C4105250C032062A83F7AC2.

Let’s confirm that the admin 0xE34aaF64b29273B7D567FCFc40544c014EEe9970 is actually a default admin for the rollup manager. First we need to check what the admin role is:

cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2 'DEFAULT_ADMIN_ROLE()(bytes32)'
0x0000000000000000000000000000000000000000000000000000000000000000

Now let’s see if the admin account has this role:

cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2 'hasRole(bytes32,address)(bool)' 0x0000000000000000000000000000000000000000000000000000000000000000 0xE34aaF64b29273B7D567FCFc40544c014EEe9970
true

Let’s also confirm that the time lock does not have the default admin role:

cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2 'hasRole(bytes32,address)(bool)' 0x0000000000000000000000000000000000000000000000000000000000000000 0x07783C37CAAFe0f05C4105250C032062A83F7AC2
false

Okay this looks good. Let’s first use the current admin account to grant admin access to the time lock:

cast send --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2 \
    --private-key 0x12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625 \
    'grantRole(bytes32,address)' 0x0000000000000000000000000000000000000000000000000000000000000000 0x07783C37CAAFe0f05C4105250C032062A83F7AC2
blockHash               0x2a6ab08a2e87865a177bd24d16c96513c54cd08814f57aa73199712f5c71d0c0
blockNumber             12342
contractAddress
cumulativeGasUsed       58147
effectiveGasPrice       3000000007
from                    0xE34aaF64b29273B7D567FCFc40544c014EEe9970
gasUsed                 58147
logs                    [{"address":"0x2f50ef6b8e8ee4e579b17619a92de3e2ffbd8ad2","topics":["0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d","0x0000000000000000000000000000000000000000000000000000000000000000","0x00000000000000000000000007783c37caafe0f05c4105250c032062a83f7ac2","0x000000000000000000000000e34aaf64b29273b7d567fcfc40544c014eee9970"],"data":"0x","blockHash":"0x2a6ab08a2e87865a177bd24d16c96513c54cd08814f57aa73199712f5c71d0c0","blockNumber":"0x3036","transactionHash":"0xef9151dadc11aed67dd567426a610b9ff04c88beaad1a0a540fb02fb74a1be5d","transactionIndex":"0x0","logIndex":"0x0","removed":false}]
logsBloom               0x00000004000000000000000000000000000000400000000000008000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000010000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000100000000000020000000400000000000000000000000000000000000000000001000000200000000
root
status                  1
transactionHash         0xef9151dadc11aed67dd567426a610b9ff04c88beaad1a0a540fb02fb74a1be5d
transactionIndex        0
type                    2
to                      0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2

Okay, it looks like that transaction worked, let’s confirm that the timelock address is actually an admin now. This call previously returned false. Hopefully it returns true now.

cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2 'hasRole(bytes32,address)(bool)' 0x0000000000000000000000000000000000000000000000000000000000000000 0x07783C37CAAFe0f05C4105250C032062A83F7AC2
true

Great, it looks like we’re headed in the right direction. Now let’s confirm the setup of our timelock. In particular, we should make sure that our timelock admin is setup correctly.

cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 'DEFAULT_ADMIN_ROLE()(bytes32)'
cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 'EXECUTOR_ROLE()(bytes32)'
0x0000000000000000000000000000000000000000000000000000000000000000
0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63

Now that we have the roles, let’s check if the admin account has them:

cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 'hasRole(bytes32,address)(bool)' 0x0000000000000000000000000000000000000000000000000000000000000000 0xE34aaF64b29273B7D567FCFc40544c014EEe9970
cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 'hasRole(bytes32,address)(bool)' 0xd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63 0xE34aaF64b29273B7D567FCFc40544c014EEe9970
false
true

It looks like our typical admin account is configured as an executor for the timelock, but not actually the admin. This means we should be able to execute transactions, but it doesn’t look like we would be able to change the delay. From the code it looks like the timelock is the only thing that can update its delay.

At this point, the question is can we use the timelock to make an admin call. Ideally we would revoke the admin’s account as the default admin role in the rollup manager. Let’s see if it would even work.

cast call --from 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2 'revokeRole(bytes32,address)' 0x0000000000000000000000000000000000000000000000000000000000000000 0xE34aaF64b29273B7D567FCFc40544c014EEe9970
0x

This is a good sign, it means the timelock has the ability to revoke admin access from the admin account in the rollup manager. Now we just need to schedule the call. First let’s get the call data.

cast calldata 'revokeRole(bytes32,address)' 0x0000000000000000000000000000000000000000000000000000000000000000 0xE34aaF64b29273B7D567FCFc40544c014EEe9970
0xd547741f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e34aaf64b29273b7d567fcfc40544c014eee9970

This looks good, now we need to schedule the call

target="0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2"
value="0"
calldata="0xd547741f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e34aaf64b29273b7d567fcfc40544c014eee9970"
predecessor="0x0000000000000000000000000000000000000000000000000000000000000000"
salt="0x0000000000000000000000000000000000000000000000000000000000000000"
delay="3601"

cast send \
    --private-key 0x12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625 \
    --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 \
    'schedule(address,uint256,bytes,bytes32,bytes32,uint256)' "$target" "$value" "$calldata" "$predecessor" "$salt" "$delay"
blockHash               0xacd613e435f89d04c07fdca6e58b2abef1d5d0f2473774950c6ff5335d24c055
blockNumber             12761
contractAddress
cumulativeGasUsed       67681
effectiveGasPrice       3000000007
from                    0xE34aaF64b29273B7D567FCFc40544c014EEe9970
gasUsed                 67681
logs                    [{"address":"0x07783c37caafe0f05c4105250c032062a83f7ac2","topics":["0x4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca","0x2834e50d0fbd2359263689c685f4afd0311de4b150625c349a40a7b2b7e7f34e","0x0000000000000000000000000000000000000000000000000000000000000000"],"data":"0x0000000000000000000000002f50ef6b8e8ee4e579b17619a92de3e2ffbd8ad2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e110000000000000000000000000000000000000000000000000000000000000044d547741f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e34aaf64b29273b7d567fcfc40544c014eee997000000000000000000000000000000000000000000000000000000000","blockHash":"0xacd613e435f89d04c07fdca6e58b2abef1d5d0f2473774950c6ff5335d24c055","blockNumber":"0x31d9","transactionHash":"0x4fd7c8cd80b05a4472748aa6cdf8e82a5a857fc02f90c231c01816bcb0fd2b73","transactionIndex":"0x0","logIndex":"0x0","removed":false}]
logsBloom               0x00000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000004000200000000000000000000000000000000000000020000000000000000000800000000000000000000000000400000000000000000000000000000000000000000000040000000000000000000000000000000080000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000400000000000000020000000000000000000000000000000000000000000000000000000000000000000
root
status                  1
transactionHash         0x4fd7c8cd80b05a4472748aa6cdf8e82a5a857fc02f90c231c01816bcb0fd2b73
transactionIndex        0
type                    2
to                      0x07783C37CAAFe0f05C4105250C032062A83F7AC2

Okay this looks successful, that should mean our call is scheduled. Let’s take a look at the logs:

EventCallScheduled(bytes32,uint256,address,uint256,bytes,bytes32,uint256)0x4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca

That means our id is 0x2834e50d0fbd2359263689c685f4afd0311de4b150625c349a40a7b2b7e7f34e

With that, we should be able to check on the status:

id="0x2834e50d0fbd2359263689c685f4afd0311de4b150625c349a40a7b2b7e7f34e"

cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 \
    'isOperation(bytes32)(bool)' "$id"
cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 \
    'isOperationPending(bytes32)(bool)' "$id"
cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 \
    'isOperationReady(bytes32)(bool)' "$id"
cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 \
    'isOperationDone(bytes32)(bool)' "$id"
cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 \
    'getTimestamp(bytes32)(uint256)' "$id"
true
true
false
false
1713985543

This looks good, it looks like our operation is scheduled. We now just need to wait until 1713985543.

printf "%d\n" $(cast block -j --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) | jq -r '.timestamp')
1713983298

It looks like we still have to wait 37 minutes.

Once the time is elapsed, I should be able to repeat the same exact call from schedule and use execute instead. First let’s make sure that it reports that it’s ready.

id="0x2834e50d0fbd2359263689c685f4afd0311de4b150625c349a40a7b2b7e7f34e"
cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 \
    'isOperationReady(bytes32)(bool)' "$id"
true

Nice, that looks good. Let’s execute it:

target="0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2"
value="0"
calldata="0xd547741f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e34aaf64b29273b7d567fcfc40544c014eee9970"
predecessor="0x0000000000000000000000000000000000000000000000000000000000000000"
salt="0x0000000000000000000000000000000000000000000000000000000000000000"

cast send \
    --private-key 0x12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625 \
    --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x07783C37CAAFe0f05C4105250C032062A83F7AC2 \
    'execute(address,uint256,bytes,bytes32,bytes32)' "$target" "$value" "$calldata" "$predecessor" "$salt"
blockHash               0x32fe6a5224885c605eeca7052cb89925f018965d4ac176b1e99ceff3ad4e9b1c
blockNumber             14076
contractAddress
cumulativeGasUsed       55161
effectiveGasPrice       3000000007
from                    0xE34aaF64b29273B7D567FCFc40544c014EEe9970
gasUsed                 55161
logs                    [{"address":"0x2f50ef6b8e8ee4e579b17619a92de3e2ffbd8ad2","topics":["0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000e34aaf64b29273b7d567fcfc40544c014eee9970","0x00000000000000000000000007783c37caafe0f05c4105250c032062a83f7ac2"],"data":"0x","blockHash":"0x32fe6a5224885c605eeca7052cb89925f018965d4ac176b1e99ceff3ad4e9b1c","blockNumber":"0x36fc","transactionHash":"0x7f0de30fe4db193ed75aba6f2c3862da8a1f8cef63e4408b8bbd802cc892559e","transactionIndex":"0x0","logIndex":"0x0","removed":false},{"address":"0x07783c37caafe0f05c4105250c032062a83f7ac2","topics":["0xc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58","0x2834e50d0fbd2359263689c685f4afd0311de4b150625c349a40a7b2b7e7f34e","0x0000000000000000000000000000000000000000000000000000000000000000"],"data":"0x0000000000000000000000002f50ef6b8e8ee4e579b17619a92de3e2ffbd8ad2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044d547741f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e34aaf64b29273b7d567fcfc40544c014eee997000000000000000000000000000000000000000000000000000000000","blockHash":"0x32fe6a5224885c605eeca7052cb89925f018965d4ac176b1e99ceff3ad4e9b1c","blockNumber":"0x36fc","transactionHash":"0x7f0de30fe4db193ed75aba6f2c3862da8a1f8cef63e4408b8bbd802cc892559e","transactionIndex":"0x0","logIndex":"0x1","removed":false}]
logsBloom               0x00000000000000000000000000000000000000400000000000008000000000000000000000000000000008000000000000200000000800000000000000000000000000000000000000000000000004000200000002000000000000000000002040000000020000000000000000000800000000000000000000000000400000000000000040000000000000000000000000000040000000000000010000000000000000090000000000000000000000000000000000000004000000000000000000000000000000080000000000000000000000000000000000000000000020000000400000000000000000000000000000000000000000001000000200000000
root
status                  1
transactionHash         0x7f0de30fe4db193ed75aba6f2c3862da8a1f8cef63e4408b8bbd802cc892559e
transactionIndex        0
type                    2
to                      0x07783C37CAAFe0f05C4105250C032062A83F7AC2

Okay, I think that looks good. Let’s make sure that the role has actually been revoked. This previously returned true and we hope that it’s false now:

cast call --rpc-url $(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc) 0x2F50ef6b8e8Ee4E579B17619A92dE3E2ffbD8AD2 'hasRole(bytes32,address)(bool)' 0x0000000000000000000000000000000000000000000000000000000000000000 0xE34aaF64b29273B7D567FCFc40544c014EEe9970
false

Okay this looks good. Just to recap that has happened:

  • We deployed the rollup manager using test mode which assigns the admin as the admin account rather than the timelock
  • We granted the DEFAULT_ADMIN_ROLE to the timelock addres
  • We scheduled a time locked transaction to revoke the admin account’s DEFAULT_ADMIN_ROLE
  • We executed the transaction after the elapsed amount of time.

Ref