1
1
pragma solidity ^ 0.5.16 ;
2
2
pragma experimental ABIEncoderV2;
3
3
4
- import "../SafeMath.sol " ;
5
-
6
- interface TimelockInterface {
7
- function delay () external view returns (uint );
8
- function GRACE_PERIOD () external view returns (uint );
9
- function acceptAdmin () external ;
10
- function queuedTransactions (bytes32 hash ) external view returns (bool );
11
- function queueTransaction (address target , uint value , string calldata signature , bytes calldata data , uint eta ) external returns (bytes32 );
12
- function cancelTransaction (address target , uint value , string calldata signature , bytes calldata data , uint eta ) external ;
13
- function executeTransaction (address target , uint value , string calldata signature , bytes calldata data , uint eta ) external payable returns (bytes memory );
14
- }
15
-
16
- interface CompInterface {
17
- function getPriorVotes (address account , uint blockNumber ) external view returns (uint96 );
18
- }
19
-
20
4
contract GovernorAlpha {
21
- using SafeMath for uint ;
22
-
23
5
/// @notice The name of this contract
24
6
string public constant name = "Compound Governor Alpha " ;
25
7
@@ -41,7 +23,7 @@ contract GovernorAlpha {
41
23
/// @notice The address of the Compound Protocol Timelock
42
24
TimelockInterface public timelock;
43
25
44
- /// @notice The address of the Compound Governance Token
26
+ /// @notice The address of the Compound governance token
45
27
CompInterface public comp;
46
28
47
29
/// @notice The address of the Governor Guardian
@@ -131,7 +113,7 @@ contract GovernorAlpha {
131
113
bytes32 public constant BALLOT_TYPEHASH = keccak256 ("Ballot(uint256 proposalId,bool support) " );
132
114
133
115
/// @notice An event emitted when a new proposal is created
134
- event ProposalCreated (uint256 id , address proposer , address [] targets , uint256 [] values , string [] signatures , bytes [] calldatas , string description );
116
+ event ProposalCreated (uint id , address proposer , address [] targets , uint [] values , string [] signatures , bytes [] calldatas , uint startBlock , uint endBlock , string description );
135
117
136
118
/// @notice An event emitted when a vote has been cast on a proposal
137
119
event VoteCast (address voter , uint proposalId , bool support , uint votes );
@@ -152,7 +134,7 @@ contract GovernorAlpha {
152
134
}
153
135
154
136
function propose (address [] memory targets , uint [] memory values , string [] memory signatures , bytes [] memory calldatas , string memory description ) public returns (uint ) {
155
- require (comp.getPriorVotes (msg .sender , block .number . sub ( 1 )) > proposalThreshold (), "GovernorAlpha::propose: proposer votes below proposal threshold " );
137
+ require (comp.getPriorVotes (msg .sender , sub256 ( block .number , 1 )) > proposalThreshold (), "GovernorAlpha::propose: proposer votes below proposal threshold " );
156
138
require (targets.length == values.length && targets.length == signatures.length && targets.length == calldatas.length , "GovernorAlpha::propose: proposal function information arity mismatch " );
157
139
require (targets.length != 0 , "GovernorAlpha::propose: must provide actions " );
158
140
require (targets.length <= proposalMaxOperations (), "GovernorAlpha::propose: too many actions " );
@@ -164,6 +146,9 @@ contract GovernorAlpha {
164
146
require (proposersLatestProposalState != ProposalState.Pending, "GovernorAlpha::propose: one live proposal per proposer, found an already pending proposal " );
165
147
}
166
148
149
+ uint startBlock = add256 (block .number , votingDelay ());
150
+ uint endBlock = add256 (startBlock, votingPeriod ());
151
+
167
152
proposalCount++ ;
168
153
Proposal memory newProposal = Proposal ({
169
154
id: proposalCount,
@@ -173,8 +158,8 @@ contract GovernorAlpha {
173
158
values: values,
174
159
signatures: signatures,
175
160
calldatas: calldatas,
176
- startBlock: block . number . add ( votingDelay ()) ,
177
- endBlock: block . number . add ( votingDelay ()). add ( votingPeriod ()) ,
161
+ startBlock: startBlock ,
162
+ endBlock: endBlock ,
178
163
forVotes: 0 ,
179
164
againstVotes: 0 ,
180
165
canceled: false ,
@@ -184,14 +169,14 @@ contract GovernorAlpha {
184
169
proposals[newProposal.id] = newProposal;
185
170
latestProposalIds[newProposal.proposer] = newProposal.id;
186
171
187
- emit ProposalCreated (newProposal.id, msg .sender , targets, values, signatures, calldatas, description);
172
+ emit ProposalCreated (newProposal.id, msg .sender , targets, values, signatures, calldatas, startBlock, endBlock, description);
188
173
return newProposal.id;
189
174
}
190
175
191
176
function queue (uint proposalId ) public {
192
177
require (state (proposalId) == ProposalState.Succeeded, "GovernorAlpha::queue: proposal can only be queued if it is succeeded " );
193
178
Proposal storage proposal = proposals[proposalId];
194
- uint eta = block .timestamp . add ( timelock.delay ());
179
+ uint eta = add256 ( block .timestamp , timelock.delay ());
195
180
for (uint i = 0 ; i < proposal.targets.length ; i++ ) {
196
181
_queueOrRevert (proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], eta);
197
182
}
@@ -219,7 +204,7 @@ contract GovernorAlpha {
219
204
require (state != ProposalState.Executed, "GovernorAlpha::cancel: cannot cancel executed proposal " );
220
205
221
206
Proposal storage proposal = proposals[proposalId];
222
- require (msg .sender == guardian || comp.getPriorVotes (proposal.proposer, block .number . sub ( 1 )) < proposalThreshold (), "GovernorAlpha::cancel: proposer above threshold " );
207
+ require (msg .sender == guardian || comp.getPriorVotes (proposal.proposer, sub256 ( block .number , 1 )) < proposalThreshold (), "GovernorAlpha::cancel: proposer above threshold " );
223
208
224
209
proposal.canceled = true ;
225
210
for (uint i = 0 ; i < proposal.targets.length ; i++ ) {
@@ -253,7 +238,7 @@ contract GovernorAlpha {
253
238
return ProposalState.Succeeded;
254
239
} else if (proposal.executed) {
255
240
return ProposalState.Executed;
256
- } else if (block .timestamp >= proposal.eta. add ( timelock.GRACE_PERIOD ())) {
241
+ } else if (block .timestamp >= add256 ( proposal.eta, timelock.GRACE_PERIOD ())) {
257
242
return ProposalState.Expired;
258
243
} else {
259
244
return ProposalState.Queued;
@@ -281,9 +266,9 @@ contract GovernorAlpha {
281
266
uint96 votes = comp.getPriorVotes (voter, proposal.startBlock);
282
267
283
268
if (support) {
284
- proposal.forVotes = proposal.forVotes. add ( votes);
269
+ proposal.forVotes = add256 ( proposal.forVotes, votes);
285
270
} else {
286
- proposal.againstVotes = proposal.againstVotes. add ( votes);
271
+ proposal.againstVotes = add256 ( proposal.againstVotes, votes);
287
272
}
288
273
289
274
receipt.hasVoted = true ;
@@ -313,9 +298,34 @@ contract GovernorAlpha {
313
298
timelock.executeTransaction (address (timelock), 0 , "setPendingAdmin(address) " , abi.encode (newPendingAdmin), eta);
314
299
}
315
300
301
+ function add256 (uint256 a , uint256 b ) internal pure returns (uint ) {
302
+ uint c = a + b;
303
+ require (c >= a, "addition overflow " );
304
+ return c;
305
+ }
306
+
307
+ function sub256 (uint256 a , uint256 b ) internal pure returns (uint ) {
308
+ require (b <= a, "subtraction underflow " );
309
+ return a - b;
310
+ }
311
+
316
312
function getChainId () internal pure returns (uint ) {
317
- uint256 chainId;
313
+ uint chainId;
318
314
assembly { chainId := chainid () }
319
315
return chainId;
320
316
}
321
317
}
318
+
319
+ interface TimelockInterface {
320
+ function delay () external view returns (uint );
321
+ function GRACE_PERIOD () external view returns (uint );
322
+ function acceptAdmin () external ;
323
+ function queuedTransactions (bytes32 hash ) external view returns (bool );
324
+ function queueTransaction (address target , uint value , string calldata signature , bytes calldata data , uint eta ) external returns (bytes32 );
325
+ function cancelTransaction (address target , uint value , string calldata signature , bytes calldata data , uint eta ) external ;
326
+ function executeTransaction (address target , uint value , string calldata signature , bytes calldata data , uint eta ) external payable returns (bytes memory );
327
+ }
328
+
329
+ interface CompInterface {
330
+ function getPriorVotes (address account , uint blockNumber ) external view returns (uint96 );
331
+ }
0 commit comments