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…

Sep 2025Otheraccounting3 min read

Chain

Other

Category

accounting

Date

Sep 2025

Source

AuditVault

EVM Playground

Source-level debugger — step opcodes and Solidity in sync

evm-hack-analyzer

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.

Loading fork state…

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-registry mirror.


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, no anvil_state. Full trace: output.txt. PoC: test/62350-licreditydecreasedebtshare-bypasses-interest-accrual-cyfrin_exp.sol.


Key info#

ImpactHIGH — borrowers can repay via direct decreaseDebtShare using a stale debt ratio, skipping accrued interest and reducing LP/protocol yield
ProtocolLicredity v1/v2 — debt share accounting
Vulnerable codeLicredity::decreaseDebtShare — missing _collectInterest() before reading totalDebtBalance/totalDebtShare
Bug classMissing pull-accrual on a “safe” path
FindingCyfrin — Licredity v2.0, 2025-09 · #62350 · reporter Immeas
Report2025-09-01-cyfrin-licredity-v2.0.md
SourceAuditVault
StatusAudit finding — fixed in PR#59. Reproduced here as a standalone local PoC.
Compiler^0.8.24 (PoC)

TL;DR#

  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 principal only.
  5. HARM: amountRepaid == amountBorrowed while the accrued preview is strictly higher.

The vulnerable code#

SOLIDITY
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 decreaseDebtShare directly (not via unlock).

Attack walkthrough#

  1. Open position, borrow DELTA shares → receive principal debt fungible.
  2. Interest becomes pending (in the real system: time passes; in the synthetic: a one-shot pending accrual flag).
  3. Preview with accrual > principal.
  4. Direct decreaseDebtShare repays at the stale ratio → principal only.
  5. Interest share never paid.

Diagrams#

sequenceDiagram participant B as Borrower participant L as Licredity B->>L: increaseDebtShare Note over L: interest pending, not yet pulled B->>L: decreaseDebtShare direct Note over L: reads stale totalDebtBalance L-->>B: burn principal only Note over B,L: interest skipped vs unlock path

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#

Taxonomy (AuditVault)#

  • severity/high · sector/lending · platform/cyfrin
  • genome: stale-price · defi/price-manipulation · debt-accrual-update · timestamp-dependence

Sources & further analysis#

Reproductions & code

Alerts & third-party analyses

  • Web3Sec X hacked database: search.
  • Rekt leaderboard: search.
  • Solodit incident search: search.

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.