Reproduced Exploit
Gondi — refinanceFromLoanExecutionData missing tokenId check
1. Refinance re-uses the NFT already in escrow (no transfer out/in). 2. Offer validation uses attacker-controlled executionData.tokenId. 3. No check that it matches the escrowed loan.nftCollateralTokenId. 4. Lender accepts a blue-chip id; escrow still holds junk → undercollateralized loan.
Chain
Other
Category
untagged
Date
Apr 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: 35206-h-04-function-refinancefromloanexecutiondata-does-not-check. Standalone Foundry PoC and full write-up: 35206-h-04-function-refinancefromloanexecutiondata-does-not-check_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/wrong-condition · vuln/direct-drain · vuln/access-roles
Reproduction: self-contained Foundry PoC with only
forge-std— no fork, no RPC. Full trace: output.txt. PoC: test/35206-h-04-function-refinancefromloanexecutiondata-does-not-check.sol.
Key info#
| Impact | HIGH — borrower refinances a junk-NFT loan using a blue-chip-only offer by spoofing executionData.tokenId; lender funds principal while only the junk NFT remains in escrow |
| Protocol | Gondi — NFT multi-source lending |
| Vulnerable code | refinanceFromLoanExecutionData passes executionData.tokenId into _processOffersFromExecutionData without requiring equality to loan.nftCollateralTokenId |
| Bug class | Missing collateral-id consistency check on refinance |
| Finding | Code4rena — Gondi, 2024-04 · #35206 · reporter minhquanym |
| Report | code4rena.com/reports/2024-04-gondi |
| Source | AuditVault |
| Status | Audit finding — confirmed and mitigated (tokenIdCheck added) |
| Compiler | ^0.8.24 (PoC) |
TL;DR#
- Refinance re-uses the NFT already in escrow (no transfer out/in).
- Offer validation uses attacker-controlled
executionData.tokenId. - No check that it matches the escrowed
loan.nftCollateralTokenId. - Lender accepts a blue-chip id; escrow still holds junk → undercollateralized loan.
The vulnerable code#
// FIX would be: require(executionData.tokenId == loan.nftCollateralTokenId);
uint256 newLoanId = _processOffersFromExecutionData(
loan,
executionData.principalReceiver,
executionData.tokenId, // @> VULN: unmatched with loan.nftCollateralTokenId
newOfferId
);
Fix: require(executionData.tokenId == loan.nftCollateralTokenId).
Root cause#
Refinance optimizes by not moving the NFT, but still lets the borrower name a different token id for offer validation. Lenders' collateral constraints are checked against the spoofed id, not the asset actually secured by the protocol.
Attack walkthrough#
- Open loan against junk NFT #999.
- Post refinance offer requiring blue-chip #1.
- Call refinance with
executionData.tokenId = 1. - Offer validates; principal paid out; escrow still #999.
Diagrams#
Impact#
Lenders can be forced into loans secured by collateral they never accepted. Principal is at risk of total loss relative to the blue-chip they thought they underwrote.
Taxonomy#
- genome: wrong-condition, direct-drain, access-roles, liquidation-underwater, oracle-freshness, reward-accounting
- sector: lending, nft, nft-lending, staking
- severity: high
- platform: code4rena
Sources#
- AuditVault finding #35206
- Code4rena report 2024-04-gondi
- Reduced from code-423n4/2024-04-gondi
refinanceFromLoanExecutionData/_processOffersFromExecutionData/_checkValidators
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 35206-h-04-function-refinancefromloanexecutiondata-does-not-check_exp (evm-hack-registry mirror).
- AuditVault finding: 35206-h-04-function-refinancefromloanexecutiondata-does-not-check.
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.