Skip to content

Commit c896e52

Browse files
authored
Merge pull request #7 from bane-labs/governance
add governance and policy contracts
2 parents 6cd26f2 + 09e8e7e commit c896e52

File tree

13 files changed

+1143
-159
lines changed

13 files changed

+1143
-159
lines changed

config/genesis_testnet.json

Lines changed: 57 additions & 35 deletions
Large diffs are not rendered by default.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: MIT
2+
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Proxy.sol)
3+
4+
pragma solidity ^0.8.20;
5+
6+
import {Proxy} from "@openzeppelin/contracts/proxy/Proxy.sol";
7+
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
8+
9+
/**
10+
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
11+
* implementation address that can be changed. This address is stored in storage in the location specified by
12+
* https://eips.ethereum.org/EIPS/eip-1967[ERC-1967], so that it doesn't conflict with the storage layout of the
13+
* implementation behind the proxy.
14+
*/
15+
contract ERC1967Proxy is Proxy {
16+
/**
17+
* @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.
18+
*
19+
* If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an
20+
* encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.
21+
*
22+
* Requirements:
23+
*
24+
* - If `data` is empty, `msg.value` must be zero.
25+
*/
26+
constructor(address implementation, bytes memory _data) payable {
27+
ERC1967Utils.upgradeToAndCall(implementation, _data);
28+
}
29+
30+
/**
31+
* @dev Returns the current implementation address.
32+
*
33+
* TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using
34+
* the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
35+
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
36+
*/
37+
function _implementation()
38+
internal
39+
view
40+
virtual
41+
override
42+
returns (address)
43+
{
44+
return ERC1967Utils.getImplementation();
45+
}
46+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.20;
3+
4+
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
5+
import "./GovernanceVote.sol";
6+
7+
/**
8+
* @dev This is an auxiliary contract meant to be assigned as the admin of a {Proxy}.
9+
* Use GovernanceVote to manage upgrade
10+
*/
11+
contract GovProxyAdmin is GovernanceVote {
12+
/**
13+
* @dev Upgrades the implementation in proxy to `newImplementation`, and
14+
* subsequently executes the function call encoded in `data`. See
15+
* {UUPSUpgradeable-upgradeToAndCall}.
16+
*
17+
* Requirements:
18+
*
19+
* - This contract must be the admin of `proxy`.
20+
*/
21+
function upgradeAndCall(
22+
UUPSUpgradeable proxy,
23+
address newImplementation,
24+
bytes memory data
25+
)
26+
public
27+
payable
28+
virtual
29+
needVote(
30+
keccak256("upgradeAndCall"),
31+
keccak256(abi.encode(proxy, newImplementation, data))
32+
)
33+
{
34+
proxy.upgradeToAndCall{value: msg.value}(newImplementation, data);
35+
}
36+
}

contracts/solidity/GovReward.sol

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.20;
3+
4+
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
5+
6+
library TransferHelper {
7+
function safeTransfer(address token, address to, uint256 value) internal {
8+
// bytes4(keccak256(bytes('transfer(address,uint256)')));
9+
(bool success, bytes memory data) = token.call(
10+
abi.encodeWithSelector(0xa9059cbb, to, value)
11+
);
12+
require(
13+
success && (data.length == 0 || abi.decode(data, (bool))),
14+
"safeTransfer: transfer failed"
15+
);
16+
}
17+
18+
function safeTransferETH(address to, uint256 value) internal {
19+
(bool success, ) = to.call{value: value}(new bytes(0));
20+
require(success, "safeTransferETH: ETH transfer failed");
21+
}
22+
}
23+
24+
interface IGovernance {
25+
// get current consensus group
26+
function getCurrentConsensus() external view returns (address[] memory);
27+
}
28+
29+
interface IGovReward {
30+
function getMiners() external view returns (address[] memory);
31+
32+
function withdraw() external;
33+
}
34+
35+
contract GovReward is IGovReward, UUPSUpgradeable {
36+
address public constant SELF = 0x1212100000000000000000000000000000000003;
37+
address public constant GOV_ADMIN =
38+
0x1212000000000000000000000000000000000000;
39+
// governance contact
40+
address public constant GOV = 0x1212000000000000000000000000000000000001;
41+
42+
receive() external payable {}
43+
44+
modifier onlyGov() {
45+
require(msg.sender == GOV, "not governance");
46+
_;
47+
}
48+
49+
modifier onlyAdmin() {
50+
require(msg.sender == GOV_ADMIN, "not admin");
51+
_;
52+
}
53+
54+
function _authorizeUpgrade(
55+
address newImplementation
56+
) internal virtual override onlyAdmin {}
57+
58+
// Only for precompiled uups implementation in genesis file, need to be removed when upgrading the contract.
59+
// This override is added because "immutable __self" in UUPSUpgradeable is not avaliable in precompiled contract.
60+
function _checkProxy() internal view virtual override {
61+
if (
62+
address(this) == SELF || // Must be called through delegatecall
63+
ERC1967Utils.getImplementation() != SELF // Must be called through an active proxy
64+
) {
65+
revert UUPSUnauthorizedCallContext();
66+
}
67+
}
68+
69+
// Only for precompiled uups implementation in genesis file, need to be removed when upgrading the contract.
70+
// This override is added because "immutable __self" in UUPSUpgradeable is not avaliable in precompiled contract.
71+
function _checkNotDelegated() internal view virtual override {
72+
if (address(this) != SELF) {
73+
// Must not be called through delegatecall
74+
revert UUPSUnauthorizedCallContext();
75+
}
76+
}
77+
78+
function getMiners() external view override returns (address[] memory) {
79+
return IGovernance(GOV).getCurrentConsensus();
80+
}
81+
82+
function withdraw() external onlyGov {
83+
if (address(this).balance > 0) {
84+
TransferHelper.safeTransferETH(GOV, address(this).balance);
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)