Rapid Walnut Wasp
Medium
According to Arbitrum's documentation A single Ethereum block could include multiple Arbitrum blocks within it; however, an Arbitrum block cannot span across multiple Ethereum blocks. Thus, any given Arbitrum transaction is associated with exactly one Ethereum block and one Arbitrum block.
The lending protocol incorrectly relies on block.number for critical timing operations in CToken.sol
function getBlockNumber() internal view virtual returns (uint) {
return block.number; // Returns L1 block number on Arbitrum
}
This affects interest rate calculations:
function accrueInterest() public virtual override returns (uint) {
uint currentBlockNumber = getBlockNumber();
uint accrualBlockNumberPrior = accrualBlockNumber;
uint blockDelta = currentBlockNumber - accrualBlockNumberPrior;
Freshness Checks:
function borrowFreshNoTransfer(address payable borrower, uint borrowAmount) internal virtual {
if (accrualBlockNumber != getBlockNumber()) {
revert BorrowFreshnessCheck();
}
Timing Mismatch:
- L1 block.number updates every ~12 seconds
- Arbitrum blocks occur every ~0.25 seconds
- 48 Arbitrum blocks can exist within one L1 block
- block.number returns L1 block number, not actual L2 block count
No response
No response
No response
Interest calculations will be severely underestimated wich will be ~48x longer than intended, while Multiple transactions within the same L1 block will share the same block number, the Freshness checks will fail for valid transactions.
No response
No response