Summary
The mint
function in the DebtToken
contract incorrectly calculates the balanceIncrease
due to interest by multiplying the user's scaled balance (which already includes the current index) by the new index. This results in the index being applied twice, leading to an inflated debt amount for users when they borrow.
Vulnerability Details
The bug occurs because the scaledBalance is already scaled by the current index, and multiplying it by the new index results in the index being applied twice
function balanceOf(address account) public view override(ERC20, IERC20) returns (uint256) {
uint256 scaledBalance = super.balanceOf(account);
return scaledBalance.rayMul(ILendingPool(_reservePool).getNormalizedDebt());
}
uint256 scaledBalance = balanceOf(onBehalfOf);
bool isFirstMint = scaledBalance == 0;
uint256 balanceIncrease = 0;
if (_userState[onBehalfOf].index != 0 && _userState[onBehalfOf].index < index) {
balanceIncrease = scaledBalance.rayMul(index) - scaledBalance.rayMul(_userState[onBehalfOf].index);
}
_userState[onBehalfOf].index = index.toUint128();
uint256 amountToMint = amount + balanceIncrease;
_mint(onBehalfOf, amountToMint.toUint128());
poc
scaledBalance = 100
currentIndex = 1.2e27 (RAY)
userPrevIndex = 1.1e27 (RAY)
balanceOf(user) = 100 * 1.2e27 = 120e27
balanceIncrease = (120e27 * 1.2e27)/1e27 - (120e27 * 1.1e27)/1e27
= 144e27 - 132e27
= 12e27
balanceIncrease = 100 * (1.2e27 - 1.1e27)
= 100 * 0.1e27
= 10e27
root cause
The balanceOf function returns the scaled balance already multiplied by the current index. When this value is used in balanceIncrease calculation and multiplied by the index again, it results in double multiplication
Impact
Users accrue more debt than they should
Collateralization ratios become inaccurate
Liquidations may trigger prematurely
Users pay excessive interest
Protocol's debt accounting becomes unreliable
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/DebtToken.sol#L150
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/DebtToken.sol#L223-L226
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/DebtToken.sol#L153-L160
Tools Used
Recommendations
use the correct