@@ -34,11 +34,6 @@ abstract contract Delegation is FlexVotingClientTest {
3434 return MockFlexVotingDelegatableClient (address (flexClient));
3535 }
3636
37- // TODO
38- // - delegating adds to a delegate's own votes
39- // - test multiple delegatees to the same delegate
40- // - test no double voting for delegatee
41- // - test that delegator can't vote after delegate votes
4237 function testFuzz_selfDelegationByDefault (
4338 address _delegator
4439 ) public {
@@ -111,7 +106,6 @@ abstract contract Delegation is FlexVotingClientTest {
111106 assertEq (client ().getPastRawBalance (_delegate, _now () - 1 ), _combined);
112107
113108 // Create the proposal.
114- uint48 _proposalTimepoint = _now ();
115109 uint256 _proposalId = _createAndSubmitProposal ();
116110
117111 // The delegate expresses a vote.
@@ -125,6 +119,83 @@ abstract contract Delegation is FlexVotingClientTest {
125119 assertEq (_abstainVotesExpressed, _voteType == GCS.VoteType.Abstain ? _combined : 0 );
126120 }
127121
122+ struct Delegator {
123+ address addr;
124+ uint208 weight;
125+ }
126+
127+ function testFuzz_multipleAddressesDelegate (
128+ Delegator memory _delegatorA ,
129+ Delegator memory _delegatorB ,
130+ Delegator memory _delegatorC ,
131+ Delegator memory _delegatorD ,
132+ Delegator memory _delegate ,
133+ uint8 _supportType
134+ ) public {
135+ Delegator[] memory _users = new Delegator [](5 );
136+ _users[0 ] = _delegatorA;
137+ _users[1 ] = _delegatorB;
138+ _users[2 ] = _delegatorC;
139+ _users[3 ] = _delegatorD;
140+ _users[4 ] = _delegate;
141+
142+ for (uint256 i = 0 ; i < _users.length ; i++ ) {
143+ _assumeSafeUser (_users[i].addr);
144+ }
145+
146+ vm.assume (_delegatorA.addr != _delegatorB.addr);
147+ vm.assume (_delegatorA.addr != _delegatorC.addr);
148+ vm.assume (_delegatorA.addr != _delegatorD.addr);
149+ vm.assume (_delegatorA.addr != _delegate.addr);
150+ vm.assume (_delegatorB.addr != _delegatorC.addr);
151+ vm.assume (_delegatorB.addr != _delegatorD.addr);
152+ vm.assume (_delegatorB.addr != _delegate.addr);
153+ vm.assume (_delegatorC.addr != _delegatorD.addr);
154+ vm.assume (_delegatorC.addr != _delegate.addr);
155+ vm.assume (_delegatorD.addr != _delegate.addr);
156+
157+ _delegatorA.weight = uint208 (bound (_delegatorA.weight, 1 , MAX_VOTES - 4 ));
158+ _delegatorB.weight = uint208 (bound (_delegatorB.weight, 1 , MAX_VOTES - _delegatorA.weight - 3 ));
159+ _delegatorC.weight = uint208 (bound (_delegatorC.weight, 1 , MAX_VOTES - _delegatorA.weight - _delegatorB.weight - 2 ));
160+ _delegatorD.weight = uint208 (bound (_delegatorD.weight, 1 , MAX_VOTES - _delegatorA.weight - _delegatorB.weight - _delegatorC.weight - 1 ));
161+ _delegate.weight = uint208 (bound (_delegate.weight, 1 , MAX_VOTES - _delegatorA.weight - _delegatorB.weight - _delegatorC.weight - _delegatorD.weight));
162+
163+ GCS.VoteType _voteType = _randVoteType (_supportType);
164+
165+ // Deposit some funds.
166+ for (uint256 i = 0 ; i < _users.length ; i++ ) {
167+ _mintGovAndDepositIntoFlexClient (_users[i].addr, _users[i].weight);
168+ }
169+
170+ _advanceTimeBy (1 );
171+
172+ // Delegate.
173+ for (uint256 i = 0 ; i < _users.length - 1 ; i++ ) {
174+ vm.prank (_users[i].addr);
175+ client ().delegate (_delegate.addr);
176+ }
177+
178+ _advanceTimeBy (1 );
179+
180+ // Create the proposal.
181+ uint256 _proposalId = _createAndSubmitProposal ();
182+
183+ // The delegate expresses a vote.
184+ vm.prank (_delegate.addr);
185+ client ().expressVote (_proposalId, uint8 (_voteType));
186+
187+ uint256 _combined;
188+ for (uint256 i = 0 ; i < _users.length ; i++ ) {
189+ _combined += _users[i].weight;
190+ }
191+
192+ (uint256 _againstVotesExpressed , uint256 _forVotesExpressed , uint256 _abstainVotesExpressed ) =
193+ client ().proposalVotes (_proposalId);
194+ assertEq (_forVotesExpressed, _voteType == GCS.VoteType.For ? _combined : 0 );
195+ assertEq (_againstVotesExpressed, _voteType == GCS.VoteType.Against ? _combined : 0 );
196+ assertEq (_abstainVotesExpressed, _voteType == GCS.VoteType.Abstain ? _combined : 0 );
197+ }
198+
128199 function testFuzz_delegateCanExpressVoteAfterWithdrawal (
129200 address _delegator ,
130201 address _delegate ,
@@ -145,7 +216,6 @@ abstract contract Delegation is FlexVotingClientTest {
145216 assertEq (client ().delegates (_delegator), _delegate);
146217
147218 // Create the proposal.
148- uint48 _proposalTimepoint = _now ();
149219 uint256 _proposalId = _createAndSubmitProposal ();
150220
151221 // The delegator withdraws their funds without voting.
@@ -164,6 +234,38 @@ abstract contract Delegation is FlexVotingClientTest {
164234 assertEq (_abstainVotesExpressed, _voteType == GCS.VoteType.Abstain ? _weight : 0 );
165235 }
166236
237+ function testFuzz_RevertIf_delegateDoubleVotes (
238+ address _delegator ,
239+ address _delegate ,
240+ uint208 _weight ,
241+ uint8 _supportType
242+ ) public {
243+ GCS.VoteType _voteType;
244+ (_weight, _voteType) = _assumeSafeVoteParams (_delegator, _weight, _supportType);
245+ _assumeSafeUser (_delegate);
246+ vm.assume (_delegator != _delegate);
247+
248+ // Deposit some funds.
249+ _mintGovAndDepositIntoFlexClient (_delegator, _weight);
250+
251+ // Delegate.
252+ vm.prank (_delegator);
253+ client ().delegate (_delegate);
254+ assertEq (client ().delegates (_delegator), _delegate);
255+
256+ // Create the proposal.
257+ uint256 _proposalId = _createAndSubmitProposal ();
258+
259+ // The delegate expresses a voting preference.
260+ vm.prank (_delegate);
261+ client ().expressVote (_proposalId, uint8 (_voteType));
262+
263+ // Even if you're voting for multiple people, you can't double vote.
264+ vm.expectRevert (FVC.FlexVotingClient__AlreadyVoted.selector );
265+ vm.prank (_delegate);
266+ client ().expressVote (_proposalId, uint8 (_voteType));
267+ }
268+
167269 function testFuzz_delegateCanExpressVoteWithoutDepositing (
168270 address _delegator ,
169271 address _delegate ,
@@ -222,6 +324,110 @@ contract BlockNumberClock_Deployment is Deployment {
222324 flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
223325 }
224326}
327+ contract BlockNumber_Constructor is Constructor {
328+ function _timestampClock () internal pure override returns (bool ) {
329+ return false ;
330+ }
331+ function _deployFlexClient (address _governor ) internal override {
332+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
333+ }
334+ }
335+ contract BlockNumber__RawBalanceOf is _RawBalanceOf {
336+ function _timestampClock () internal pure override returns (bool ) {
337+ return false ;
338+ }
339+ function _deployFlexClient (address _governor ) internal override {
340+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
341+ }
342+ }
343+ contract BlockNumber__CastVoteReasonString is _CastVoteReasonString {
344+ function _timestampClock () internal pure override returns (bool ) {
345+ return false ;
346+ }
347+ function _deployFlexClient (address _governor ) internal override {
348+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
349+ }
350+ }
351+ contract BlockNumber__SelfDelegate is _SelfDelegate {
352+ function _timestampClock () internal pure override returns (bool ) {
353+ return false ;
354+ }
355+ function _deployFlexClient (address _governor ) internal override {
356+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
357+ }
358+ }
359+ contract BlockNumber__CheckpointRawBalanceOf is _CheckpointRawBalanceOf {
360+ function _timestampClock () internal pure override returns (bool ) {
361+ return false ;
362+ }
363+ function _deployFlexClient (address _governor ) internal override {
364+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
365+ }
366+ }
367+ contract BlockNumber__CheckpointTotalBalance is _CheckpointTotalBalance {
368+ function _timestampClock () internal pure override returns (bool ) {
369+ return false ;
370+ }
371+ function _deployFlexClient (address _governor ) internal override {
372+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
373+ }
374+ }
375+ contract BlockNumber_GetPastRawBalance is GetPastRawBalance {
376+ function _timestampClock () internal pure override returns (bool ) {
377+ return false ;
378+ }
379+ function _deployFlexClient (address _governor ) internal override {
380+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
381+ }
382+ }
383+ contract BlockNumber_GetPastTotalBalance is GetPastTotalBalance {
384+ function _timestampClock () internal pure override returns (bool ) {
385+ return false ;
386+ }
387+ function _deployFlexClient (address _governor ) internal override {
388+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
389+ }
390+ }
391+ contract BlockNumber_Withdraw is Withdraw {
392+ function _timestampClock () internal pure override returns (bool ) {
393+ return false ;
394+ }
395+ function _deployFlexClient (address _governor ) internal override {
396+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
397+ }
398+ }
399+ contract BlockNumber_Deposit is Deposit {
400+ function _timestampClock () internal pure override returns (bool ) {
401+ return false ;
402+ }
403+ function _deployFlexClient (address _governor ) internal override {
404+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
405+ }
406+ }
407+ contract BlockNumber_ExpressVote is ExpressVote {
408+ function _timestampClock () internal pure override returns (bool ) {
409+ return false ;
410+ }
411+ function _deployFlexClient (address _governor ) internal override {
412+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
413+ }
414+ }
415+ contract BlockNumber_CastVote is CastVote {
416+ function _timestampClock () internal pure override returns (bool ) {
417+ return false ;
418+ }
419+ function _deployFlexClient (address _governor ) internal override {
420+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
421+ }
422+ }
423+ contract BlockNumber_Borrow is Borrow {
424+ function _timestampClock () internal pure override returns (bool ) {
425+ return false ;
426+ }
427+ function _deployFlexClient (address _governor ) internal override {
428+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
429+ }
430+ }
225431contract BlockNumberClock_Delegation is Delegation {
226432 function _timestampClock () internal pure override returns (bool ) {
227433 return false ;
@@ -230,15 +436,120 @@ contract BlockNumberClock_Delegation is Delegation {
230436 flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
231437 }
232438}
233- contract TimestampClock_Deployment is Deployment {
439+
440+ contract TimestampClockClock_Deployment is Deployment {
441+ function _timestampClock () internal pure override returns (bool ) {
442+ return true ;
443+ }
444+ function _deployFlexClient (address _governor ) internal override {
445+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
446+ }
447+ }
448+ contract TimestampClock_Constructor is Constructor {
449+ function _timestampClock () internal pure override returns (bool ) {
450+ return true ;
451+ }
452+ function _deployFlexClient (address _governor ) internal override {
453+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
454+ }
455+ }
456+ contract TimestampClock__RawBalanceOf is _RawBalanceOf {
457+ function _timestampClock () internal pure override returns (bool ) {
458+ return true ;
459+ }
460+ function _deployFlexClient (address _governor ) internal override {
461+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
462+ }
463+ }
464+ contract TimestampClock__CastVoteReasonString is _CastVoteReasonString {
465+ function _timestampClock () internal pure override returns (bool ) {
466+ return true ;
467+ }
468+ function _deployFlexClient (address _governor ) internal override {
469+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
470+ }
471+ }
472+ contract TimestampClock__SelfDelegate is _SelfDelegate {
473+ function _timestampClock () internal pure override returns (bool ) {
474+ return true ;
475+ }
476+ function _deployFlexClient (address _governor ) internal override {
477+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
478+ }
479+ }
480+ contract TimestampClock__CheckpointRawBalanceOf is _CheckpointRawBalanceOf {
481+ function _timestampClock () internal pure override returns (bool ) {
482+ return true ;
483+ }
484+ function _deployFlexClient (address _governor ) internal override {
485+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
486+ }
487+ }
488+ contract TimestampClock__CheckpointTotalBalance is _CheckpointTotalBalance {
489+ function _timestampClock () internal pure override returns (bool ) {
490+ return true ;
491+ }
492+ function _deployFlexClient (address _governor ) internal override {
493+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
494+ }
495+ }
496+ contract TimestampClock_GetPastRawBalance is GetPastRawBalance {
497+ function _timestampClock () internal pure override returns (bool ) {
498+ return true ;
499+ }
500+ function _deployFlexClient (address _governor ) internal override {
501+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
502+ }
503+ }
504+ contract TimestampClock_GetPastTotalBalance is GetPastTotalBalance {
505+ function _timestampClock () internal pure override returns (bool ) {
506+ return true ;
507+ }
508+ function _deployFlexClient (address _governor ) internal override {
509+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
510+ }
511+ }
512+ contract TimestampClock_Withdraw is Withdraw {
513+ function _timestampClock () internal pure override returns (bool ) {
514+ return true ;
515+ }
516+ function _deployFlexClient (address _governor ) internal override {
517+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
518+ }
519+ }
520+ contract TimestampClock_Deposit is Deposit {
521+ function _timestampClock () internal pure override returns (bool ) {
522+ return true ;
523+ }
524+ function _deployFlexClient (address _governor ) internal override {
525+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
526+ }
527+ }
528+ contract TimestampClock_ExpressVote is ExpressVote {
529+ function _timestampClock () internal pure override returns (bool ) {
530+ return true ;
531+ }
532+ function _deployFlexClient (address _governor ) internal override {
533+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
534+ }
535+ }
536+ contract TimestampClock_CastVote is CastVote {
537+ function _timestampClock () internal pure override returns (bool ) {
538+ return true ;
539+ }
540+ function _deployFlexClient (address _governor ) internal override {
541+ flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
542+ }
543+ }
544+ contract TimestampClock_Borrow is Borrow {
234545 function _timestampClock () internal pure override returns (bool ) {
235546 return true ;
236547 }
237548 function _deployFlexClient (address _governor ) internal override {
238549 flexClient = MFVC (address (new MockFlexVotingDelegatableClient (_governor)));
239550 }
240551}
241- contract TimestampClock_Delegation is Delegation {
552+ contract TimestampClockClock_Delegation is Delegation {
242553 function _timestampClock () internal pure override returns (bool ) {
243554 return true ;
244555 }
0 commit comments