Contract can be re-used under certain conditions #166
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-146
satisfactory
satisfies C4 submission criteria; eligible for awards
upgraded by judge
Original issue severity upgraded from QA/Gas by judge
Lines of code
https://github.com/code-423n4/2022-12-forgeries/blob/fc271cf20c05ce857d967728edfb368c58881d85/src/VRFNFTRandomDraw.sol#L304-L320
Vulnerability details
Impact
The contract isn't designed to be used multiple times. However, under certain conditions the admin can start and stop the lottery at will, denying some winners the prize if they chose to do so. This can be done using
lastResortTimelockOwnerClaimNFT()
andredraw()
functions. This is problematic since the contract can be used outside of its designed purpose as shown in the POC.Proof of Concept
Assume the conditions to call
lastResortTimelockOwnerClaimNFT()
are satisfied. This can be easily done by creating the lottery and waiting until the time specified insettings.recoverTimelock
. This is also satisfied if the lottery simply has been going on for a long time (users not claiming, winning token is burnt/not minted, etc)reroll()
as adminlastResortTimelockOwnerClaimNFT()
to remove the NFTsettings.drawBufferTime
seconds. Then transfers NFT back to lottery withtransferFrom
and callsreroll()
reroll()
passes all checks since the lottery is the owner of the NFT again. Rerolls the winner denying the last winnerSimilar behavior can also be observed after removing NFT with
winnerClaimNFT()
, transferring it andreroll()
Tools Used
Manual Review
Recommended Mitigation Steps
Consider destroying the contract once done. Implement a function
Call this function after the NFT is transferred out either via
lastResortTimelockOwnerClaimNFT()
or viawinnerClaimNFT()
The text was updated successfully, but these errors were encountered: