# Arbitrary Transfer of Unowned NFTs

Meebits acceptTrade verified signatures via ecrecover without rejecting the zero address, letting an invalid signature transfer any unowned or unminted NFT.

- Payout: Audit contest
- Severity: high
- Program: LarvaLabs Meebits
- Disclosed: 2021-06-30
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-04-meebits-findings/issues/4
- Library page: https://bugbountylibrary.com/r/c4%3A2021-04-meebits%3AH-02
- Tags: area:web3 domain:web3 impact:integrity kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Meebits NFT marketplace contract (acceptTrade/tradeValid/verify)
**Root cause:** verify() accepts ecrecover's return value without checking it is non-zero; an invalid signature yields address(0), which matches the zero-address signer check, so verification passes.
**Steps:**
1. Call `acceptTrade` with a trade whose signature is invalid.
2. `tradeValid` invokes `verify`, which calls `ecrecover` and gets address(0) for the invalid signature.
3. `verify` returns true because the recovered signer equals the expected zero-address.
4. Trade proceeds, transferring any NFT whose `idToOwner` is zero, including unminted NFTs.
**How found:** Code review of the trade validation path: noticed verify relies on ecrecover and reasoned about ecrecover's zero-address return on invalid signatures, then checked whether verify guards against it.
**Exploitation:** Submit an acceptTrade with an invalid signature; ecrecover returns address(0), verify passes, and the trade transfers an NFT with idToOwner == 0 (unowned or unminted) to the attacker.
**Insight:** When auditing signature verification, always check whether ecrecover's address(0) return on malformed signatures is explicitly rejected; any signer comparison against a zero/default value becomes a bypass.

