-
Notifications
You must be signed in to change notification settings - Fork 25
[feature] invalidate winners #240
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
Conversation
Summary by OctaneNew ContractsNo new contracts were added in this PR. Updated Contracts
🔗 Commit Hash: 0775919 |
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.
Pull Request Overview
This PR adds functionality to invalidate raffle winners, allowing administrators to mark specific winners as invalid and enabling the prize to be redrawn. The implementation includes new error types, events, helper functions for managing winner validity, and a migration utility to backfill validity flags for existing winners.
Key changes:
- Added
invalidateWinnerfunction for admins to invalidate specific winners - Introduced
validflag tracking in the Winner struct with helper functions - Added migration utility
backfillValidFlagsto update existing winner records
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 21 comments.
| File | Description |
|---|---|
| plume/src/spin/Raffle.sol | Implements winner invalidation logic, validity tracking, and migration utilities |
| plume/test/Raffle.t.sol | Updates all test cases to include the new formId parameter in function calls |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
plume/src/spin/Raffle.sol
Outdated
| revert NotAWinner(); | ||
| } | ||
|
|
||
| if (!individualWin.claimed) { |
Copilot
AI
Oct 22, 2025
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.
The condition is inverted - it should check if (!individualWin.valid) instead of if (!individualWin.claimed). Currently, this reverts when a winner hasn't claimed their prize yet, which is the opposite of the intended behavior. The check should verify that the winner is valid before allowing them to claim.
| if (!individualWin.claimed) { | |
| if (!individualWin.valid) { |
plume/test/Raffle.t.sol
Outdated
| function testSpendRaffleInsufficient() public { | ||
| vm.prank(ADMIN); | ||
| raffle.addPrize("A", "A", 0, 1); | ||
| raffle.addPrize("A", "A", 0, 1,"0"); |
Copilot
AI
Oct 22, 2025
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.
[nitpick] Missing space after comma before "0". For consistency with other calls in the file (e.g., line 47, 69), add a space between the comma and the string argument.
| raffle.addPrize("A", "A", 0, 1,"0"); | |
| raffle.addPrize("A", "A", 0, 1, "0"); |
plume/test/Raffle.t.sol
Outdated
| function testRequestWinnerEmitsEvents() public { | ||
| vm.prank(ADMIN); | ||
| raffle.addPrize("A", "A", 0, 1); | ||
| raffle.addPrize("A", "A", 0, 1,"0"); |
Copilot
AI
Oct 22, 2025
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.
[nitpick] Missing space after comma before "0". For consistency with other calls in the file (e.g., line 47), add a space between the comma and the string argument.
plume/test/Raffle.t.sol
Outdated
| function testClaimPrizeSuccess() public { | ||
| vm.prank(ADMIN); | ||
| raffle.addPrize("A", "A", 0, 1); | ||
| raffle.addPrize("A", "A", 0, 1,"0"); |
Copilot
AI
Oct 22, 2025
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.
[nitpick] Missing space after comma before "0". For consistency with other calls in the file (e.g., line 47), add a space between the comma and the string argument.
| raffle.addPrize("A", "A", 0, 1,"0"); | |
| raffle.addPrize("A", "A", 0, 1, "0"); |
Overview
Detailed findings
|
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.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
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.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| if (winnersDrawn[prizeId] > 0) { | ||
| winnersDrawn[prizeId] -= 1; | ||
| } | ||
| uint256 c = userWinCount[prizeId][w.winnerAddress]; | ||
| if (c > 0) { | ||
| userWinCount[prizeId][w.winnerAddress] = c - 1; | ||
| } |
Copilot
AI
Oct 24, 2025
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.
[nitpick] The manual synchronization of winnersDrawn and userWinCount creates potential for inconsistency. Since getValidWinnersCount() now computes the actual count by iterating invalidWinners, consider whether winnersDrawn still serves a purpose or if it should be deprecated to reduce redundancy and maintenance burden.
| for (uint256 i = 0; i < arr.length; i++) { | ||
| if (!invalidWinners[prizeId][i]) { | ||
| count++; | ||
| } | ||
| } |
Copilot
AI
Oct 24, 2025
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.
getValidWinnersCount() iterates through all winners on every call. This function is called in requestWinner(), handleWinnerSelection(), setPrizeActive(), and view functions, creating O(n) overhead for each operation. For prizes with many winners, this could become expensive. Consider caching the valid count and updating it when winners are invalidated.
| for (uint256 i = 0; i < wins.length; i++) { | ||
| if (wins[i].winnerAddress == user && (!onlyUnclaimed || !wins[i].claimed)) { | ||
| // Also check that winner is not invalidated | ||
| if (wins[i].winnerAddress == user && !invalidWinners[prizeId][i] && (!onlyUnclaimed || !wins[i].claimed)) { |
Copilot
AI
Oct 24, 2025
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.
[nitpick] This complex conditional with multiple && operators is difficult to parse. Consider extracting the invalidation check or other conditions into named boolean variables to improve readability, e.g., bool isValidWinner = !invalidWinners[prizeId][i];
| if (wins[i].winnerAddress == user && !invalidWinners[prizeId][i] && (!onlyUnclaimed || !wins[i].claimed)) { | |
| bool isWinner = wins[i].winnerAddress == user; | |
| bool isValidWinner = !invalidWinners[prizeId][i]; | |
| bool isUnclaimedOrAll = !onlyUnclaimed || !wins[i].claimed; | |
| if (isWinner && isValidWinner && isUnclaimedOrAll) { |
What's new in this PR?
In bullet point format, please describe what's new in this PR.
Why?
What problem does this solve?
Why is this important?
What's the context?