The LiquidationPool
contract is responsible for managing staking positions and distributing rewards based on the staked assets. The LiquidationPool::distributeAssets
function is a key component that allocates rewards to stakers proportionally to their stake in the pool. But stakers may receive less than their fair share of rewards, potentially due to rounding errors inherent in the Solidity programming language's handling of integer division.
Solidity performs integer division, which truncates the decimal part of the quotient, potentially leading to a loss of precision in calculations. In the LiquidationPool::distributeAssets
the _portion
is calculated as follows:
But this calculation can result in truncated values, causing some stakers to receive slightly fewer rewards.
Let's consider the following scenario:
The amount of a given asset is 100. Thera are 3 holders and their positions are respectively: 1, 2 and 3.
The _portion
amount for the first holder will be: 100 * 1 / 6
which is 16,666666667
but in Solidity is rounding down to 16
.
The _portion
amount for the second holder will be: 100 * 2 / 6
which is 33,333333333
but in Solidity is rounding down to 33
.
The _portion
amount for the third holder will be: 100 * 3 / 6
which is 50
.
The first two holders will receive less than their fair share of rewards.
Also, the LiquidationPool::distributeAssets
function does not appear to handle any remainder that might be left after all rewards have been distributed.
Additionally, if costInEuros
is greater than _position.EUROs
the _portion
will be calculated as the following:
In that case multiplication of the result of division will be executed. Also, if costInEuros
is greater than _portion * position.EUROs
, _portion
will be 0
.
Manual Review
You can track the amount of the distributed assets and the last holder can receive the remaining undistributed assets.
Or you can track the remainder of rewards that are not distributed due to rounding and this remainder can be added to the reward pool for the next distribution cycle.
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.