LinearDistributionIntervalDecrease
library has getPeriodReward
which checks pool startTime
should not be less than the reward payoutStart
time.
However in the condition startTime_
is assigned the value of payoutStart_
which disturb the whole reward accounting if startTime_
input is passed less than the time payoutStart_
; leading to loss of rewards for stakers.
In Line#33 when startTime_
is set to payoutStart_
they are then substracted from each other at L#48 which will result in 0 as both have same value.
The resultant value of timePassedBefore_
will be zero which will bypass the condition at L#49 if ((timePassedBefore_ / interval_) == ((endTime_ - payoutStart_) / interval_))
, as it is no met.
The code then comes at L#57 which calls the _calculatePartPeriodReward
function where on line#110 calculation will be carried out uint256 intervalsPassed_ = (startTime_ - payoutStart_) / interval_;
As, both the startTime_
and payoutStart_
will have same value it will result in 0
which will lead to zero value outcome when division is carried out with interval_
.
The result of decreaseRewardAmount_
will also result in zero as the value of intervalsPassed_
is zero.
The value of intervalFullReward_
at L#115 will remain unchanged, as the value of decreaseRewardAmount
will be zero due to calculation uint256 intervalFullReward_ = initialAmount_ - decreaseRewardAmount_;
.
As the value of toEnd_
is true
it will go to L#119 which will have result in same value as the value of interval_
as the intervalsPassed_
value is zero which is added to 1
resulting in one.
In the above arithmetic operation the interval_
is multiplied by one as intervalsPassed
have a value of zero.
interval_
will have result in same value and later added with payoutStart_ - startTime_
which as well have value equal to zero as both have same value due to condition at line #33.
When the code reaches L#124 the value of will be same which will return value equal to 0
.
After the calling of _calculatePartPeriodReward
at line#57 the code will then proceed to L#66, that calls the _calculateFullPeriodReward
.
_calculateFullPeriodReward
function at L#131 will have same issues of calculation as above define as value of timePassedBefore_
will be zero due to condition at line#33.
At line#141, the _divideCeil
function is called which will also return 0 as can be checked from this simple test.
This will result in value at L#143 to be equal to 0. Due to zero value the variable initialReward_
will remain unchanged.
At line#153 the result will be lower value as intervalsPassedBefore_
will be equal to zero that leads to loss of precision. Afterwards at L#158 the return value will be less reward token than the staker is eligible for leading to loss of rewards.
When the call to _calculateFullPeriodReward
complete at line 66 the code proceed to line#75.
At line 75 _calculatePartPeriodReward
function is again called with bool value false which will repeat the same process carried out at L#57 with exception to going to L#121 after L#115.
At line 121 the result value will be zero as the value of intervalsPassed_
will be already zero and the whole calculation will result in same zero as well.
The next code executed will be return value at line#128 which will have a resultant zero due to intervalPart_
part being zero.
After completion of _calculatePartPeriodReward
function call at line #75 the code will proceed to line#84 which will return the value of above variables that will be less than expected as firstPeriodReward_
, thirdPeriodReward_
will return zero and secondPeriodReward_
have less reward tokens.
The impact will be on several functions in Distribution.sol
mainly the claim
functions as it call _getCurrentPoolRate(_)
inside it.
_getCurrentPoolRate(_)
function calls getPeriodReward
method which returns the value from getPeriodReward
method of LinearDistributionIntervalDecrease
Library.
claim
is the main function that will be used by stakers to claim their reward token.
The recommendation is made to simply does not allowing value of startTime_
to be less than payoutStart_
and putting a sanity check that validates value of startTime_
is always greater than payoutStart_
.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.