Lottery owner can rig the draw to win the jackpot by swapping the source #393
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
primary issue
Highest quality submission among a set of duplicates
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
Lines of code
https://github.com/code-423n4/2023-03-wenwin/blob/main/src/RNSourceController.sol#L89-L104,https://github.com/code-423n4/2023-03-wenwin/blob/main/src/VRFv2RNSource.sol#L32-L38,https://github.com/code-423n4/2023-03-wenwin/blob/main/src/RNSourceBase.sol#L33-L46
Vulnerability details
Lottery owner can rig the draw to win the jackpot by swapping the source
Impact
The lottery owner has the ability to swap the Random Source under certain cirumstances, and this can be exploited to set a new source contract that returns any number set by it. This way, it can claim the jackpot prize, or any other prizes, by previously buying the corresponding tickets.
Although mentioned the [M-1] Centralization Risk for trusted owners, the risk presented here involves major asset losses for the whole system, affecting its economy, and all of its users.
Wenwin puts a heavy enfasis on transparency for its users, making sure that no "rug pull" can happen on the initial sale,
going for the immutability of their contracts, while trying to build decentralized and trustless games with infinite scalability.
A similar issue evaluated on a previous Code4rena contest can be found here.
Proof of Concept
From the Wenwin documentation:
The system uses the Chainlink oracle with the VRF Direct funding method for a source of randomness. An explanation on how the VRF Direct Funding works can be found here.
But the owner can make the requests made by the oracle purposefully fail by not funding the consuming contract with enough LINK tokens:
Additionally, the owner can take any opportunity the oracles fails enough times to swap the source as well.
The code for swapping the source only verifies that the caller is the owner, and that enough retries have been made:
Link to code
Other vector for making the oracle fail could be on the
fulfillRandomWords
function, as stated on thedocumentation:
Link to code
Link to code
Link to code
Tools Used
Manual review
Recommended Mitigation Steps
Possible mitigations are:
Implement a proxy that deploys the same version of the
VRFv2RNSource
contract, and only let the owner swap to a new implementation with new values. This prevents any manipulation, but it has the drawback of fixing the implementation to the current Chainlink Oracle contract.Implement contracts for other possible oracles that may be useful integrating in case of a failure on the original oracle. This goes inline with the previous approach.
Implement a mechanism that cancels any ongoing draw, or sets a timelock to allow users to claim back the tokens for the tickets they bought, until the new source is set. This way it prevents rigging an ongoing draw, but on the other hands it doesn't prevent the owner from getting tokens from the init pot.
The text was updated successfully, but these errors were encountered: