Skip to content
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
4 changes: 3 additions & 1 deletion contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ Any contract inheriting `GovernanceVote.sol` can set up a consensus vote on meth

[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`.

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**.
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**.

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.

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).

Expand Down
54 changes: 48 additions & 6 deletions contracts/solidity/GovProxyAdmin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,36 @@ pragma solidity ^0.8.25;

import {GovernanceVote} from "./base/GovernanceVote.sol";
import {GovProxyUpgradeable} from "./base/GovProxyUpgradeable.sol";
import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol";

/**
* @dev This is an auxiliary contract meant to be assigned as the admin of a {Proxy}.
* Use GovernanceVote to manage upgrade
*/
contract GovProxyAdmin is GovernanceVote {
contract GovProxyAdmin is GovernanceVote, TimelockController {
//bytes4(keccak256(bytes('upgradeToAndCall(address,bytes)')))
bytes4 public constant UPGRADE_SELECTOR = 0x4f1ef286;

/**
* @dev This constructor does not affect the deployment code in the genesis file because we use GovProxyAdmin as a pre-deployment contract.
* This constructor is only there because the inheritance of TimelockController requires a constructor to compile properly.
*/
constructor(
uint256 minDelay,
address[] memory proposers,
address[] memory executors,
address admin
) TimelockController(minDelay, proposers, executors, admin) {}

/**
* @dev Upgrades the implementation in proxy to `newImplementation`, and
* subsequently executes the function call encoded in `data`. See
* {UUPSUpgradeable-upgradeToAndCall}.
* @dev Schedule an operation that upgrades `proxy` to `newImplementation` and calls a function on the new implementation.
*
* Requirements:
*
* - need voting pass
* - This contract must be the admin of `proxy`.
*/
function upgradeAndCall(
function scheduleUpgrade(
GovProxyUpgradeable proxy,
address newImplementation,
bytes memory data
Expand All @@ -34,6 +48,34 @@ contract GovProxyAdmin is GovernanceVote {
keccak256(abi.encode(proxy, newImplementation, data))
)
{
proxy.upgradeToAndCall{value: msg.value}(newImplementation, data);
this.schedule(
address(proxy),
msg.value,
abi.encodeWithSelector(UPGRADE_SELECTOR, newImplementation, data),
0,
0,
getMinDelay()
);
}

/**
* @dev Execute an (ready) operation that upgrades `proxy` to `implementation` and calls a function on the new implementation.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function executeUpgrade(
GovProxyUpgradeable proxy,
address newImplementation,
bytes memory data
) public payable {
this.execute(
address(proxy),
msg.value,
abi.encodeWithSelector(UPGRADE_SELECTOR, newImplementation, data),
0,
0
);
}
}
Loading