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: 16/115
Findings: 3
Award: $235.12
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xDetermination
Also found by: DeFiHackLabs, Norah, Pessimistic, PwnStars, SpicyMeatball, Testerbot, ThreeSigma, bin2chen, blutorque, deadrxsezzz, dirk_y, ether_sky, hals, neumo, rokinot, said, seerether, turvy_fuzz
198.4834 USDC - $198.48
https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L818-L822 https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L397-L405
The management of pending score updates within the Prime Program can lead to certain users not accruing their deserved interests in newly added markets. This is because their scores may not be updated as intended. Meanwhile, an attacker could obtain more rewards than they're entitled to due to these temporarily inaccurate scores.
function _startScoreUpdateRound() internal { nextScoreUpdateRoundId++; totalScoreUpdatesRequired = totalIrrevocable + totalRevocable; pendingScoreUpdates = totalScoreUpdatesRequired; }
claim
function. This mints a new Prime Token, increasing the count to 5.updateScores
providing 3 previously minted token addresses plus their own onependingScoreUpdates
counter decrements in each iteration. As a result, it will be set to 0 after processing the Bob’s and the 3 other addresses.if (pendingScoreUpdates == 0) revert NoScoreUpdatesRequired();
no further score updates are allowed for this user.
Bob will receive more rewards than expected, because the omitted user has score 0, so the available rewards won't be distributed to that user.Manual review
Increment the pendingScoreUpdates
whenever any new Prime Token is claimed.
Timing
#0 - c4-pre-sort
2023-10-06T01:15:17Z
0xRobocop marked the issue as duplicate of #555
#1 - c4-judge
2023-11-01T19:59:13Z
fatherGoose1 marked the issue as satisfactory
#2 - c4-judge
2023-11-05T00:52:22Z
fatherGoose1 changed the severity to 3 (High Risk)
🌟 Selected for report: 0xDetermination
Also found by: 0xblackskull, 0xweb3boy, ADM, Breeje, Pessimistic, PwnStars, SBSecurity, Satyam_Sharma, ThreeSigma, al88nsk, blutorque, debo, dethera, maanas, neumo, oakcobalt, pina, said, sces60107, tapir, tsvetanovv, xAriextz
32.2731 USDC - $32.27
https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L200-L230
It has been confirmed by the sponsor that the updateScores
function will be called for every user by the owner, e.g. if the new market will be added.
An attacker, upon observing the owner's transaction containing an array of user addresses intended for score updates, can front-run this transaction. By selecting a single address from the owner's list and invoking the updateScores
function with a higher gas price, the attacker ensures that this specific user's score is updated prior to the owner's transaction being mined. When the owner's transaction processes and encounters the already updated address, the check
if (isScoreUpdated[nextScoreUpdateRoundId][user]) continue;
will trigger.
Because the continue statement is invoked and the loop counter doesn't increment until the end, the function can run out of gas and revert. This allows an attacker to repeatedly grief the owner, leading to financial losses from wasted gas.
updateScores
call, providing an array of all users addresses to update their scores.if (isScoreUpdated[nextScoreUpdateRoundId][user]) continue;
will skip the address, resulting in transaction revert due to out of gas error.Manual review
Increment the i
counter directly in the loop header:
for (uint256 i = 0; i < users.length; i++)
Loop
#0 - c4-pre-sort
2023-10-04T22:18:55Z
0xRobocop marked the issue as duplicate of #556
#1 - c4-judge
2023-11-01T20:29:21Z
fatherGoose1 marked the issue as satisfactory
🌟 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
Description:
The sweep token function here https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/PrimeLiquidityProvider.sol#L216 when given a fee-on-trasfer token (considering there is some amount of that token in the contract) will emit the incorrect event as the amount in the argument of the event would be less than the amount given as parameter.
Description:
The function getEffectivedistributionSpeed here https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/PrimeLiquidityProvider.sol#L232 might give incorrect result as before calculating uint256 accrued
it does not call accrueTokens , since it is a view function is would be incorrect to change state this way but it can be changed to a normal external function.
Description:
The appropriate role can call issue() function https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L331 to issue a Prime token to an array of users , but if one of the user already has a prime token the whole call will revert due to the checks in the _mint function that if the user already has a prime token then revert. Ensure that before minting the user does not have a prime token.
We accrue interest and update score of the users across all markets in this code block https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L211-L217 , but instead of this a simple call to _accrueInterestAndUpdateScore
would be sufficient since it does the same job and would make the code more readable and streamlined.
Description:
updateAlpha , updateMultiplers , addMarket when called updates a round Id through _startScoreUpdate round at L818 and score updates for these rounds take place in the function updateScores() at L200 . If for a round before updateScores() is called for a user the next round gets started ( through updateAlpha , updateMultiplers , addMarket ) then score won’t be updated for that round for the users and isScoreUpdated will always be false for that round.
Description:
Capital is calculated here https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L661 , currently vToken will be 8 decimals but other are possible in future , if in future the decimal is more than 18 , capital calculation will always revert and no scores calculated.
Description:
The comment here https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/PrimeLiquidityProvider.sol#L23 is incorrect , it should be “ the last block where tokens were accrued” instead of “The rate at which token is distributed to the Prime contract”
#0 - c4-pre-sort
2023-10-07T01:26:23Z
0xRobocop marked the issue as low quality report