Skip to content

Commit cc6be2f

Browse files
authored
Add ArcUpgradeScheme (#718)
* Add ArcUpgradeScheme * Remove .DS_Store * Size limits and fixes * lint * Rename UpgradeScheme -> ControllerUpgradeScheme * Bump version * Use loop for test max contracts upgrade * Fix test * Update execute upgrade scheme * Fix execute * fix tests
1 parent 9078a97 commit cc6be2f

File tree

13 files changed

+815
-299
lines changed

13 files changed

+815
-299
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ node_modules/
88
.vscode/
99
site/
1010
yarn*
11+
.DS_Store

contracts/libs/Bytes32ToStr.sol

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
pragma solidity ^0.5.16;
2+
3+
library Bytes32ToStr {
4+
function toStr(bytes32 x) internal pure returns (string memory) {
5+
bytes memory bytesString = new bytes(32);
6+
uint charCount = 0;
7+
uint j;
8+
for (j = 0; j < 32; j++) {
9+
byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
10+
if (char != 0) {
11+
bytesString[charCount] = char;
12+
charCount++;
13+
}
14+
}
15+
bytes memory bytesStringTrimmed = new bytes(charCount);
16+
for (j = 0; j < charCount; j++) {
17+
bytesStringTrimmed[j] = bytesString[j];
18+
}
19+
return string(bytesStringTrimmed);
20+
}
21+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
pragma solidity ^0.5.16;
2+
3+
import "@daostack/infra-experimental/contracts/votingMachines/IntVoteInterface.sol";
4+
import "@daostack/infra-experimental/contracts/votingMachines/ProposalExecuteInterface.sol";
5+
import "../votingMachines/VotingMachineCallbacks.sol";
6+
import "@openzeppelin/upgrades/contracts/Initializable.sol";
7+
8+
/**
9+
* @title A scheme to manage the upgrade of an organization.
10+
* @dev The scheme is used to upgrade the controller of an organization to a new controller.
11+
*/
12+
13+
contract ControllerUpgradeScheme is Initializable, VotingMachineCallbacks, ProposalExecuteInterface {
14+
15+
event NewControllerUpgradeProposal(
16+
address indexed _avatar,
17+
bytes32 indexed _proposalId,
18+
address indexed _intVoteInterface,
19+
address _newController,
20+
string _descriptionHash
21+
);
22+
23+
event ChangeControllerUpgradeSchemeProposal(
24+
address indexed _avatar,
25+
bytes32 indexed _proposalId,
26+
address indexed _intVoteInterface,
27+
address _newControllerUpgradeScheme,
28+
string _descriptionHash
29+
);
30+
31+
event ProposalExecuted(address indexed _avatar, bytes32 indexed _proposalId, int256 _param);
32+
event ProposalDeleted(address indexed _avatar, bytes32 indexed _proposalId);
33+
34+
// Details of an upgrade proposal:
35+
struct UpgradeProposal {
36+
address upgradeContract; // Either the new controller we upgrade to, or the new upgrading scheme.
37+
uint256 proposalType; // 1: Upgrade controller, 2: change upgrade scheme.
38+
}
39+
40+
mapping(bytes32=>UpgradeProposal) public organizationProposals;
41+
42+
IntVoteInterface public votingMachine;
43+
bytes32 public voteParams;
44+
Avatar public avatar;
45+
46+
/**
47+
* @dev initialize
48+
* @param _avatar the avatar this scheme referring to.
49+
* @param _votingMachine the voting machines address to
50+
* @param _voteParams voting machine parameters.
51+
*/
52+
function initialize(
53+
Avatar _avatar,
54+
IntVoteInterface _votingMachine,
55+
bytes32 _voteParams
56+
)
57+
external
58+
initializer
59+
{
60+
require(_avatar != Avatar(0), "avatar cannot be zero");
61+
avatar = _avatar;
62+
votingMachine = _votingMachine;
63+
voteParams = _voteParams;
64+
}
65+
66+
/**
67+
* @dev execution of proposals, can only be called by the voting machine in which the vote is held.
68+
* @param _proposalId the ID of the voting in the voting machine
69+
* @param _param a parameter of the voting result, 1 yes and 2 is no.
70+
*/
71+
function executeProposal(bytes32 _proposalId, int256 _param) external onlyVotingMachine(_proposalId) returns(bool) {
72+
UpgradeProposal memory proposal = organizationProposals[_proposalId];
73+
require(proposal.proposalType != 0);
74+
delete organizationProposals[_proposalId];
75+
emit ProposalDeleted(address(avatar), _proposalId);
76+
// Check if vote was successful:
77+
if (_param == 1) {
78+
79+
// Define controller and get the params:
80+
Controller controller = Controller(avatar.owner());
81+
// Upgrading controller:
82+
if (proposal.proposalType == 1) {
83+
require(controller.upgradeController(proposal.upgradeContract));
84+
}
85+
86+
// Changing upgrade scheme:
87+
if (proposal.proposalType == 2) {
88+
bytes4 permissions = controller.schemesPermissions(address(this));
89+
require(
90+
controller.registerScheme(proposal.upgradeContract, permissions)
91+
);
92+
if (proposal.upgradeContract != address(this)) {
93+
require(controller.unregisterSelf());
94+
}
95+
}
96+
}
97+
emit ProposalExecuted(address(avatar), _proposalId, _param);
98+
return true;
99+
}
100+
101+
/**
102+
* @dev propose an upgrade of the organization's controller
103+
* @param _newController address of the new controller that is being proposed
104+
* @param _descriptionHash proposal description hash
105+
* @return an id which represents the proposal
106+
*/
107+
function proposeUpgrade(address _newController, string memory _descriptionHash)
108+
public
109+
returns(bytes32)
110+
{
111+
bytes32 proposalId = votingMachine.propose(2, voteParams, msg.sender, address(avatar));
112+
UpgradeProposal memory proposal = UpgradeProposal({
113+
proposalType: 1,
114+
upgradeContract: _newController
115+
});
116+
organizationProposals[proposalId] = proposal;
117+
emit NewControllerUpgradeProposal(
118+
address(avatar),
119+
proposalId,
120+
address(votingMachine),
121+
_newController,
122+
_descriptionHash
123+
);
124+
proposalsInfo[address(votingMachine)][proposalId] = ProposalInfo({
125+
blockNumber:block.number,
126+
avatar:avatar
127+
});
128+
return proposalId;
129+
}
130+
131+
/**
132+
* @dev propose to replace this scheme by another controller upgrading scheme
133+
* @param _scheme address of the new upgrading scheme
134+
* @param _descriptionHash proposal description hash
135+
* @return an id which represents the proposal
136+
*/
137+
function proposeChangeControllerUpgradingScheme(
138+
address _scheme,
139+
string memory _descriptionHash
140+
)
141+
public
142+
returns(bytes32)
143+
{
144+
bytes32 proposalId = votingMachine.propose(2, voteParams, msg.sender, address(avatar));
145+
require(organizationProposals[proposalId].proposalType == 0);
146+
147+
UpgradeProposal memory proposal = UpgradeProposal({
148+
proposalType: 2,
149+
upgradeContract: _scheme
150+
});
151+
organizationProposals[proposalId] = proposal;
152+
153+
emit ChangeControllerUpgradeSchemeProposal(
154+
address(avatar),
155+
proposalId,
156+
address(votingMachine),
157+
_scheme,
158+
_descriptionHash
159+
);
160+
proposalsInfo[address(votingMachine)][proposalId] = ProposalInfo({
161+
blockNumber:block.number,
162+
avatar:avatar
163+
});
164+
return proposalId;
165+
}
166+
}

0 commit comments

Comments
 (0)