The DebtToken contract is designed to account for accrued debt by computing a balanceIncrease during token burns. However, in the burn function, the calculated balanceIncrease is not applied to adjust the amount to be burned. Instead, the code uses a no-op assignment (amount = amount;), which results in inaccurate debt adjustments when a user's balance has increased due to accrued interest.
In the burn function, when a user’s stored index is lower than the current index, the contract computes a balanceIncrease value intended to represent the accrued interest on the user’s debt, However, instead of adjusting the amount by incorporating this computed increase, the code incorrect set back amount = amount
The failure to adjust amount with balanceIncrease means that the debt reduction is calculated on an outdated value. Users who have accrued additional debt due to interest will not see their burn operation reflect the true debt amount. This miscalculation can lead to persistent inaccuracies in debt accounting.
Scenario:
Initial State:
User’s stored debt index: 1.0e27 (RAY)
Current debt index (from getNormalizedDebt()): 1.1e27 (10% interest)
User’s debt balance (balanceOf): 100 tokens (principal)
Interest Accrual:
The user’s debt has accrued to 100 * 1.1 = 110 tokens due to interest.
balanceIncrease calculation:
balanceIncrease = 100 * (1.1 - 1.0) = 10 tokens
Burn Operation:
User calls burn(100) to repay the principal (100 tokens).
Expected Behavior:
The contract should burn 110 tokens (principal + accrued interest) to fully clear the debt.
Actual Behavior:
The code leaves amount = 100 (ignoring balanceIncrease), resulting in:
Scaled amount burned: 100 / 1.1 ≈ 90.90 (rounded down)
Remaining scaled debt: 100 - 90.90 ≈ 9.09
Remaining debt after applying index: 9.09 * 1.1 ≈ 10 tokens
Result:
The user’s debt is reduced to 10 tokens instead of 0, leaving residual debt due to unaccounted interest.
Inaccurate debt accounting leads to residual debt after burns, allowing users to underpay their obligations and potentially exploit the system to maintain lower effective debt than owed.
manual review
Adjust the amount to be burned by incorporating the balanceIncrease to ensure the full debt (principal + accrued interest) is accounted for.
This ensures the amount reflects the total debt (principal + interest) to be burned.
Interest IS applied through the balanceOf() mechanism. The separate balanceIncrease calculation is redundant/wrong. Users pay full debt including interest via userBalance capping.
Interest IS applied through the balanceOf() mechanism. The separate balanceIncrease calculation is redundant/wrong. Users pay full debt including interest via userBalance capping.
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.