01 — The Paradigm Shift
Traditional Platforms
Mint-on-Claim (Reactive)
01
User arrives claiming to own a PSA 10 Jordan rookie card
02
Platform accepts user-submitted cert number and card details
⚠ Attack: fake or recycled cert number
03
Platform mints a new NFT based on what the user claims
⚠ Attack: front-run minting race condition
04
User receives token — now the "owner" on-chain
⚠ Attack: duplicate mints for same physical item
05
Platform must retroactively detect and revoke fraud
⚠ Trust is granted first, verification happens later
VS
VaultFolio — Reverse Pre-Mint
Declarative Registry (Secure)
01
VaultFolio ingests PSA/BGS/CGC registry — every authenticated item pre-minted to escrow contract
✓ Tokens exist before any user arrives
02
User submits cert number and ownership proof (receipt, photo hash, email hash)
✓ Cert number looked up against immutable on-chain registry
03
Edge Function verifies proof, queries smart contract: token exists and is unclaimed
✓ Fraud impossible: token is already locked to PSA's exact data
04
Smart contract transfers pre-minted token from escrow to user's wallet
✓ Transfer, not mint — no new supply created
05
Ownership is on-chain. Provenance, photos, and claim metadata attached permanently.
✓ Verification happens before trust is granted
02 — Token Lifecycle: Five States, One Direction
📄
UNMINTED
No owner
Off-chain only
Registry record
queued for mint
batchPreMint()
operator only
ON-CHAIN
🔐
PRE_MINTED
Escrow contract
Polygon · ERC-721
Token exists.
Awaiting claim.
claimToken()
+ ownership proof
OWNED
👤
CLAIMED
User TBA wallet
Provenance locked
User owns token.
Provenance set.
transferToken()
sale / gift
TRANSFERRED
🔄
TRANSFERRED
New owner wallet
Chain preserved
New owner on-chain.
History intact.
invalidate()
fraud / dispute
🚫
INVALIDATED
Burn address
Flagged on-chain
Permanently
revoked.
03 — Fraud Attack Vectors: Before & After
Attack Vector 01
Fake or Recycled Cert Number
BEFORE: User submits PSA #12345678 for a counterfeit. Platform mints a token. Fraudster now has "verified" provenance.
AFTER: Token for cert #12345678 was pre-minted with PSA's exact data (card, grade, population). Metadata mismatch detected instantly. No token issued.
Attack Vector 02
Duplicate Claim (Two People, One Card)
BEFORE: Two users claim the same PSA cert. Race condition — whoever processes first gets the token.
AFTER: One token per cert. isClaimed mapping is set on first transfer. Second claimant fails at smart contract level — not application level.
Attack Vector 03
Front-Run Minting
BEFORE: Attacker monitors mempool for pending mint transactions and front-runs with higher gas to steal the token.
AFTER: Nothing to front-run. The token was minted to the escrow contract weeks before the user arrived. The minting race is over.
Attack Vector 04
Registry Data Tampering
BEFORE: Platform database is compromised. Item records modified to change grade, cert number, or ownership history.
AFTER: On-chain token metadata is immutable. The blockchain record is the source of truth. DB is a cache — the chain is the proof.
04 — Smart Contract: VaultfolioRegistry.sol
VaultfolioRegistry
ERC-721 · OpenZeppelin v5
Polygon
ReentrancyGuard
Ownable + Operator
batchPreMint()
Mints tokens for registry items to the contract address. Called by the VaultFolio operator after PSA/BGS ingestion.
onlyOperator
claimToken()
Transfers a pre-minted token from escrow to the user's wallet. Requires proof verification. ReentrancyGuard protected.
nonReentrant · JWT verified off-chain
mintNew()
For fresh purchases with no existing registry entry. Mints directly to the user's wallet. Returns PROVENANCE_ONLY status.
onlyOperator
invalidate()
Transfers token to the burn address and sets isInvalidated flag. Used for fraud resolution. Permanent and irreversible.
onlyOwner · permanent
05 — Data Security: On-Chain vs Off-Chain Separation
On-Chain (Polygon)
Immutable. Public. Permanent.
Token ID ↔ keccak256(uniqueIdentifier)
Owner address (TBA wallet or escrow)
Claim status (isClaimed boolean)
Invalidation flag (isInvalidated)
IPFS metadata URI (cert + grade + photos)
Transfer history (ERC-721 Transfer events)
Block timestamp of every state transition
DATA
BOUNDARY
Off-Chain (Supabase)
Queryable. Encrypted. RLS-Protected.
User PII (email, name — never on-chain)
Full item metadata (purchase price, notes)
High-res photos (Supabase storage, signed URLs)
Valuation history (live market data cache)
Insurance documentation (private, per-user)
Possession status (In Hand / Storage / Consigned)
Access gated by JWT + Row Level Security
06 — Security Properties of the Architecture
01
Fraud-Structurally Impossible
A token that already exists cannot be fraudulently minted. The minting race is over before any user arrives. The only remaining attack surface is the ownership proof — not the minting mechanism.
STRUCTURAL
02
PII Never Touches the Chain
User identity, purchase price, insurance details, and personal photos are stored in Supabase behind JWT auth and Row Level Security. Only ownership proof hashes and token IDs go on-chain. GDPR/Privacy Act compliant by design.
PRIVACY
03
Tamper-Proof Provenance
Once a token's metadata URI points to IPFS content, the content hash is permanent. No platform employee, hacker, or legal order can modify the historical provenance record without a detectable on-chain discrepancy.
IMMUTABLE
04
Operator/Owner Separation
The smart contract separates the operator key (hot wallet, used for batching) from the owner key (cold storage, used only for admin actions). Compromising the operator key cannot drain the registry or modify token ownership.
KEY MGMT
05
ReentrancyGuard on Claims
The claimToken() function is protected by OpenZeppelin's ReentrancyGuard. A malicious contract cannot trigger re-entrant calls to claim the same token twice before the isClaimed flag is set.
SMART CONTRACT
06
The Timestamp Is the Proof
Every pre-minted token carries a block timestamp. When VaultFolio ingests 50M PSA certs, those timestamps are permanent. A competitor who launches later cannot claim their registry predates ours. The chain is the audit log.
TIMESTAMP MOAT