First Flight #11: Snek-Raffle

Beginner FriendlyFoundryNFT
100 EXP
Ended
Submission Details
Severity: high
Valid

Insufficient CALLBACK_GAS_LIMIT value prevents drawing a winner (call to fulfillRandomWords() reverts)

https://github.com/Cyfrin/2024-03-snek-raffle/blob/6b12b719f5d8587f9bbbf3b029954f23a5a38704/contracts/snek_raffle.vy#L48

Summary

CALLBACK_GAS_LIMIT determines the gas limit for the callback to fulfillRandomWords() function. It is set to 100000. However, a typical call to fulfillRandomWords() costs 130-160k gas.

Vulnerability Details

fulfillRandomWords() is called by the VRF coordinator with a fixed gas budget that is given by CALLBACK_GAS_LIMIT. It is set to 100000. However, a typical call to fulfillRandomWords() costs 130-160k gas. This can be determined by using the @pytest.mark.gas_profile decorator when using the titanoboa testing framework for vyper contracts.

Since the function call consumes more gas than the defined limit, it will fail. Once fulfillRandomWords() fails for the first time, the VRF coordinator will not send another transaction after a failed transaction. The Chainlink VRF v2 documentation states: "fulfillRandomWords must not revert." ( https://docs.chain.link/vrf/v2/security#fulfillrandomwords-must-not-revert , last accessed on 3/14/2024). This leaves the protocol permanently bricked as it is stuck in the RaffleState.CALCULATING state.

Note that this bug could not be detected with the existing tests in snek_raffle_test.py because the mocking framework used for the VRF coordinator (contracts/test/VRFCoordinatorV2Mock.vy) does not implement the logic for the callback gas limit.

Impact

High: The protocol will be non-functional unless the constant is changed.

Tools Used

Manual code inspection and gas profiling using the titanoboa framework.

Recommendations

Increase CALLBACK_GAS_LIMIT to a value that covers a successful call to fulfillRandomWords(), for example 200000. Note that transaction costs may be different for Arbitrum deployment ( https://docs.chain.link/vrf/v2/estimating-costs ).

Updates

Community Judging Commences

Community Judging Judge
10 months ago
Community Judgement Published
66.7% Valid

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

CALLBACK_GAS_LIMIT too low

Support

FAQs

Can’t find an answer? Join our Discord or follow us on Twitter.

Cyfrin
Updraft
CodeHawks
Solodit
Resources
Cyfrin CodeHawks | #106 - Insufficient CALLBACK_GAS_LIMIT value prevents drawing a winner (call to fulfillRandomWords() reverts)