Reproduced Exploit

ParaSpace — [H-08] NFTFloorOracle asset and feeder structures can be corrupted

1. Asset indices stored as uint8; assets never shrinks on remove (delete only). 2. After 256 assets, the next add stores uint8(256) == 0. 3. removeAsset then zeros the wrong slot — oracle structures permanently broken.

Nov 2022Otheruntagged2 min read

Chain

Other

Category

untagged

Date

Nov 2022

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: 15981-h-08-nftfloororacles-asset-and-feeder-structures-can-be-corr. Standalone Foundry PoC and full write-up: 15981-h-08-nftfloororacles-asset-and-feeder-structures-can-be-corr_exp in the evm-hack-registry mirror.


Vulnerability classes: wrong-condition · data-corruption · uint8 truncation

Reproduction: self-contained Foundry PoC with only forge-std — no fork. Full trace: output.txt.

AuditVault taxonomy: lang/solidity · platform/code4rena · severity/high · sector/lending · sector/nft · sector/oracle · genome: wrong-condition · data-corruption/price-manipulation · access-roles


Key info#

ImpactHIGHuint8 index wrap past 255 permanently corrupts asset/feeder maps
ProtocolParaSpace
Vulnerable codeNFTFloorOracle._addAsset / _addFeederuint8(assets.length - 1)
Bug classUnsafe downcast of array index
FindingCode4rena 2022-11-paraspace · #15981 (H-08) · reporter Jeiwan
Note#25724 is the same root cause (deferred as duplicate)
Compiler^0.8.24 (PoC)

TL;DR#

  1. Asset indices stored as uint8; assets never shrinks on remove (delete only).
  2. After 256 assets, the next add stores uint8(256) == 0.
  3. removeAsset then zeros the wrong slot — oracle structures permanently broken.

The vulnerable code#

SOLIDITY
assets.push(_asset);
assetFeederMap[_asset].index = uint8(assets.length - 1); // @> VULN: truncates once length > 255
// FIX: use uint32/uint256 index

Diagrams#

flowchart TD A["assets length grows forever"] --> B["length hits 257"] B --> C["uint8 length-1 wraps to 0"] C --> D["removeAsset deletes assets 0"] D --> E["Wrong asset wiped; map desynced"]

Impact#

Inability to correctly address assets/feeders → oracle malfunction and collateral mispricing.

Remediation#

Widen index type to uint32/uint256; pop assets on remove like feeders.

Sources#


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.