Gravitational plate of three masses and a slashed discABC0Static engraved plate. Three-dimensional view is unavailable or reduced motion is requested.

← back to fieldarticle

articleDec 25, 2022

Damn Vulnerable DeFi — Free Rider (msg.value reuse in NFT marketplace)

High-level look at DVDeFi Challenge #10 Free Rider: batch NFT purchase logic that reuses a single msg.value across many buys, plus marketplace payout quirks. Solve steps omitted.

Damn Vulnerable DeFi Challenge #10 — Free Rider

Educational wargame by @tinchoabbate. Public contracts live under the free-rider challenge tree. Solve scripts and PoC omitted.

Theme

A marketplace lists six Damn Valuable NFTs at a fixed ETH price. A buyer offers a bounty for delivering all tokens. The player starts with little ETH but has access to a Uniswap V2 pair that can provide short-lived liquidity (flash-swap style capital).

Root-cause concept

  • msg.value reuse in a batch buy: an external buyMany-style entrypoint loops private _buyOne helpers. Each iteration still sees the same call’s msg.value, so a payment meant for one NFT can incorrectly satisfy many price checks
  • Marketplace accounting that pays sellers from contract balance without tightly binding “one payment ↔ one transfer” makes underpayment profitable
  • Resale / offer flows on the same marketplace can further distort who holds ETH versus who holds NFTs after a bad buy

Impact (abstract)

In the lab, a player can obtain all listed NFTs and claim the buyer bounty while only providing a fraction of the naive sticker price—then settle any temporary borrowed liquidity inside one transaction. In production terms: batch checkout that trusts msg.value once per multi-item loop undercharges buyers and drains marketplace inventory/funds.

Mitigations / lessons

  • For multi-item purchases, require msg.value to cover the sum of prices (or pull ERC-20 with explicit per-item amounts)—never re-check the same msg.value as if it were fresh each iteration
  • Prefer pull-payment patterns and explicit accounting events per tokenId
  • Separate “buyer bounty escrow” from marketplace treasury logic with clear ownership and reentrancy guards already present where needed
  • Treat flash liquidity as a reminder that economic bugs are often one-transaction complete

Solve steps and PoC omitted.

related

  1. Dec 22, 2022/articleDamn Vulnerable DeFi — Compromised (oracle trust & leaked reporter keys)
  2. Dec 21, 2022/articleDamn Vulnerable DeFi — Selfie (flash-loan governance)
  3. Dec 16, 2022/articleDamn Vulnerable DeFi — Side entrance (high-level)

graphfeed