The TempleGoldStaking contract employs `block.number` to manage delays and timing within its functions. However, on Arbitrum, `block.number` does not reliably reflect real-time passage due to its synchronization with L1 block numbers only once per minute. This discrepancy can lead to significant vulnerabilities, allowing users to exploit timing-based protections in the contract.
Functions Affected:
getPriorVotes(address account, uint256 blockNumber)
_writeCheckpoint(address delegatee, uint256 nCheckpoints, uint256 oldVotes, uint256 newVotes)
These functions rely on block.number
to determine the timing and validity of voting power and checkpoint records. On Arbitrum, block.number
reflects the L1 block number, which is updated approximately once per minute. This means that within a 60-second window, the block number remains constant, then jumps to the latest L1 block number, and repeats this process.
A user can exploit this by timing their transactions to occur just before and after the block number synchronization. For instance, they can open a position one Arbitrum block before the sync and close it immediately after. This would make it appear that there has been a significant delay (e.g., 5 blocks, considering an average mainnet block time of 12 seconds) when, in reality, only one Arbitrum block has passed. This discrepancy could be used to bypass timing restrictions within the contract.
Detailed Explaination: Block gas limit, numbers and time
These are critical functions and they may not always work correctly as intended.
Manual Review
Replace the use of block.number
with block.timestamp
for reliable timing calculations. Unlike block.number
, block.timestamp
reflects the actual passage of time and is updated consistently.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.