Platform: Code4rena
Start Date: 04/05/2022
Pot Size: $50,000 DAI
Total HM: 24
Participants: 71
Period: 5 days
Judge: Justin Goro
Total Solo HM: 14
Id: 119
League: ETH
Rank: 21/71
Findings: 1
Award: $320.67
🌟 Selected for report: 0
🚀 Solo Findings: 0
https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleVesting.sol#L117 https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/MerkleResistor.sol#L259
Inside the initialize()
function in MerkleVesting
and MerkleResistor
, if totalCoins
and the length of the vesting period are not perfectly divisible, then a rounding error can occur. Usually, such a rounding error is negligible however as coinsPerSecond
is multiplied by time to calculate currentWithdrawal
, this effect is exaggerated. coinsPerSecond
will always round down so users will not receive a fair amount of tokens as specified by the vesting schedule.
This example will use MerkleVesting
though this applies to MerkleResistor
as well which has a few more calculations
Say a whitelisted user calls initialize()
with the correct proof and the following parameters:
Let totalCoins
be 50, endTime
to be 30 and startTime to be 0
Calculating coinsPerSecond
we get 50 / 30 = 1
(rounds down)
Say the user withdraws at time t = 20
they will get 20
tokens instead of the expected 33
The user will have to wait until the end of the vesting period to get the fair share.
Consider storing coinsPerSecond
as two variables, one being the numerator and another being the denominator. The, rounding error will only occur when calculating currentWithdrawal
which is less extreme and can be recovered by the end of the vesting period.
#0 - illuzen
2022-05-12T04:40:13Z
Duplicate #107