Platform: Code4rena
Start Date: 06/03/2023
Pot Size: $36,500 USDC
Total HM: 8
Participants: 93
Period: 3 days
Judge: cccz
Total Solo HM: 3
Id: 218
League: ETH
Rank: 33/93
Findings: 1
Award: $148.64
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: sashik_eth
Also found by: 0xbepresent, Dug, Haipls, MadWookie, adriro, hl_, horsefacts, peanuts
148.6407 USDC - $148.64
An unclaimed, winning ticket could be listed for sale on a peer to peer NFT exchange by a nefarious actor who then watches the mempool for a purchase/transfer.
Upon seeing that the NFT was purchased, they could frontrun the transaction with a call to claimRewards
, receiving the rewards ahead of transferring the now claimed NFT to the recipient.
It is just calling an existing claimRewards
function, which calls claimWinningTicket
, rewarding the owner and marking it as claimed.
function claimRewards(LotteryRewardType rewardType) external override returns (uint256 claimedAmount) { address beneficiary = (rewardType == LotteryRewardType.FRONTEND) ? msg.sender : stakingRewardRecipient; claimedAmount = LotteryMath.calculateRewards(ticketPrice, dueTicketsSoldAndReset(beneficiary), rewardType); emit ClaimedRewards(beneficiary, claimedAmount, rewardType); rewardToken.safeTransfer(beneficiary, claimedAmount); }
function claimWinningTicket(uint256 ticketId) private onlyTicketOwner(ticketId) returns (uint256 claimedAmount) { uint256 winTier; (claimedAmount, winTier) = this.claimable(ticketId); if (claimedAmount == 0) { revert NothingToClaim(ticketId); } unclaimedCount[ticketsInfo[ticketId].drawId][ticketsInfo[ticketId].combination]--; markAsClaimed(ticketId); emit ClaimedTicket(msg.sender, ticketId, claimedAmount); }
Manual review
Burn tickets when claimed.
#0 - c4-judge
2023-03-11T15:59:35Z
thereksfour marked the issue as duplicate of #425
#1 - c4-judge
2023-03-19T10:06:32Z
thereksfour marked the issue as satisfactory