Security
Last updated 2026-10-12 · nft2.club
How the NFT2 smart contracts and API were checked, what was found and fixed, and what each privileged wallet can and cannot do.
01Summary
19
13
0
| Severity | Found | Fixed | Acknowledged |
|---|---|---|---|
| Critical | 1 | 1 | 0 |
| High | 5 | 5 | 0 |
| Medium | 4 | 3 | 1 |
| Low | 6 | 4 | 2 |
| Informational | 3 | 0 | 3 |
Acknowledged items are risks the team has accepted with a reason; they are counted here but not described until they are resolved. Informational items have no security impact.
02What was checked, and how
- NFT2.solThe collection: paid and airdrop mints, tier reveal, go-live, liquidation
- accretiveToken_v2.solThe collection token: capped at 21M, minted only on payout
- NFT2Staking.solStaking for the collection token
- launchpad_v4.solBonding-curve sales in USDT, refunds, go-live into Uniswap V3
- NFT2Liquidator.solBurn an NFT2 and swap the payout in one transaction
- MarketplaceEngine.sol, MarketplaceConduit.solGasless listings and tier offers
- Backend APISign-in, admin access, airdrop signatures, uploads, market data
Not in scope: Business design: token split, prices, fees, tier weights and the halving schedule; Legacy contracts (launchpad v2/v3, the v1 token) and test tokens; The website's own code (beyond the wallet-signing flows it drives).
Every contract was scanned with two static analysers and reviewed line by line for access control, reentrancy, rounding, signatures, Uniswap and USDT integration, price manipulation, denial of service and randomness. Every finding has a test that reproduced it; after each fix the same test proves the attack fails.
Slither 0.11.4
Static analysis, 100 detectors, every in-scope contract
Aderyn 0.6.8
Second static analyser with different detectors
Foundry fork tests
70 tests against Ethereum mainnet and Sepolia state, including a proof for every finding
Foundry invariant tests
Token and staking rules checked across 128,000 random calls
npm audit
Backend dependencies
03Fixed findings
Issue. Listings and offers were signed in the same format, so a seller's public listing could be submitted as a buy offer and the seller charged their own price.
Fix. Listings and offers are now different signed types, and the new marketplace engine refuses any old signature.
Issue. The tier was decided inside the mint transaction, so a contract could undo every mint that did not roll the top tier.
Fix. Tiers now come from the two blocks after the mint, which do not exist while the mint runs; they appear about 36 seconds later.
Issue. The deploying wallet became a collection owner, and owners could burn any NFT after go-live and keep the payout.
Fix. Only the launchpad is an owner, every burn needs the holder's permission, and payouts always go to the holder.
Issue. An offer for a top-tier NFT could be filled with a common one.
Fix. Offers sign the tier and the engine checks every token's tier before settling.
Issue. A retired wallet sign-in route accepted a signature made for any other site.
Fix. The old routes were removed; sign-in only accepts the message the server issued, once.
Issue. A seller could list an NFT under a rarer tier than it is.
Fix. The server reads the tier from the chain before accepting a listing, and every purchase checks it again.
Issue. USDT purchases could not settle, and a token that reports failure quietly could deliver an NFT unpaid.
Fix. Every payment uses OpenZeppelin SafeERC20; real USDT settlement is tested on a mainnet fork.
Issue. Trade records and the coin price chart accepted unauthenticated writes.
Fix. The unused routes were removed and the server now reads coin prices from the Uniswap pools itself.
Issue. Releasing an unused airdrop signature returned the credit while the signature stayed valid.
Fix. An unused signature is handed back as-is instead of a new one being issued.
Issue. Uploads had no size limit and the image host accepted SVG.
Fix. Uploads are capped and limited to raster images.
Issue. Two backend packages had published advisories.
Fix. Both were updated.
Issue. Sign-in sessions lasted a year.
Fix. Sessions now last 30 days.
Issue. The API accepted requests from localhost pages in production.
Fix. Those origins are only allowed outside production.
04Who can do what
Every privileged role, in plain words. Anything not listed here is not possible for that role.
Launchpad · Owner wallets
Can: Change the treasury wallet, the AGB paired per collection and the owner list; withdraw AGB and other free tokens.
Cannot: Touch USDT owed to buyers, creators or the treasury, or the tokens of collections not yet live.
NFT2 collection · The launchpad only
Can: Mint on the curve, take the collection live, set the airdrop signer.
Cannot: Burn or move anyone's NFT, or choose a tier.
NFT2 collection · The creator
Can: Close the airdrop early; set the royalty (up to 10%).
Cannot: Mint, burn, or change tiers.
Collection token and staking · Nobody
Can: No owner and no admin functions; new tokens are minted only on the release schedule, within the 21M cap.
Marketplace · Conduit owner
Can: Authorise which engine may settle trades; claim the 0.25% marketplace fee.
Cannot: Move assets except through an authorised engine executing a user's signed order.
Liquidator · Nobody
Can: No owner; holds nothing between transactions.
Creators are responsible for the IP and art they launch. NFT2 does not verify who owns the rights to a collection, and the launchpad accepts any collection.
05Deployed contracts
Verify any address on the network's block explorer before you interact with it.
- Launchpad (AGB)Not deployed yet
- Marketplace engineNot deployed yet
- Marketplace conduitNot deployed yet
- LiquidatorNot deployed yet
- Launchpad (AGB)0x16Df215FbAD282565C5d74Fb0A3E2F2acF9d51bb
- Marketplace engine0xcadeb8118b53bc487292930ae20e22f37b8f99f6
- Marketplace conduit0x5e5ba453553221d23f23c3e60df81dfc2cbdfd65
- Liquidator0x29300C9eda34E8B6457FafF29353f0Ddd773E444
06Report a vulnerability
Email security@nft2.club with a description and, if you can, steps or a test that reproduces it. Please do not test against mainnet funds or other users, and give us reasonable time to fix an issue before disclosing it.
We will not pursue anyone who reports in good faith, avoids harming users or their data, and follows these steps.