Reproduced Exploit
Licredity — decreaseDebtShare bypasses interest accrual
1. Interest accrues only in unlock / swap / LP add-remove paths. 2. decreaseDebtShare is allowed outside unlock because it only reduces debt. 3. It burns fullMulDivUp(delta, totalDebtBalance, totalDebtShare) without accruing first. 4. After time/pending interest is due, a direct repay costs princip…
Chain
Other
Category
accounting
Date
Sep 2025
Source
AuditVault
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.
Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 62350-licreditydecreasedebtshare-bypasses-interest-accrual-cyfrin. Standalone Foundry PoC and full write-up: 62350-licreditydecreasedebtshare-bypasses-interest-accrual-cyfrin_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/accounting/missing-accrual · impact/yield-theft · trigger/direct-call
Reproduction: a self-contained Foundry PoC that compiles & runs in an isolated project with only
forge-std— no fork, no RPC, noanvil_state. Full trace: output.txt. PoC: test/62350-licreditydecreasedebtshare-bypasses-interest-accrual-cyfrin_exp.sol.
Key info#
| Impact | HIGH — borrowers can repay via direct decreaseDebtShare using a stale debt ratio, skipping accrued interest and reducing LP/protocol yield |
| Protocol | Licredity v1/v2 — debt share accounting |
| Vulnerable code | Licredity::decreaseDebtShare — missing _collectInterest() before reading totalDebtBalance/totalDebtShare |
| Bug class | Missing pull-accrual on a “safe” path |
| Finding | Cyfrin — Licredity v2.0, 2025-09 · #62350 · reporter Immeas |
| Report | 2025-09-01-cyfrin-licredity-v2.0.md |
| Source | AuditVault |
| Status | Audit finding — fixed in PR#59. Reproduced here as a standalone local PoC. |
| Compiler | ^0.8.24 (PoC) |
TL;DR#
- Interest accrues only in
unlock/ swap / LP add-remove paths. decreaseDebtShareis allowed outsideunlockbecause it only reduces debt.- It burns
fullMulDivUp(delta, totalDebtBalance, totalDebtShare)without accruing first. - After time/pending interest is due, a direct repay costs principal only.
- HARM:
amountRepaid == amountBorrowedwhile the accrued preview is strictly higher.
The vulnerable code#
function decreaseDebtShare(uint256 positionId, uint256 delta, bool useBalance)
external
returns (uint256 amount)
{
// FIX: _collectInterest();
uint256 _totalDebtShare = totalDebtShare; // @> VULN: stale ratio
uint256 _totalDebtBalance = totalDebtBalance;
amount = _fullMulDivUp(delta, _totalDebtBalance, _totalDebtShare);
// ... burn amount, decrease shares ...
}
Root cause#
“Repay-only” was treated as safe and skipped the accrual gate that every other state-changing path hits. The share→balance conversion then uses a stale index.
Preconditions#
- Outstanding debt shares exist.
- Interest is pending (time elapsed / accrual not yet pulled).
- Borrower calls
decreaseDebtSharedirectly (not viaunlock).
Attack walkthrough#
- Open position, borrow
DELTAshares → receive principal debt fungible. - Interest becomes pending (in the real system: time passes; in the synthetic: a one-shot pending accrual flag).
- Preview with accrual > principal.
- Direct
decreaseDebtSharerepays at the stale ratio → principal only. - Interest share never paid.
Diagrams#
Impact#
- Lower realized interest for LPs and protocol revenue.
- Distorted debt accounting until some other action accrues.
- Even unintentional early repayments reduce net APY.
Sources#
- AuditVault finding #62350
- Cyfrin Licredity v2.0 report
- Vulnerable source:
Licredity/licredity-v1-core@e8ae10a—src/Licredity.sol(decreaseDebtShare) - Fix: PR#59 commits
8ca2a35,81e54c0
Taxonomy (AuditVault)#
severity/high·sector/lending·platform/cyfrin- genome: stale-price · defi/price-manipulation · debt-accrual-update · timestamp-dependence
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 62350-licreditydecreasedebtshare-bypasses-interest-accrual-cyfrin_exp (evm-hack-registry mirror).
- AuditVault finding: 62350-licreditydecreasedebtshare-bypasses-interest-accrual-cyfrin.
Alerts & third-party analyses
These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.