Summary
The DebtToken::burn function burns an incorrect amount when _userState[from].index != 0 && _userState[from].index < index.
Vulnerability Details
After the if condition is true in the burn function, balanceIncrease is calculated using index and borrowIndex, but it is not added to the amount.
The balanceIncrease should be added to the amount so that the correct amount of tokens can be burned.
function burn(
address from,
uint256 amount,
uint256 index
) external override onlyReservePool returns (uint256, uint256, uint256, uint256) {
``````
``````
uint256 userBalance = balanceOf(from);
uint256 balanceIncrease = 0;
@>> if (_userState[from].index != 0 && _userState[from].index < index) {
@>> uint256 borrowIndex = ILendingPool(_reservePool).getNormalizedDebt();
@>> balanceIncrease = userBalance.rayMul(borrowIndex) - userBalance.rayMul(_userState[from].index);
@>> amount = amount;
}
_userState[from].index = index.toUint128();
if(amount > userBalance){
amount = userBalance;
}
uint256 amountScaled = amount.rayDiv(index);
if (amountScaled == 0) revert InvalidAmount();
_burn(from, amount.toUint128());
emit Burn(from, amountScaled, index);
return (amount, totalSupply(), amountScaled, balanceIncrease);
}
Impact
An incorrect amount of tokens will be burned from the user's account.
Recommendations
function burn(
address from,
uint256 amount,
uint256 index
) external override onlyReservePool returns (uint256, uint256, uint256, uint256) {
``````
``````
uint256 userBalance = balanceOf(from);
uint256 balanceIncrease = 0;
if (_userState[from].index != 0 && _userState[from].index < index) {
uint256 borrowIndex = ILendingPool(_reservePool).getNormalizedDebt();
balanceIncrease = userBalance.rayMul(borrowIndex) - userBalance.rayMul(_userState[from].index);
- amount = amount;
+ amount = amount + balanceIncrease;
}
_userState[from].index = index.toUint128();
if(amount > userBalance){
amount = userBalance;
}
uint256 amountScaled = amount.rayDiv(index);
if (amountScaled == 0) revert InvalidAmount();
_burn(from, amount.toUint128());
emit Burn(from, amountScaled, index);
return (amount, totalSupply(), amountScaled, balanceIncrease);
}