Summary
The mint function in the DebtToken contract incorrectly adds the balance increase (accrued interest) to the amountToMint, which results in overstated user debt. This is because the user's debt balance is already updated by the index increase . The amountToMint should only include the principal amount being borrowed, not the accrued interest. This flaw leads to incorrect debt calculations and could cause users to owe more than they should.
Vulnerability Details
The mint function calculates the balanceIncrease (accrued interest) as:
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());
The user's debt balance is already updated by the index changes when balanceOf is called. The balanceIncrease is already reflected in the scaled balance. By adding the balanceIncrease to the amountToMint, the user's debt is double-counted, leading to an overstated debt balance.
it("should show user dept is higher than it should be", async function () {
const mintAmount = ethers.parseEther("100");
const index1 = ethers.getBigInt("1000000000000000000000000000");
const index2 = ethers.getBigInt("1100000000000000000000000000");
await mockLendingPool.setNormalizedDebt(index1);
const tx = await debtToken.connect(mockLendingPoolSigner).mint(user1.address, user1.address, mintAmount, index1);
const receipt = await tx.wait();
const balance = await debtToken.balanceOf(user1.address);
console.log("User balance after mint:", balance.toString());
expect(balance).to.equal(mintAmount);
await mockLendingPool.setNormalizedDebt(index2);
const balance2 = await debtToken.balanceOf(user1.address);
console.log("User balance after mint:", balance2.toString());
expect(balance2).to.equal(mintAmount * 11n / 10n);
const tx2 = await debtToken.connect(mockLendingPoolSigner).mint(user1.address, user1.address, mintAmount, index2);
const receipt2 = await tx2.wait();
const balance3 = await debtToken.balanceOf(user1.address);
console.log("User balance after mint:", balance3.toString());
expect(balance3).to.greaterThan(mintAmount * 11n / 10n + mintAmount);
});
Impact
Users will owe more than they should because the accrued interest is added twice
Tools Used
Manual
Recommendations
The amountToMint should only include the principal amount (amount), not the accrued interest (balanceIncrease)