Puppy Raffle

AI First Flight #1
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

Player still can refund after raffle end

User still can refund the raffle fee even if the raffles has ended.

Description

Normally user can't get refund if the Raffle has ended. In this case, user still can refund the raffle fee even if the raffles has ended, if the raffle players is less than 4. This is because missing check on Raffle timing on refund()

function refund(uint256 playerIndex) public {
address playerAddress = players[playerIndex];
require(playerAddress == msg.sender, "PuppyRaffle: Only the player can refund");
require(playerAddress != address(0), "PuppyRaffle: Player already refunded, or is not active");
// no check for the Raffle period
payable(msg.sender).sendValue(entranceFee);
players[playerIndex] = address(0);
emit RaffleRefunded(playerAddress);
}

Risk

Likelihood:

Event will occured when the Raffle has ended but the players is less than 4

Impact:

User able to refund the fee where it supposed to be accrued to protocol


Proof of Concept

Add this function to existing test suite

Run with forge test --match-test testCanGetRefundAfterEnd -vvvv

function testCanGetRefundAfterEnd() public playersEntered {
uint256 balanceBefore = address(playerOne).balance;
uint256 indexOfPlayer = puppyRaffle.getActivePlayerIndex(playerOne);
vm.warp(block.timestamp + duration + 1);
vm.roll(block.number + 1);
vm.prank(playerOne);
puppyRaffle.refund(indexOfPlayer);
assertEq(address(playerOne).balance, balanceBefore + entranceFee);
}

Recommended Mitigation

Add Raffle timing check on refund()

function refund(uint256 playerIndex) public {
address playerAddress = players[playerIndex];
require(playerAddress == msg.sender, "PuppyRaffle: Only the player can refund");
require(playerAddress != address(0), "PuppyRaffle: Player already refunded, or is not active");
+ require(block.timestamp < raffleStartTime + raffleDuration, "PuppyRaffle: Raffle is already over");
payable(msg.sender).sendValue(entranceFee);
players[playerIndex] = address(0);
emit RaffleRefunded(playerAddress);
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 3 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!