Summary
The request_raffle_winner
function doesn't emits/logs RequestRaffleWinner
event. Since logs records are great resource of information and events
in blockchain technology are essential for creating dynamic, responsive, and interoperable decentralized applications. They enable smart contracts to communicate, interact, and trigger off-chain processes, making blockchain technology more versatile and useful in a wide range of applications.
Vulnerability Details
Raffle expects to emit or log the request_raffle_winner
event.
Checkout the Line 81 and Line 137
.
.
.
event RequestedRaffleWinner:
----------------^
request_id: indexed(uint256)
event RaffleEntered:
player: indexed(address)
event WinnerPicked:
player: indexed(address)
.
.
.
@external
def request_raffle_winner() -> uint256:
"""Request a random winner from the VRF Coordinator after a raffle has completed."""
is_open: bool = RaffleState.OPEN == self.raffle_state
time_passed: bool = (block.timestamp - self.last_timestamp) > RAFFLE_DURATION
has_players: bool = len(self.players) > 0
has_balance: bool = self.balance > 0
assert is_open and time_passed and has_players and has_balance, ERROR_NOT_ENDED
self.raffle_state = RaffleState.CALCULATING
request_id: uint256 = VRF_COORDINATOR.requestRandomWords(
GAS_LANE,
SUBSCRIPTION_ID,
REQUEST_CONFIRMATIONS,
CALLBACK_GAS_LIMIT,
NUM_WORDS
)
------>
return ERC721._total_supply()
.
.
.
Impact
This omission results in the absence of a log record for the raffle spin request for the winner, which could potentially lead to communication issues with DApps.
Tools Used
Manual Review
Recommendations
Log/Emit the RequestedRaffleWinner
after a successful Raffle spin winner request. Update snek_raffle.vy
like below...
.
.
.
@external
def request_raffle_winner() -> uint256:
"""Request a random winner from the VRF Coordinator after a raffle has completed."""
is_open: bool = RaffleState.OPEN == self.raffle_state
time_passed: bool = (block.timestamp - self.last_timestamp) > RAFFLE_DURATION
has_players: bool = len(self.players) > 0
has_balance: bool = self.balance > 0
assert is_open and time_passed and has_players and has_balance, ERROR_NOT_ENDED
self.raffle_state = RaffleState.CALCULATING
request_id: uint256 = VRF_COORDINATOR.requestRandomWords(
GAS_LANE,
SUBSCRIPTION_ID,
REQUEST_CONFIRMATIONS,
CALLBACK_GAS_LIMIT,
NUM_WORDS
)
+ log RaffleEntered(request_id)
return ERC721._total_supply()
.
.
.