Skip to content

Commit 537371d

Browse files
[add proposal type] governance general purpose (#116)
* feat : add execute * fix : upgrade issue * test : execute * feat : append gap * fix : gap size * fix : [execute fail] return value * fix : typo * fix : typo * feat : test code * feat : gov abigen
1 parent 1edab31 commit 537371d

11 files changed

+867
-38
lines changed

wemix/bind/gen_ballotStorage_abi.go

+59-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wemix/bind/gen_envStorage_abi.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wemix/bind/gen_gov_abi.go

+353-20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wemix/bind/gen_ncpExit_abi.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wemix/bind/gen_registry_abi.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wemix/bind/gen_staking_abi.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wemix/governance-contract/contracts/GovImp.sol

+75
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,14 @@ contract GovImp is AGov, ReentrancyGuardUpgradeable, BallotEnums, EnvConstants,
509509
changeGov(ballotIdx);
510510
} else if (ballotType == uint256(BallotTypes.EnvValChange)) {
511511
applyEnv(ballotIdx);
512+
} else if (ballotType == uint256(BallotTypes.Execute)) {
513+
_execute(ballotIdx);
514+
}
515+
} else {
516+
if (ballotType == uint256(BallotTypes.Execute)) {
517+
IBallotStorage _ballotStorage = IBallotStorage(getBallotStorageAddress());
518+
(, uint256 _value, ) = _ballotStorage.getBallotExecute(ballotIdx);
519+
_returnValueToCreator(_ballotStorage, ballotIdx, _value);
512520
}
513521
}
514522
finalizeBallot(ballotIdx, ballotState);
@@ -1077,4 +1085,71 @@ contract GovImp is AGov, ReentrancyGuardUpgradeable, BallotEnums, EnvConstants,
10771085

10781086
return 0;
10791087
}
1088+
1089+
// Critical
1090+
1091+
function upgradeTo(address) external override {
1092+
revert("Invalid access");
1093+
}
1094+
1095+
function upgradeToAndCall(address, bytes memory) external payable override {
1096+
revert("Invalid access");
1097+
}
1098+
1099+
// Genernal Purpose
1100+
1101+
event Executed(bool indexed success, address indexed to, uint256 value, bytes calldatas, bytes returnData);
1102+
event FailReturnValue(uint256 indexed ballotIdx, address indexed creator, uint256 value, bytes result);
1103+
1104+
function addProposalToExecute(
1105+
address _target,
1106+
bytes memory _calldata,
1107+
bytes memory _memo,
1108+
uint256 _duration
1109+
) external payable onlyGovMem checkTimePeriod checkLockedAmount {
1110+
require(_target != ZERO, "target cannot be zero");
1111+
1112+
address _creator = msg.sender;
1113+
if (msg.value != 0) {
1114+
(bool _ok, ) = _creator.call{ value: 0 }("");
1115+
require(_ok, "creator is not payable");
1116+
}
1117+
1118+
uint256 _ballotIdx = ballotLength + 1;
1119+
1120+
IBallotStorage(getBallotStorageAddress()).createBallotForExecute(
1121+
_ballotIdx, // ballot id
1122+
uint256(BallotTypes.Execute), // ballot type
1123+
_duration,
1124+
_creator, // creator
1125+
_target,
1126+
msg.value,
1127+
_calldata
1128+
);
1129+
updateBallotMemo(_ballotIdx, _memo);
1130+
ballotLength = _ballotIdx;
1131+
}
1132+
1133+
function _execute(uint256 _ballotIdx) private {
1134+
fromValidBallot(_ballotIdx, uint256(BallotTypes.Execute));
1135+
IBallotStorage _ballotStorage = IBallotStorage(getBallotStorageAddress());
1136+
1137+
(address _target, uint256 _value, bytes memory _calldata) = _ballotStorage.getBallotExecute(_ballotIdx);
1138+
(bool _success, bytes memory _returnData) = _target.call{ value: _value }(_calldata);
1139+
1140+
modifiedBlock = block.number;
1141+
emit Executed(_success, _target, _value, _calldata, _returnData);
1142+
1143+
if (!_success) _returnValueToCreator(_ballotStorage, _ballotIdx, _value);
1144+
}
1145+
1146+
function _returnValueToCreator(IBallotStorage _ballotStorage, uint256 _ballotIDx, uint256 _value) private {
1147+
if (_value == 0) return;
1148+
1149+
(, , , address _creator, , , , , , , ) = _ballotStorage.getBallotBasic(_ballotIDx);
1150+
(bool _ok, bytes memory _returnData) = _creator.call{ value: _value }("");
1151+
if (!_ok) {
1152+
emit FailReturnValue(_ballotIDx, _creator, _value, _returnData);
1153+
}
1154+
}
10801155
}

wemix/governance-contract/contracts/abstract/BallotEnums.sol

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ contract BallotEnums {
2323
MemberRemoval, // old Member Address
2424
MemberChange, // Old Member Address, New Member Address, new Node id, New Node ip, new Node port
2525
GovernanceChange, // new Governace Impl Address
26-
EnvValChange // Env variable name, type , value
26+
EnvValChange, // Env variable name, type , value
27+
Execute // Genernal Purpose
2728
}
2829
}

wemix/governance-contract/contracts/interface/IBallotStorage.sol

+4
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,8 @@ interface IBallotStorage {
4141
function getBallotAddress(uint256) external view returns (address);
4242
function getBallotVariable(uint256) external view returns (bytes32, uint256, bytes memory);
4343
function getBallotForExit(uint256) external view returns (uint256, uint256);
44+
45+
// Genernal Purpose
46+
function createBallotForExecute(uint256, uint256, uint256, address, address, uint256, bytes memory) external;
47+
function getBallotExecute(uint256) external view returns (address, uint256, bytes memory);
4448
}

wemix/governance-contract/contracts/storage/BallotStorageImp.sol

+38
Original file line numberDiff line numberDiff line change
@@ -567,4 +567,42 @@ contract BallotStorageImp is GovChecker, BallotEnums, IBallotStorage, UUPSUpgrad
567567
}
568568

569569
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
570+
571+
// Genernal Purpose
572+
573+
struct BallotExecute {
574+
address target;
575+
uint256 value;
576+
bytes data;
577+
}
578+
mapping(uint => BallotExecute) private __ballotExecuteMap;
579+
580+
function createBallotForExecute(
581+
uint256 _id,
582+
uint256 _ballotType,
583+
uint256 _duration,
584+
address _creator,
585+
address _target,
586+
uint256 _value,
587+
bytes memory _calldata
588+
) external override onlyGov notDisabled {
589+
require(_ballotType == uint256(BallotTypes.Execute), "Invalid Ballot Type");
590+
require(_target != address(0), "Invalid target address");
591+
// ballot basic
592+
_createBallot(_id, _ballotType, _duration, _creator);
593+
// ballot executeMap
594+
__ballotExecuteMap[_id] = BallotExecute({ target: _target, value: _value, data: _calldata });
595+
}
596+
597+
function getBallotExecute(uint256 _id) external view override returns (address, uint256, bytes memory) {
598+
BallotExecute memory _ballot = __ballotExecuteMap[_id];
599+
return (_ballot.target, _ballot.value, _ballot.data);
600+
}
601+
602+
/**
603+
* @dev This empty reserved space is put in place to allow future versions to add new
604+
* variables without shifting down storage in the inheritance chain.
605+
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
606+
*/
607+
uint256[40] private __gap;
570608
}

0 commit comments

Comments
 (0)