Option 1 — Governance-approved contract registry + log-based detection
recommendedsize LReplace the fingerprint with a governance-gated ApprovedNftContracts map; move
detection from calldata parsing to ERC721 Transfer event logs; add the
(contract, token_id) dedup index; extend the RewardPoolReceiver
precompile to reject unapproved contracts so users keep custody.
Covers A1, A2, A3, A4 and B.
Advantages
- The only option that closes all four tickets and defect (B).
- Net simplification: deletes
is_erc721_compatible,get_contract_code,is_sent_to_reward_pool_address,extract_token_id_param,extract_from_param— all five hand-rolled offset parsers, i.e. the exact class of bug that produced F3/F4. - Strictly cheaper
on_finalize: removes the full-bytecode read (up to 24 KB of PoV per EVM tx) and the 9×O(code_len) scan; adds one O(1) registry read per candidate log, memoizable with the sameBTreeMappattern already used for the reputation cache atlib.rs:397. - Revert-safety is free and structural — reverted frames have no logs.
- The log's
fromtopic is both unspoofable and the true prior owner, so it preserves the approved-operator semantics the comment atlib.rs:452-462deliberately defends. Strictly better than the ticket'stransaction_status.fromsuggestion, which would credit marketplaces and relayers instead of owners. - Detects nested/internal transfers to the pool that the top-level calldata check misses today — those NFTs are currently orphaned.
- No EVM call in
on_finalize. - Reuses the existing
EnsureRootOrHalfAndMinTechnicalorigin.
Disadvantages
- Makes NFT submission permissioned. If permissionless submission is the product intent, this is a product decision, not a bug fix — needs a call before implementation.
- Governance operational burden and onboarding latency for every new collection.
- The registry is a trust point: approving one contract with an owner-callable
mint()re-opens (B) completely. Approval review quality becomes a security control. - Largest diff of the detection options; rewrites
process_eth_transactionand reworks the test fixtures (AccountCodesinjection →TransactionStatus.logsconstruction). - Needs genesis seeding for dev/testnet/mainnet specs and
eth-tests, and possibly a storage migration to backfill the dedup index frompallet_fractional_nft::CollectionIdNftInfo. - Broader detection (internal transfers) is a behavioural change needing its own tests.