51863 sc low lack of winning ticket removal in handlewinnerselection leads to unfair prize distribution and economic exploitation
Description
Brief/Intro
Vulnerability Details
function handleWinnerSelection(uint256 requestId, uint256[] memory rng) external onlyRole(SUPRA_ROLE) {
uint256 prizeId = pendingVRFRequests[requestId];
// ... validation ...
// Calculate winning ticket - same range every time
uint256 winningTicketIndex = (rng[0] % totalTickets[prizeId]) + 1;
// Binary search to find winner
Range[] storage ranges = prizeRanges[prizeId];
address winnerAddress;
// ... binary search logic ...
// Store winner - but ticket remains in pool
prizeWinners[prizeId].push(Winner({
winnerAddress: winnerAddress,
winningTicketIndex: winningTicketIndex,
drawnAt: block.timestamp,
claimed: false
}));
// Increment counters but don't modify ticket pool
winnersDrawn[prizeId]++;
userWinCount[prizeId][winnerAddress]++;
}Impact Details
References
Proof of Concept
Previous50167 sc high retroactive reward drain via incomplete reward debt resetNext52371 sc high distributeyieldwithlimit is vulnerable to inter batch balance and holders array mutations
Was this helpful?