Skip to content

Commit a72a2c8

Browse files
authored
Merge pull request #245 from bane-labs/systemcontract-timelock
systemcontract: add timelock for GovProxyAdmin
2 parents bba1a53 + 5886781 commit a72a2c8

File tree

5 files changed

+75
-10
lines changed

5 files changed

+75
-10
lines changed

contracts/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ Any contract inheriting `GovernanceVote.sol` can set up a consensus vote on meth
3434

3535
[GovProxyAdmin](https://github.com/bane-labs/go-ethereum/blob/bane-main/contracts/solidity/GovProxyAdmin.sol) controls the upgrade of other pre-compiled system contracts, since all of their `onlyOwner`/`onlyAdmin` point to `0x1212000000000000000000000000000000000000`.
3636

37-
This contract inherits `GovernanceVote.sol` so that it requires a `50%` majority votes among current consensus to execute `upgradeAndCall(...)`, which means **more than half** of the **current consensus** votes for **the same contract implementation**.
37+
This contract inherits `GovernanceVote.sol` so that it requires a `50%` majority votes among current consensus to execute `scheduleUpgrade(...)`, which means **more than half** of the **current consensus** votes for **the same contract implementation**.
38+
39+
This contract inherits `TimelockController.sol` to implement a lock period(2 days) after the vote is passed before calling `executeUpgrade(...)` to upgrade the upgradable system contract. Anyone can call `executeUpgrade(...)`` after the lock period is reached.
3840

3941
All of the upgradable Neo X system contracts use [ERC1967Proxy](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v5.0/contracts/proxy/ERC1967/ERC1967Proxy.sol) and [UUPSUpgradeable](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v5.0/contracts/proxy/utils/UUPSUpgradeable.sol).
4042

contracts/solidity/GovProxyAdmin.sol

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,36 @@ pragma solidity ^0.8.25;
33

44
import {GovernanceVote} from "./base/GovernanceVote.sol";
55
import {GovProxyUpgradeable} from "./base/GovProxyUpgradeable.sol";
6+
import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol";
67

78
/**
89
* @dev This is an auxiliary contract meant to be assigned as the admin of a {Proxy}.
910
* Use GovernanceVote to manage upgrade
1011
*/
11-
contract GovProxyAdmin is GovernanceVote {
12+
contract GovProxyAdmin is GovernanceVote, TimelockController {
13+
//bytes4(keccak256(bytes('upgradeToAndCall(address,bytes)')))
14+
bytes4 public constant UPGRADE_SELECTOR = 0x4f1ef286;
15+
16+
/**
17+
* @dev This constructor does not affect the deployment code in the genesis file because we use GovProxyAdmin as a pre-deployment contract.
18+
* This constructor is only there because the inheritance of TimelockController requires a constructor to compile properly.
19+
*/
20+
constructor(
21+
uint256 minDelay,
22+
address[] memory proposers,
23+
address[] memory executors,
24+
address admin
25+
) TimelockController(minDelay, proposers, executors, admin) {}
26+
1227
/**
13-
* @dev Upgrades the implementation in proxy to `newImplementation`, and
14-
* subsequently executes the function call encoded in `data`. See
15-
* {UUPSUpgradeable-upgradeToAndCall}.
28+
* @dev Schedule an operation that upgrades `proxy` to `newImplementation` and calls a function on the new implementation.
1629
*
1730
* Requirements:
1831
*
32+
* - need voting pass
1933
* - This contract must be the admin of `proxy`.
2034
*/
21-
function upgradeAndCall(
35+
function scheduleUpgrade(
2236
GovProxyUpgradeable proxy,
2337
address newImplementation,
2438
bytes memory data
@@ -34,6 +48,34 @@ contract GovProxyAdmin is GovernanceVote {
3448
keccak256(abi.encode(proxy, newImplementation, data))
3549
)
3650
{
37-
proxy.upgradeToAndCall{value: msg.value}(newImplementation, data);
51+
this.schedule(
52+
address(proxy),
53+
msg.value,
54+
abi.encodeWithSelector(UPGRADE_SELECTOR, newImplementation, data),
55+
0,
56+
0,
57+
getMinDelay()
58+
);
59+
}
60+
61+
/**
62+
* @dev Execute an (ready) operation that upgrades `proxy` to `implementation` and calls a function on the new implementation.
63+
*
64+
* Requirements:
65+
*
66+
* - This contract must be the admin of `proxy`.
67+
*/
68+
function executeUpgrade(
69+
GovProxyUpgradeable proxy,
70+
address newImplementation,
71+
bytes memory data
72+
) public payable {
73+
this.execute(
74+
address(proxy),
75+
msg.value,
76+
abi.encodeWithSelector(UPGRADE_SELECTOR, newImplementation, data),
77+
0,
78+
0
79+
);
3880
}
3981
}

0 commit comments

Comments
 (0)