_setPseudorandomValue will not work properly for Arbitrum
Summary
The FairQueueInitializable contract, when deployed on Arbitrum, uses the blockhash function to generate pseudorandom values for delay times. However, Arbitrum's implementation of blockhash is insecure and not suitable for randomness, resulting in exploitable delay assignments.
Vulnerability Detail
On what chains are the smart contracts going to be deployed?
Any EVM-compatible networks (Ethereum, Base, Polygon, BSC, etc.)
The FairQueueInitializable contract uses blockhash(block.number - 1) to generate a pseudorandom value for calculating delays. On Arbitrum, blockhash returns non-cryptographic hashes for blocks within the range block.number - 256 <= x < block.number. This behavior makes the delay times predictable and exploitable.
function _setPseudorandomValue(uint160 salt) internal {
if (distancePerSecond == 0) {
// there is no delay: random value is not needed
return;
}
require(salt > 0, "I demand more randomness");
randomValue = uint160(uint256(blockhash(block.number - 1))) ^ salt;
}
Returns a cryptographically insecure, pseudo-random hash for x within the range block.number - 256 <= x < block.number. If x is outside of this range, blockhash(x) will return 0. This includes blockhash(block.number), which always returns 0 just like on Ethereum. The hashes returned do not come from L1. ⚠️ Arbitrum's L2 block hashes should not be relied on as a secure source of randomness.
Impact
Given that blockhash on Arbitrum is not cryptographically secure, a validator or miner with the ability to influence or predict the blockhash can manipulate the randomValue used to assign delays. By manipulating the randomValue, the validator can ensure that specific addresses (potentially their own or those of colluding participants) receive minimal or zero delay times.
hunter_w3b
medium
_setPseudorandomValue
will not work properly for ArbitrumSummary
The
FairQueueInitializable
contract, when deployed on Arbitrum, uses theblockhash
function to generate pseudorandom values for delay times. However, Arbitrum's implementation ofblockhash
is insecure and not suitable for randomness, resulting in exploitable delay assignments.Vulnerability Detail
The
FairQueueInitializable
contract usesblockhash(block.number - 1)
to generate a pseudorandom value for calculating delays. On Arbitrum,blockhash
returns non-cryptographic hashes for blocks within the rangeblock.number - 256 <= x < block.number
. This behavior makes the delay times predictable and exploitable.Arbitrum's documentation:
Impact
Given that blockhash on Arbitrum is not cryptographically secure, a validator or miner with the ability to influence or predict the blockhash can manipulate the randomValue used to assign delays. By manipulating the randomValue, the validator can ensure that specific addresses (potentially their own or those of colluding participants) receive minimal or zero delay times.
Code Snippet
https://github.com/sherlock-audit/2024-05-tokensoft-distributor-contracts-update/blob/main/contracts/packages/hardhat/contracts/claim/factory/FairQueueInitializable.sol#L36-L44
Tool used
Manual Review
Recommendation