-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add transition period for continuity #18
Conversation
@gershido I haven't dug into the code in more detail than a cursory review, but overall this approach looks good to me. The diagram is helpful. Only thing I'd consider is adding an option to set a new transition period as an arg in |
test/JokeraceEligibility.t.sol
Outdated
@@ -20,15 +20,15 @@ contract DeployImplementationTest is DeployImplementation, Test { | |||
// bytes32 public SALT; | |||
|
|||
uint256 public fork; | |||
uint256 public BLOCK_NUMBER = 9_713_194; // the block number where hats module factory was deployed on Goerli; | |||
uint256 public BLOCK_NUMBER = 6_488_268; // the block number where hats module factory was deployed on Goerli; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sepolia, i assume? If so, please change the comment
Added the following changes:
|
src/JokeraceEligibility.sol
Outdated
@@ -31,6 +31,8 @@ contract JokeraceEligibility is HatsEligibilityModule { | |||
|
|||
/// @notice Emitted when a reelection is set | |||
event NewTerm(address NewContest, uint256 newTopK, uint256 newTermEnd, uint256 newTransitionPeriod); | |||
/// @notice Emitted when election's results are pulled | |||
event ElectionResultsPulled(address NewContest); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would like to see a test for this event
src/JokeraceEligibility.sol
Outdated
|| ( | ||
currentContest != address(0) | ||
&& GovernorCountingSimple(payable(currentContest)).state() == Governor.ContestState.Canceled | ||
) // or if we're in a transition period, and the next contest was canceled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test for this new logic? I might be missing it, but I don't see one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test added
Added:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good! thanks for adding those tests
Following last week's discussion about the election flow, changed the implementation to allow setting up the next term even before the current term has ended. The main implication on the implementation side was that it requires to keep the full set of details for the next term (contest, term end, top K and transition period). Here are the main changes:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
approving with several suggestions. otherwise, good to go!
src/JokeraceEligibility.sol
Outdated
/// @notice Emitted when a reelection is set | ||
event NewTerm(address NewContest, uint256 newTopK, uint256 newTermEnd); | ||
/// @notice Emitted when the next term is set | ||
event NextTermSet(address NewContest, uint256 newTopK, uint256 newTermEnd, uint256 newTransitionPeriod); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: camel case for newContest
/// @notice Term's ending time (a unix timestamp) | ||
uint256 termEnd; | ||
/// @notice Period of time after the term end when previous elected members are still considered eligible until a | ||
/// new term begins. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: join these two comment lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's automatically formatted like that, the line_length
in the foundry.toml file is set to 120.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh whoops, I misinterpreted github's ui 🫠
/// @notice Jokerace contest (election) | ||
address contest; | ||
/// @notice First K winners of the contest will be eligible | ||
uint96 topK; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice storage slot packing :)
src/JokeraceEligibility.sol
Outdated
function pullElectionResults() public returns (bool success) { | ||
GovernorCountingSimple currentContest = GovernorCountingSimple(payable(underlyingContest)); | ||
function startNextTerm() public { | ||
TermDetails memory nextTerm = terms[currentTermIndex + 1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this function only needs topK
and contest
from the nextTerm
object, it will be cheaper here to set nextTerm
as a storage pointer rather than SLOADing the entire nextTerm object into memory
ie,
TermDetails stoarge nextTerm = terms[currentTermIndex + 1];
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the details from the nextTerm
object are emitted in the event at the end of the function. A different approach would be to just include the next term's index instead of all the details. That's a bit less good for whoever listens to the event because it will require a call to the contract in order to get the details of this new term. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah good point, i missed the event params! Keep it as is, then.
src/JokeraceEligibility.sol
Outdated
address candidate = _getCandidate(currentContest, proposalsOfCurrentRank[proposalIndex]); | ||
eligibleWearersPerContest[candidate][address(currentContest)] = true; | ||
address candidate = _getCandidate(contest, proposalsOfCurrentRank[proposalIndex]); | ||
eligibleWearersPerTerm[candidate][currentTermIndex + 1] = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the second SLOAD of currentTermIndex
, so I'd suggest storing this in memory
src/JokeraceEligibility.sol
Outdated
} | ||
|
||
/*////////////////////////////////////////////////////////////// | ||
INTERNAL FUNCTIONS | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
function _currentTermEnded(uint256 currentTermEnd) internal view returns (bool allowed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason these shouldn't be public functions? Might be nice for front ends to be able to easily get these sub-components of canStartNextTerm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added two separate public functions: currentTermEnded
and nextContestCompleted
, that wrap the internal ones. The reason for the separate public functions is to make them input-less, while the internal ones receive input params to save fetches from storage (in the cases where the function that uses the internal function already fetched this param from storage for other purposes).
Proposed elections flow: