// TECHNICAL DOCS
/DOCS
A complete description of the system: how the puzzle-mint flow works, where the cryptography lives, and what was audited.
// OVERVIEW
Hash Shifters is 333 NFTs on Ethereum mainnet, minted exclusively through daily cryptographic puzzles solved with Claude Code. Three rounds, 111 NFTs each. Position-based pricing from $1 to $111. Rarity revealed globally seven days after the third round sells out.
The mint is gated by puzzles, not by gas wars or whitelists. No bot can mint without solving the round's challenge. Each committed slot is a wallet-bound capability that can't be transferred or stolen.
// THE SYSTEM
Four components, each independently auditable:
- 01Contract
HashShifters.sol— ERC-721 with server-signed mint authorization. Solidity 0.8.24, OpenZeppelin v5.6.1. Deployed immutably (no proxy, no upgradeability) at 0x02b2BeC8…708de896. Pausable, Ownable2Step, ReentrancyGuard. - 02Skill
/hashshifters-mint— Claude Code skill (Python). Computes the commit hash, signs it with the user's wallet, caches the salt, then later reveals the solution to receive the server-signed mintCode. - 03BackendNode.js + Fastify + SQLite. Verifies wallet signatures, assigns positions atomically, validates puzzle solutions, signs mintCodes with the server signer EOA. Lives at
api.hashshifters.space. - 04FrontendNext.js 16. Three primary surfaces: the round dashboard (commit progress + leaderboard), the challenge briefs, and the mint page that takes a server-signed code and calls the contract.
// THE FLOW (PER USER)
1. user installs the /hashshifters-mint skill in Claude Code
2. user reads the round's challenge brief, solves it with Claude as co-pilot
3. skill computes: commitHash = keccak256(solution ‖ salt ‖ wallet)
4. user signs commitHash with their wallet (personal_sign / EIP-191)
5. skill POSTs { roundId, wallet, commitHash, walletSignature } to backend
6. backend verifies the signature, atomically assigns the next position,
stores commit, returns position N and locked priceWei
... commit phase runs until 111 commits arrive ...
7. round closes; 6-hour reveal phase opens
8. user runs /hashshifters-mint reveal — skill POSTs solution+salt
9. backend re-computes commitHash, matches against stored value, runs
the verifier on the solution
10. on success, backend issues a server-signed mintCode containing
(chainId, contractAddress, roundId, position, wallet, lockedPriceWei,
mintCode) — ECDSA over EIP-191 envelope
11. skill prints a mint URL
12. user opens the URL, connects wallet, calls mint() — contract
verifies the signature, accepts payment, _safeMints the NFT// SECURITY MODEL
Every signature binds (chainId, contractAddress, roundId, position, msg.sender, lockedPriceWei, mintCode). A signature valid for one chain, contract, position, wallet, or price is invalid for any other tuple. Replay across chains or deployments is mathematically blocked.
msg.senderbinding means a leaked mintCode can't be used by a third party — the contract recovers the signer from the digest, which includes the original wallet. Sending the tx from a different wallet fails on-chain with BadSignature.
Per-block mint cap of 4 throttles a worst-case leaked-signer attack from "one block drain" to ~17 minutes — long enough for the owner's pause() to land.
Rarity is revealed via commit-reveal: the contract bytecode contains keccak256(seed) from deploy time. Seven days after sellout, the owner calls globalReveal(seed, baseURI), the contract verifies the preimage matches the commit, and the on-chain seed becomes the source of all rarity + image assignments.
The reveal seed is on paper in cold storage. It never touches a server or repo. The on-chain commit is the only public artifact before reveal day.
// AUDIT
Pre-launch internal audit pipeline (DIY, before paid external review):
| Tool | Coverage | Result |
|---|---|---|
| Slither | ~100 detectors | 0 real findings (5 false positives) |
| Aderyn 0.6.8 | full ruleset | 6 findings, 2 actionable applied |
| Mythril 0.24.8 | symbolic execution | 0 real (27 FP from 0.8.x checked-math) |
| Echidna 2.3.2 | 8 invariants × 10k random calls | 0 violations |
| OZ v5 checklist | 35 best practices | 35/35 pass |
| Adversarial agent ×2 | contract + cross-layer | 23 findings, 14 actioned |
| Foundry tests | 47 unit + fuzz | all passing |
| Sepolia rehearsal | full mint flow | green |
Full reports in the public repo: AUDIT.md, AUDIT-DIY.md, INTEGRATION_AUDIT.md, hshift1/audit-out/*.
External paid review is recommended (and welcomed). See audit-out/free-audit-paths.md in the repo for the bug bounty channel.
// ON-CHAIN REFERENCES
- Chain
- Ethereum mainnet (chainId 1)
- Supply
- 333 NFTs · 3 rounds × 111
- Pricing
- $1–$111 linear, paid in ETH at the rate locked at commit time
- Reveal delay
- 7 days post-sellout
- Placeholder URI
- /placeholder.json