Reproduced Exploit
Debita: burning the veNFT receipt locks 100 AERO that lenders are supposed to claim
claimCollateralAsLender reads the liquidation token's decimals through getDataByReceipt. That view calls ownerOf. After the auction buyer withdraws the veNFT, burnReceipt destroys the receipt and ownerOf reverts with ERC721NonexistentToken. The 100 AERO the buyer paid never reaches the lender. Read…
Loss
100 AERO of auction proceeds stay in the loan. The lender's balance stays 0
Chain
Ethereum
Category
dos
Date
Oct 2024
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: 44224-h-1-lenders-and-borrowers-can-not-claim-liquidation-token-af. Standalone Foundry PoC and full write-up: 44224-h-1-lenders-and-borrowers-can-not-claim-liquidation-token-af_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/dos/frozen-funds · vuln/logic/missing-check
Key info#
| Field | Value |
|---|---|
| Loss | 100 AERO of auction proceeds stay in the loan. The lender's balance stays 0 |
| Vulnerable contract | Receipt.getDataByReceipt |
| Attacker EOA | 0x0000000000000000000000000000000000442241 (the auction buyer) |
| Attack contract | Exploit |
| Attack tx | Exploit.run() |
| Chain / block / date | Ethereum model · block 0 · 2024-10 |
| Compiler | solc 0.8.27, cancun, via IR |
| Bug class | ownerOf on a burned receipt reverts the liquidation claim |
TL;DR#
claimCollateralAsLender reads the liquidation token's decimals through getDataByReceipt. That view calls ownerOf. After the auction buyer withdraws the veNFT, burnReceipt destroys the receipt and ownerOf reverts with ERC721NonexistentToken. The 100 AERO the buyer paid never reaches the lender. Reading decimals from the token, without ownerOf, pays the lender in full.
Background#
Sherlock's Debita Finance V3 contest, issue 156 (H-1), reported by 0xc0ffEE. The judging write-up is in 2024-10-debita-judging. The auction buyer becomes the receipt holder, then veNFTVault.withdraw burns the receipt before lenders or the borrower claim.
The vulnerable code#
uint256 _decimals = token.decimals();
address manager = vaultContract.managerAddress();
// @> VULN: ownerOf reverts after burnReceipt, and claim only needed the decimals
address currentOwnerOfReceipt = ownerOf(receiptID);
ownerOf reverts when the stored owner is the zero address. burnReceipt writes that zero.
Root cause#
The claim path needs decimals and does not need the current receipt owner. getDataByReceipt still calls ownerOf, so a burned receipt makes every later claim revert. The liquidation balance is left in the loan.
Preconditions#
- The buyer holds receipt id 1 and the vault still has the NFT attached.
- The buyer pays 100 AERO into the loan as the auction proceeds.
- The buyer then calls
withdraw, which burns the receipt.
Attack walkthrough#
buyAuctionpulls 100 AERO into the loan and records it as the claimable liquidation.withdrawchecks the buyer still owns the receipt, clearsattached_NFTID, and callsburnReceipt.claimCollateralAsLenderentersgetDataByReceiptand reverts onownerOf.- The caught revert leaves the 100 AERO in the loan. The lender's balance is 0.
- The control reads
decimalsfrom the token and transfers the 100 AERO to the lender.
Diagrams#
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 44224-h-1-lenders-and-borrowers-can-not-claim-liquidation-token-af_exp (evm-hack-registry mirror).
- AuditVault finding: 44224-h-1-lenders-and-borrowers-can-not-claim-liquidation-token-af.
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.