Platform: Code4rena
Start Date: 28/09/2023
Pot Size: $36,500 USDC
Total HM: 5
Participants: 115
Period: 6 days
Judge: 0xDjango
Total Solo HM: 1
Id: 290
League: ETH
Rank: 103/115
Findings: 1
Award: $4.37
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Bauchibred
Also found by: 0x3b, 0xDetermination, 0xMosh, 0xScourgedev, 0xTheC0der, 0xTiwa, 0xWaitress, 0xdice91, 0xfusion, 0xpiken, 0xprinc, 0xweb3boy, ArmedGoose, Aymen0909, Breeje, Brenzee, Daniel526, DavidGiladi, DeFiHackLabs, Flora, Fulum, HChang26, Hama, IceBear, J4X, Krace, KrisApostolov, Maroutis, Mirror, MohammedRizwan, Norah, PwnStars, SPYBOY, TangYuanShen, Testerbot, ThreeSigma, Tricko, al88nsk, alexweb3, ast3ros, berlin-101, bin2chen, blutorque, btk, d3e4, deth, e0d1n, ether_sky, ge6a, gkrastenov, glcanvas, hals, imare, inzinko, jkoppel, jnforja, joaovwfreire, josephdara, kutugu, lotux, lsaudit, mahdirostami, merlin, n1punp, nadin, neumo, nisedo, nobody2018, oakcobalt, orion, peanuts, pep7siup, pina, ptsanev, rokinot, rvierdiiev, said, santipu_, sashik_eth, seerether, squeaky_cactus, terrancrypt, tonisives, twicek, vagrant, xAriextz, y4y
4.3669 USDC - $4.37
PrimeLiquidityProvider#accrueTokens() and _initializeToken() depend on getBlockNumber() in order to calculate variables which will be incorrect because block.number works differently on Arbitrum.
function getBlockNumber() public view virtual returns (uint256) { return block.number; }
According to the Arbitrum Documentation, block.number
returns a value close to the L1 block number at which the sequencer received the transaction.
This could lead to inaccurate deltaBlock
and lastAccruedBlock[token_]
values in accrueTokens():
https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/PrimeLiquidityProvider.sol#L254
function accrueTokens(address token_) public { _ensureZeroAddress(token_); _ensureTokenInitialized(token_); uint256 blockNumber = getBlockNumber(); uint256 deltaBlocks = blockNumber - lastAccruedBlock[token_]; if (deltaBlocks > 0) { uint256 distributionSpeed = tokenDistributionSpeeds[token_]; uint256 balance = IERC20Upgradeable(token_).balanceOf(address(this)); uint256 balanceDiff = balance - tokenAmountAccrued[token_]; if (distributionSpeed > 0 && balanceDiff > 0) { uint256 accruedSinceUpdate = deltaBlocks * distributionSpeed; uint256 tokenAccrued = (balanceDiff <= accruedSinceUpdate ? balanceDiff : accruedSinceUpdate); tokenAmountAccrued[token_] += tokenAccrued; emit TokensAccrued(token_, tokenAccrued); } lastAccruedBlock[token_] = blockNumber; } }
the time of token initialization could also be set to incorrect values: https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/PrimeLiquidityProvider.sol#L288
function _initializeToken(address token_) internal { _ensureZeroAddress(token_); uint256 blockNumber = getBlockNumber(); uint256 initializedBlock = lastAccruedBlock[token_]; if (initializedBlock > 0) { revert TokenAlreadyInitialized(token_); } /* * Update token state block number */ lastAccruedBlock[token_] = blockNumber; emit TokenDistributionInitialized(token_); }
Manual Review
calculate time differences using block.timestamp
Timing
#0 - c4-pre-sort
2023-10-05T23:27:58Z
0xRobocop marked the issue as duplicate of #132
#1 - c4-judge
2023-10-31T19:34:39Z
fatherGoose1 changed the severity to QA (Quality Assurance)
#2 - c4-judge
2023-11-03T01:58:35Z
fatherGoose1 marked the issue as grade-b