@@ -37,6 +37,10 @@ contract Apella is IApella {
37
37
gerousia = _gerousia;
38
38
39
39
configuration = DataStructures.Configuration ({
40
+ proposeConfig: DataStructures.ProposeConfiguration ({
41
+ lockDelay: Timestamp.wrap (3600 ),
42
+ lockAmount: 1000e18
43
+ }),
40
44
votingDelay: Timestamp.wrap (3600 ),
41
45
votingDuration: Timestamp.wrap (3600 ),
42
46
executionDelay: Timestamp.wrap (3600 ),
@@ -81,21 +85,7 @@ contract Apella is IApella {
81
85
override (IApella)
82
86
returns (uint256 )
83
87
{
84
- users[msg .sender ].sub (_amount);
85
- total.sub (_amount);
86
-
87
- uint256 withdrawalId = withdrawalCount++ ;
88
-
89
- withdrawals[withdrawalId] = DataStructures.Withdrawal ({
90
- amount: _amount,
91
- unlocksAt: Timestamp.wrap (block .timestamp ) + configuration.lockDelay (),
92
- recipient: _to,
93
- claimed: false
94
- });
95
-
96
- emit WithdrawInitiated (withdrawalId, _to, _amount);
97
-
98
- return withdrawalId;
88
+ return _initiateWithdraw (_to, _amount, configuration.withdrawalDelay ());
99
89
}
100
90
101
91
function finaliseWithdraw (uint256 _withdrawalId ) external override (IApella) {
@@ -114,21 +104,37 @@ contract Apella is IApella {
114
104
115
105
function propose (IPayload _proposal ) external override (IApella) returns (bool ) {
116
106
require (msg .sender == gerousia, Errors.Apella__CallerNotGerousia (msg .sender , gerousia));
107
+ return _propose (_proposal);
108
+ }
117
109
118
- uint256 proposalId = proposalCount++ ;
119
-
120
- proposals[proposalId] = DataStructures.Proposal ({
121
- config: configuration,
122
- state: DataStructures.ProposalState.Pending,
123
- payload: _proposal,
124
- creator: msg .sender ,
125
- creation: Timestamp.wrap (block .timestamp ),
126
- summedBallot: DataStructures.Ballot ({yea: 0 , nea: 0 })
127
- });
110
+ /**
111
+ * @notice Propose a new proposal by locking up a bunch of power
112
+ *
113
+ * Beware that if the gerousia changes these proposals will also be dropped
114
+ * This is to ensure consistency around way proposals are made, and they should
115
+ * really be using the proposal logic in Gerousia, which might have a similar
116
+ * mechanism in place as well.
117
+ * It is here for emergency purposes.
118
+ * Using the lock should be a last resort if the Gerousia is broken.
119
+ *
120
+ * @param _proposal The proposal to propose
121
+ * @param _to The address to send the lock to
122
+ * @return True if the proposal was proposed
123
+ */
124
+ function proposeWithLock (IPayload _proposal , address _to )
125
+ external
126
+ override (IApella)
127
+ returns (bool )
128
+ {
129
+ uint256 availablePower = users[msg .sender ].powerNow ();
130
+ uint256 amount = configuration.proposeConfig.lockAmount;
128
131
129
- emit Proposed (proposalId, address (_proposal));
132
+ require (
133
+ amount <= availablePower, Errors.Apella__InsufficientPower (msg .sender , availablePower, amount)
134
+ );
130
135
131
- return true ;
136
+ _initiateWithdraw (_to, amount, configuration.proposeConfig.lockDelay);
137
+ return _propose (_proposal);
132
138
}
133
139
134
140
function vote (uint256 _proposalId , uint256 _amount , bool _support )
@@ -264,7 +270,7 @@ contract Apella is IApella {
264
270
}
265
271
266
272
// If the gerousia have changed we mark is as dropped
267
- if (gerousia != self.creator ) {
273
+ if (gerousia != self.gerousia ) {
268
274
return DataStructures.ProposalState.Dropped;
269
275
}
270
276
@@ -294,4 +300,42 @@ contract Apella is IApella {
294
300
295
301
return DataStructures.ProposalState.Expired;
296
302
}
303
+
304
+ function _initiateWithdraw (address _to , uint256 _amount , Timestamp _delay )
305
+ internal
306
+ returns (uint256 )
307
+ {
308
+ users[msg .sender ].sub (_amount);
309
+ total.sub (_amount);
310
+
311
+ uint256 withdrawalId = withdrawalCount++ ;
312
+
313
+ withdrawals[withdrawalId] = DataStructures.Withdrawal ({
314
+ amount: _amount,
315
+ unlocksAt: Timestamp.wrap (block .timestamp ) + _delay,
316
+ recipient: _to,
317
+ claimed: false
318
+ });
319
+
320
+ emit WithdrawInitiated (withdrawalId, _to, _amount);
321
+
322
+ return withdrawalId;
323
+ }
324
+
325
+ function _propose (IPayload _proposal ) internal returns (bool ) {
326
+ uint256 proposalId = proposalCount++ ;
327
+
328
+ proposals[proposalId] = DataStructures.Proposal ({
329
+ config: configuration,
330
+ state: DataStructures.ProposalState.Pending,
331
+ payload: _proposal,
332
+ gerousia: gerousia,
333
+ creation: Timestamp.wrap (block .timestamp ),
334
+ summedBallot: DataStructures.Ballot ({yea: 0 , nea: 0 })
335
+ });
336
+
337
+ emit Proposed (proposalId, address (_proposal));
338
+
339
+ return true ;
340
+ }
297
341
}
0 commit comments