Sparkn

CodeFox Inc.
DeFiFoundryProxy
15,000 USDC
View results
Submission Details
Severity: high

[ H ] Chain reorg on Polygon can lead to incorrect distribution of prizes and token recovery

Summary

If this contract gets deployed on Polygon, its worth baring in mind that chain re-orgs
with > 3 depth happen often on Polygon.

There has even been a 156 depth re-org on Polygon.

(see article https://protos.com/polygon-hit-by-157-block-reorg-despite-hard-fork-to-reduce-reorgs/)

Vulnerability Details

There are more than 5 block reorgs a day more than 3 blocks.

https://polygonscan.com/blocks_forked

It is very likely that a contests expiration status will be changed due to reverted blocks, therefore
rendering the logic to check if a contest is expired or not, unreliable.

Impact

Proof of concept:

The contract gets deployed on Polygon and a contest is created.

The contest's expiration is determined based on the current block timestamp and EXPIRATION_TIME.

The function checks the contest's expiration status by comparing saltToCloseTime[salt] + EXPIRATION_TIME
with the current block timestamp. If the contest is deemed expired, the function proceeds to distribute prizes.

If a chain re-org occurs, the block history and contract states could change.
This means that the original contest expiration status might be altered in the re-organized blocks.
The new state of the blockchain might reflect a different contest expiration status than what
was initially determined.

If the altered contract state indicates that the contest is not expired, even though the original
intention was that it should be, the function might incorrectly believe that the contest is
ongoing and not distribute prizes.

Additionally, the reorg event might in like manner effect token recovery.

So when the Owner tries to rescue funds if token is stuck after the deployment and contest is over for a while,
the recovery will fail because the status of the contest will have changed due to the re-org. i.e not expired.

Tools Used

Manual Review

Recommendations

You could either set a higher EXPIRATION_TIME to match the volatility of the chain, or
use an Oracle to get the current block.timestamp across the desired chains of deployment.

Then use the Oracle to check the current block timestamp before ascertaining if the contest has expired.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.