Platform: Code4rena
Start Date: 19/10/2021
Pot Size: $30,000 ETH
Total HM: 5
Participants: 13
Period: 3 days
Judge: GalloDaSballo
Total Solo HM: 4
Id: 43
League: ETH
Rank: 6/13
Findings: 3
Award: $830.71
🌟 Selected for report: 2
🚀 Solo Findings: 0
hickuphh3
If the owner would like to remove rewards, the number of epochs affected could potentially be 1 less because solidity division rounds down, resulting in more rewards taken out than allowed.
Assume
There is therefore (2000 - 1000) * 1 CQT = 1000 CQT remaining to be distributed.
If the owner removes 99.99 CQT = 99.99 * 1e18 = 9999 * 1e16
,
However, the number of remaining rewards is 1000 - 99.99 = 900.01 is only able to cover for 900 epochs, which is 1 less than the calculated end epoch of 1901.
Use OpenZeppelin's ceilDiv()
for the epoch calculation.
uint128 epochs = uint128(Math.ceilDiv(amount, allocatedTokensPerEpoch));
#0 - kitti-katy
2021-10-21T19:10:32Z
similar/related to #10
#1 - GalloDaSballo
2021-11-08T01:04:03Z
Duplicate of #10
0.0137 ETH - $48.98
hickuphh3
The following lines in takeOutRewardTokens()
are only needed in the case where endEpoch != 0
.
uint128 currentEpoch = uint128(block.number); uint128 epochs = amount / allocatedTokensPerEpoch;
Hence, they can be shifted inside the "if" block.
Furthermore, a double calculation of endEpoch - epochs
can be avoided by saving the result into a new variable newEpoch
.
if (endEpoch != 0) { uint128 newEpoch = endEpoch - (amount / allocatedTokensPerEpoch); require(newEpoch > uint128(block.number), "Cannot takeout rewards from past"); endEpoch = newEpoch; }
#0 - GalloDaSballo
2021-11-01T16:57:02Z
Agree with the finding, the sponsor has applied the improvement
0.0546 ETH - $195.43
hickuphh3
The check require(amount < divider, "Rate must be less than 100%");
exists in setValidatorComissionRate()
but not in addValidator()
.
Add the check in addValidator()
as well.
#0 - GalloDaSballo
2021-11-02T00:52:09Z
The sponsor has mitigated the issue