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: 41/115
Findings: 2
Award: $129.33
π Selected for report: 0
π Solo Findings: 0
π Selected for report: deth
Also found by: 0xDetermination, 0xpiken, 3agle, Brenzee, Flora, HChang26, KrisApostolov, Satyam_Sharma, Testerbot, aycozynfada, berlin-101, gkrastenov, mahdirostami, merlin, rokinot, rvierdiiev, said, santipu_, sl1, tapir, twicek
124.9633 USDC - $124.96
Judge has assessed an item in Issue #518 as 3 risk. The relevant finding follows:
[L-01] StakedAt time is not deleted during the issuance of prime tokens When a directly revocable token is issued, the stakedAt time of the user is deleted delete stakedAt[users[i]]. This is not done when an irrevocable token is issued. The idea behind deleting the userβs stakedAt time is to prevent situations where a user already has a staking position. If they decide to withdraw all XVS tokens and only _accrueInterestAndUpdateScore is called in the xvsUpdated function without clearing the stakedAt time, it could open up the possibility of future minting of prime tokens without staking XVS for the 90-day duration.
Recommendation Delete stakedAt time of user durring issuing of irrevocable token.
if (userToken.exists && !userToken.isIrrevocable) { _upgrade(users[i]); } else { _mint(true, users[i]); _initializeMarkets(users[i]);
delete stakedAt[users[i]]; }
#0 - c4-judge
2023-11-03T16:45:20Z
fatherGoose1 marked the issue as satisfactory
#1 - c4-judge
2023-11-03T20:42:14Z
fatherGoose1 marked the issue as duplicate of #633
π 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
When a directly revocable token is issued, the stakedAt time of the user is deleted delete stakedAt[users[i]]
. This is not done when an irrevocable token is issued. The idea behind deleting the user's stakedAt time is to prevent situations where a user already has a staking position. If they decide to withdraw all XVS tokens and only _accrueInterestAndUpdateScore
is called in the xvsUpdated
function without clearing the stakedAt time, it could open up the possibility of future minting of prime tokens without staking XVS for the 90-day duration.
Delete stakedAt time of user durring issuing of irrevocable token.
if (userToken.exists && !userToken.isIrrevocable) { _upgrade(users[i]); } else { _mint(true, users[i]); _initializeMarkets(users[i]); + delete stakedAt[users[i]]; }
The total unreleased income is the amount from the last time releaseFund
was invoked in the PSR contract. In scenarios where the income variable is totalIncomeUnreleased == 0
or less than unreleasedPSRIncome[underlying]
, it is possible for the uint256 distributionIncome = totalIncomeUnreleased - unreleasedPSRIncome[underlying];
to revert because unreleasedPSRIncome[underlying]
represents the latest saved income.
Add additional check for that:
uint256 distributionIncome; if(totalIncomeUnreleased >= unreleasedPSRIncome[underlying]) { distributionIncome = totalIncomeUnreleased - unreleasedPSRIncome[underlying]; }
The isEligible
function can directly return a value instead of using an if condition.
function isEligible(uint256 amount) internal view returns (bool) { //@audit GAS: directly return amount >= MINIMUM_STAKED_XVS if (amount >= MINIMUM_STAKED_XVS) { return true; } return false; }
Make the following changes:
function isEligible(uint256 amount) internal view returns (bool) { return amount >= MINIMUM_STAKED_XVS; }
#0 - 0xRobocop
2023-10-07T02:03:44Z
L-01 Dup of #633
#1 - c4-pre-sort
2023-10-07T02:03:48Z
0xRobocop marked the issue as low quality report
#2 - c4-judge
2023-11-03T16:45:53Z
fatherGoose1 marked the issue as grade-b