Platform: Code4rena
Start Date: 27/10/2022
Pot Size: $33,500 USDC
Total HM: 8
Participants: 96
Period: 3 days
Judge: kirk-baird
Total Solo HM: 1
Id: 176
League: ETH
Rank: 72/96
Findings: 1
Award: $19.64
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: robee
Also found by: 0x007, 0x1f8b, 0x52, 0xDjango, 0xNazgul, 0xSmartContract, 8olidity, Awesome, B2, Bnke0x0, Chom, Diana, Dravee, JTJabba, Jeiwan, Josiah, Lambda, Mathieu, Picodes, RaoulSchaffranek, RaymondFam, RedOneN, ReyAdmirado, Rolezn, Ruhum, Sm4rty, Tricko, Trust, Waze, __141345__, a12jmx, adriro, ajtra, brgltd, c3phas, carlitox477, cccz, ch0bu, chaduke, chrisdior4, corerouter, cryptonue, csanuragjain, ctf_sec, cylzxje, delfin454000, dic0de, djxploit, horsefacts, imare, jayphbee, jwood, ktg, ladboy233, leosathya, lukris02, minhtrng, neko_nyaa, oyc_109, pashov, peritoflores, rbserver, rvierdiiev, shark, tnevler, yixxas
19.6449 USDC - $19.64
https://github.com/code-423n4/2022-10-paladin/blob/main/contracts/WardenPledge.sol#L256-L265
User who pledge can loose their boost and receive no reward without any warning, reducing user experience
The current reward amount received by user when calling pledge function is calculated as follow:
uint256 slope = amount / boostDuration; uint256 bias = slope * boostDuration; uint256 totalDelegatedAmount = ((bias * boostDuration) + bias) / 2; uint256 rewardAmount = (totalDelegatedAmount * pledgeParams.rewardPerVote) / UNIT;
First of all, uint256 slope = amount / boostDuration
, since this is integer division, if amount < boostDuration, then slope
= 0 and rewardAmount
= 0.
If slope
!=0, rewardAmount
can still =0 if totalDelegatedAmount * pledgeParams.rewardPerVote)
< UNIT
.
After these steps, the function does not check if rewardAmount
> 0 and go ahead with the transfer:
if(rewardAmount > pledgeAvailableRewardAmounts[pledgeId]) revert Errors.RewardsBalanceTooLow(); pledgeAvailableRewardAmounts[pledgeId] -= rewardAmount; // Send the rewards to the user IERC20(pledgeParams.rewardToken).safeTransfer(user, rewardAmount);
Since many ERC20 tokens will not revert with transfer amount = 0, the user will lose boost balance and receive back 0 reward amount without any proper warning because the boost amount is already transferred at this step https://github.com/code-423n4/2022-10-paladin/blob/main/contracts/WardenPledge.sol#L248-L253.
Manual review.
I recommend checking if rewardAmount
=0 and revert with an explanation like The pledge amount is too small
.
#0 - trust1995
2022-10-30T21:44:02Z
This calculation falls in line with that curve boost v2 is doing, so I don't believe it is an actual issue. If rewardAmount ends up zero, there is still no impact or harm done.
#1 - Kogaroshi
2022-10-31T00:00:54Z
Duplicate of #126
#2 - kirk-baird
2022-11-11T08:31:17Z
These calculations operate the same as boost so bias will round the same way and pledgers won't lose anything but gas. However, it is a good check to add so I'm going to consider this QA.
#3 - c4-judge
2022-11-11T08:31:23Z
kirk-baird changed the severity to QA (Quality Assurance)
#4 - c4-judge
2022-11-12T00:24:42Z
kirk-baird marked the issue as grade-b