When calculating the utilization rate at RAACMinter::getUtilizationRate()
, the LendingPool
is called, specifically LendingPool::getNormalizedDebt()
. This function return value depends on the debt interest index which always increases and changes. Thus, every time its value is needed the lending pool should update the indexes.
And the problem is precisely that, RAACMinter
wil use an outdated debt index because the getNormalizedDebt()
does not update LendingPool
indexes.
You can see that there is no call to update indexes on the lending pool in any of the execution paths that use the getUtilizationRate()
:
RAACMinter::updateEmissionRate() public
-> RAACMinter::calculateNewEmissionRate() internal
-> RAACMinter::getUtilizationRate() internal
See no third party calls in updateEmissionRate()
here. Neither in calculateEmissionRate()
here.
RAACMinter::tick() external callable by anyone
-> RAACMinter::updateEmissionRate() public
No third party calls in tick()
either, see here. And it can only be updated once every X seconds interval due to the emissionUpdateInterval
check. So once a faulty calculation is done it remains like that for the whole interval.
StabilityPool::_mintRAACRewards()
-> RAACMinter::tick()
StabilityPool::deposit() || withdraw()
-> StabilityPool::_update()
-> StabilityPool::_mintRAACRewards()
Deposit and withdraw call _update()
right at the beginning of their execution, so it doesn't matter if they later update the lending pool, they will use an outdated value for the calculation of utilization rate. See deposit here, see withdraw here.
There can be wrong utilization rate calculations if no other actions is taken on the LendingPool
previously in the same block. Likely underestimating how much debt there is actually in the system. Utilization rate is used to determine how much RAAC to mint. Wrongly calculating it will slower down or accelerate the minting process.
If a user calls an action that updates interest and this actions is executed previous to the RAACMinting, then the utilization rate will be correct. As the indexes will be updated. But notice that not always this will be the case. Maybe in 1 block no-one interacts with the LendingPool
yet someone deposits in the StabilityPool
, triggering a RAACMinter
call.
Call LendingPool::updateState()
to update the lending pool indexes before calling LendingPool::getNormalizedDebt()
when calculatin the utilization rate on RAACMinter
contract:
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.