-
Notifications
You must be signed in to change notification settings - Fork 34
Description
Description
The AssetInterestRateStrategy.sol stores interest rates on an annual basis.
When interest is accrued, the MathUtils::calculateLinearInterest() function calculates the interest generated over a time interval defined in seconds.
To align the units correctly (per-year interest rate vs seconds passed), the function converts the per-year interest rate into a per-second rate.
However, when a linearized interest rate is recompounded, the effective rate is potentially different:
- If the rate is recompounded more frequently than the original period, the effective rate is higher
- If the rate is recompounded at the same frequency as the original period, the effective rate is the same
- If the rate is recompounded less frequently than the original period, the effective rate is lower
The problem is: given interest accrual can be triggered permissionlessly by users, lenders can exploit this pattern to inflate the interest rate, causing borrowers to pay more interest than intended.
Impact
Here is an example, assuming a maximum annual rate of 1,000% (please find all of the calculations here)
- The linearized second rate is 3.17E-07 (spreadsheet ref 1)
- The recompounded annual rate is 2,202,543% (spreadsheet ref 2)
This would allow an attacker to inflate the annual interest rate from 1,000% to over 2 million percent, by forcing it to compound every second.
Recommended mitigation
One way of mitigating this issue with minimal code changes is to first decompound the annual rate into a more granular rate, before linearizing it. I would suggest to use weekly rates.
This would reduce the impact as follows, assuming a maximum annual rate of 1,000%:
- The equivalent weekly rate is ~4.71% (spreadsheet ref 3)
- The linearized second rate for ~4.71% per week is 7.78E-08 (spreadsheet ref 4)
- The recompounded annual rate is 1,063% (spreadsheet ref 5)
As noted, the recommended mitigation is still exploitable, but the impact is limited to only a marginal increase in the resulting recompounded annual rate, from 1,000% to 1,063%.
This mitigation assumes that the asset will have at least one user interaction per week. This is because a downside of such mitigation is that, if the interest accrual is triggered less frequently than that, the resulting annual rate will be less than expected.
For example, if the interest accrual is only triggered after one year (instead of at least once per week), then the resulting effective interest rate will be 245% instead of 1,000%. (spreadsheet ref 6)
Alternative mitigations:
If the rate is set on a daily basis, a maximum annual rate of 1,000% would be:
- Equivalent to 0.66% per day
- The linearized rate per second would be 7.63E-08
- The recompounded annual rate would be 1,009%
- If the accrual is done only once per year, the final rate will be 241%
If the rate is set on a monthly basis, a maximum annual rate of 1,000% would be:
- Equivalent to 22.12% per month
- The linearized rate per second would be 8.42E-08
- The recompounded annual rate would be 1,321%
- If the accrual is done only once per year, the final rate will be 265%