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.
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.
High: The protocol will be non-functional unless the constant is changed.
Manual code inspection and gas profiling using the titanoboa
framework.
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 ).
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by the community.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.