As stated in the Arbitrum Docs, the block.number function returns the most recently synchronized L1 block number. This synchronization between the block number in the Sequencer and the actual L1 block number occurs once every minute.
Proof-of-Concept
L2 block.number: updated to sync with L1 block.number ~ every minute (source):
L1 block.number 1000 1001 1002 1003 1004 1005
L2 block.number 1000 1000 1000 1000 1004 1004
The PrimeLiquidityProvider.accrueTokens function will utilize an L1 block.number for the Arbitrum chain.
Impact
The calculation of tokenAmountAccrued will be done using the Ethereum L1 block.number, not the L2 Arbitrum block.number. Additionally, the actual L1 block number occurs once every minute.
Tools Used
Manual review
Recommended Mitigation Steps
Consider utilizing the L2 block.number for computing tokenAmountAccrued:
+uint256 constant public ARBITRUM_CHAIN_ID = 42161;
ArbSys constant public arbSys = +ArbSys(address(100));
function getBlockNumber() public view virtual returns (uint256) {
+if(block.chainid == ARBITRUM_CHAIN_ID)
+{
+ return arbSys.arbBlockNumber();
+}
return block.number;
}
Lines of code
https://github.com/code-423n4/2023-09-venus/blob/b11d9ef9db8237678567e66759003138f2368d23/contracts/Tokens/Prime/PrimeLiquidityProvider.sol#L255
Vulnerability details
Bug Description
As stated in the Arbitrum Docs, the block.number function returns the most recently synchronized L1 block number. This synchronization between the block number in the Sequencer and the actual L1 block number occurs once every minute.
Proof-of-Concept
L2 block.number: updated to sync with L1 block.number ~ every minute (source): L1 block.number 1000 1001 1002 1003 1004 1005 L2 block.number 1000 1000 1000 1000 1004 1004
The
PrimeLiquidityProvider.accrueTokens
function will utilize an L1 block.number for the Arbitrum chain.Impact
The calculation of tokenAmountAccrued will be done using the Ethereum L1 block.number, not the L2 Arbitrum block.number. Additionally, the actual L1 block number occurs once every minute.
Tools Used
Manual review
Recommended Mitigation Steps
Consider utilizing the L2 block.number for computing tokenAmountAccrued:
Assessed type
Timing