How it works
Modern Punk is one ERC-721 contract. Nothing here is sold ready made: the only way a Punk comes into existence is a hash below the current target, paid for at the entry price of the current epoch, and it is always the next one in line.
Every moving part is below, and the instruments are real — keccak256 in your browser, the live chain, and the same formulas the contract uses.
What your browser
actually computes
Open the minerFour values, one hash, one comparison — and you can run them right here. Everything else on this page is a consequence of them.
A miner picks a nonce and hashes four values together: their own address, the nonce, the work behind the previous Punk, and an anchor — the hash of a recent block. 20 + 32 + 32 + 32 bytes, keccak256, 32 bytes out. If the result has at least as many leading zero bits as the target asks for, the contract accepts it, takes the entry price of the current epoch and mints the next Punk in line.
Every Punk is chained to the one before it. The work of the last Punk goes into the next one, so nothing can be mined ahead of time, and the moment somebody else mints, every solution being held becomes worthless.
The address is part of the work. That is what makes a solution untradeable: the same nonce and anchor produce a different hash for anybody else.
The miner runs on processor cores. One Web Worker per core, minus one so the page keeps drawing; each worker walks its own stride of nonces with the same keccak256 the contract uses, changing only the 32 nonce bytes of a reused 116-byte buffer. Pure JavaScript, no graphics card, no WebAssembly in this version — about 1.8 MH/s on an ordinary desktop.
A solution is checked before it costs anything. The worker reports it, the page hashes it again, then asks the contract's own checkSolution view against the chain as it stands. Only then is mine(nonce, anchorBlock) sent, with the entry price attached. The contract recomputes the whole thing itself; the browser's hash is a preview, never a claim.
The address is inside the hash, so a copied transaction computes to something else. The anchor and the previous work are public; your address is what makes them yours.
The contract mints at most once per block. Two valid solutions in the same block: the first one included wins, the second reverts — and its work was void anyway, because the previous work moved.
Thirteen workers on a 14-thread CPU, pure JavaScript keccak. At 20 bits that is under a second per Punk; at 32 bits, about forty minutes.
No wallet connected, so the zero address stands in. Connect one and this row — and every hash below — becomes yours.
The only free value of the four — this is what the workers spin, hundreds of thousands of times a second per core.
The work behind the Punk before yours. Every mint replaces it, and everything found under the old one is spent.
A recent block hash, read from the live chain. The contract accepts any of the last 250 blocks — about 25 seconds on Robinhood Chain.
The hash does not pick the picture. Punks are numbered, and the next number in line goes to whoever mints next: your hash is the proof of work behind Punk #n, recorded with it for ever, but #n was drawn long before you found it. Spare hashrate buys zero bits, and nothing else.
At 1.8MH/s — thirteen workers of an ordinary desktop, pure JavaScript keccak, no GPU. Every extra bit doubles all three numbers; there is no shortcut, and that is the whole point.
A solution dies with the next mint, or when its anchor leaves the window — whichever comes first. The anchor is the hash of a recent block, and the contract accepts one of the last 250 of them. At the planned pace the next Punk usually arrives first; the anchor is the backstop for a quiet hour.
One cell is 5 blocks of the 250-block window — about 25s at Robinhood Chain's 0.1 s blocks. A solution found against this anchor is sent with its block number; when the window runs out the solution is dead and the search starts again against a fresh anchor. The next mint usually ends it sooner: every mint replaces the previous work, which is inside the preimage too.
- Your browser reads the current target, the anchor, the work behind the last Punk and the entry price.
- Web Workers hash nonces until one lands below the target.
- The candidate is dry-run through
checkSolution, then sent to the contract with the entry price attached. - The contract recomputes the hash from your address and checks it itself — against the target for your address in that block, the price, the anchor and the one-per-block rule.
- The next Punk in line is minted to you, and its work becomes the previous work of everyone else’s search.
- The entry price stays in the contract until the owner withdraws it to the treasury. No rent, no hook, no token.
Six rules that
set the target
Difficulty is not one number drifting upward: a floor that rises with the epoch, a retarget every eight mints, and a streak that doubles the work for every recent mint.
Every bit doubles the search, so the two sliders multiply: the epoch sets the floor (14 + epoch on this chain), the streak stacks on top of it, and the price of that epoch moves alongside — money and work grow together. The floor is only the lowest the base can sit; the retarget can hold it higher.
- Epoch floorfloorBase + epoch
- Work doubles every epoch, and the retarget may never go below that line. Measured on the base difficulty, before the streak is added.
- Base difficultyread from the chain
- What the retarget works on. The first Punk was mined at the number the deployment set; from there the pace alone moves it, and it never goes below the epoch floor.
- Retargetevery 8 mints
- Compares the real pace of the last eight mints with the plan of 10 seconds each and moves the base: up to 4× harder in one window (+2 bits), at most 2× easier (−1), and never below the floor.
- Streak×2 per recent mint
- Adds one bit for every recent mint and cools one step at a time, every 10 seconds, counted per network and per address. Twelve mints in a row cost 4 096× the work of one; the doubling stops after 16 steps.
- Failsafe5 min, one bit
- After that much silence the target is one bit easier — never more. The first mint switches it off again.
- One Punk per block1 per block
- A hard ceiling, counted by the chain’s own block number. On a 2-second chain that is 30 Punks a minute at the very most; the rules above keep the real pace near one every 10 seconds.
Every epoch doubles three things at once: the floor's work, the size of the epoch and the price step — and halves what a burn returns. The last epoch, #2 041–3 333, is cut short by the cap: 3 333 Punks, then the contract refuses every solution.
| constant | value | note |
|---|---|---|
| baseBits | reading… | |
| floorBase | reading… | |
| TARGET_INTERVAL | 10 s | one mint every ten seconds is the plan |
| RETARGET_WINDOW | 8 mints | — / 8 into the current window |
| STREAK_COOLDOWN | 10 s per step | cap 16 |
| FAILSAFE_IDLE | 5 min, one bit | never deeper |
| ANCHOR_WINDOW | 250 blocks · 25s | Robinhood Chain |
| BLOCK_CEILING | 1 per block · 100 ms | counted by the chain, not by the clock |
What the price is,
and where it goes
The entry price is the number of Punks that already exist times a fixed step. It is derived, not chosen.
Epochs double. The first is 8 Punks, each next one twice as large: 8, 16, 32 … up to the last, which the 3 333 cap cuts short. The price is constant inside an epoch and changes only at its border.
The price is derived, not chosen. It equals the number of Punks minted before the epoch began times 0.00002 ETH. Epoch 3 starts after 56 Punks, so every Punk in it costs 56 × 0.00002 = 0.00112 ETH. There is no list of prices in the contract, only that one line.
The first 8 Punks are the exception. Nobody exists before them, so they cost a flat 0.000069 ETH. From the second epoch on, the formula above is the whole story.
Where it goes. Every entry price stays in the contract until the owner calls withdraw(), which sends the balance to the treasury address. There is no rent to earlier Punks, no hook, no buyback and no token to buy back: what a Punk costs is the work behind it, and the price is the ticket.
The first six epochs together. The price is flat inside an epoch, so a whole epoch is entered at one number — and these are pocket change. The work is what you pay.
The last epoch would run to #4 088; the cap stops it at #3 333. After that mine() reverts with SoldOut whatever the hash.
| Epoch | Punks | Size | Before it | Price (ETH) |
|---|---|---|---|---|
| 0 | #1–8 | 8 | 0 | 0.000069 |
| 1 | #9–24 | 16 | 8 | 0.00016 |
| 2 | #25–56 | 32 | 24 | 0.00048 |
| 3 | #57–120 | 64 | 56 | 0.00112 |
| 4 | #121–248 | 128 | 120 | 0.0024 |
| 5 | #249–504 | 256 | 248 | 0.00496 |
| 6 | #505–1 016 | 512 | 504 | 0.01008 |
| 7 | #1 017–2 040 | 1 024 | 1 016 | 0.02032 |
| 8 | #2 041–3 333 | 1 293 | 2 040 | 0.0408 |
The identity the price rests on: the number of Punks that already exist, times one fixed step. Nothing is chosen per epoch; the table above is that one line evaluated nine times.
The other exit:
burn it for points
A Punk burned in its own epoch credits 1 000 PUNK points to the address that burns it. Wait an epoch and it is 500; wait two and it is 250. Burning is final.
A Punk cannot be burned the minute it is mined. Two doors stand before the burn: at least one more Punk has to exist after yours, and 10 minutes have to pass since the mint. The contract answers both separately (burnQuote), so the Punk page can tell you which one you are waiting on.
Points are a number on-chain, next to your address. points[owner] goes up, the token goes away, Burned is emitted. The site shows the balance next to the wallet button. There is no ERC-20, nothing to trade and nothing to approve: PUNK points are an airdrop promise, not a token.
The supply stays 3 333 for ever. A burned id is never reissued and minted never goes down, so a burn does not make room for another mint. It makes the collection smaller.
The halving is per epoch, not per day. The clock is epoch() − punk.epoch: the epoch of the next mint, minus the one your Punk was mined in. On a quiet chain a Punk can sit in its own epoch for a long time at the full rate; a busy chain melts it faster.
Halves with every epoch waited, down to 1. Inside an epoch the rate does not move at all; it drops at the border.
| Waited | Points |
|---|---|
| own epoch | 1 000 |
| 1 epoch | 500 |
| 2 epochs | 250 |
| 3 epochs | 125 |
| 4 epochs | 62 |
| 5 epochs | 31 |
| 6 epochs | 15 |
| 7 epochs | 7 |
| 8 epochs | 3 |
1 000 points if the burn lands in the same epoch the Punk was mined in, half of that for every epoch waited, never below 1. Points are credited to the burner's address on-chain and shown next to the wallet; the Punk is gone for good and its number is never reissued.
3 333 portraits,
drawn before the first hash
Browse PunksEvery Modern Punk is a 128 × 128 pixel portrait, pre-rendered and scaled 8× to 1 024 px with no smoothing. The set was fixed before deployment; mining decides who gets the next one, not what it looks like.
Sequential assignment. Token id, edition and artwork number are the same integer. The next Punk in line is yours — the hash does not pick the picture, and no amount of hashrate reaches past the queue. A farm cannot grind for a rare Punk; it can only be first to the next one.
Seven trait types. 7 layers per portrait, 81 values in all. Rarity is a share of the 3 333, known in advance and printed on every Punk page next to the trait.
Provenance. Every image has a SHA-256, and the SHA-256 of all 3 333 of them in order is the provenance hash below. The per-image hash is printed on the Punk's page; recompute it from the PNG and it matches, or the site is lying.
Served by this site. Images and metadata come from /api/image/[id] and /api/metadata/[id]; the contract's baseURI points here and the owner can move it. No IPFS yet — the provenance hash is what pins the set until then.

| Trait | Values | Rarest |
|---|---|---|
| Background | 10 | Plum · 280 |
| Equipment | 15 | Golden Scythe · 4 |
| Skin | 6 | Cool Umber · 555 |
| Clothes | 6 | Black Techwear · 555 |
| Face | 6 | Silver Beard · 51 |
| Eyes | 11 | Yellow Laser · 54 |
| Head | 27 | Golden Helmet · 7 |
d92e4bb0c1ae493f3fe9b0b3c3539e82090924019810fd2969ee09e9ff969209Concatenate the SHA-256 of /punks/1.png through /punks/3 333.png as hex, in order, hash the string once more, and this is what you get.
The whole thing,
by address
One contract: the ERC-721, the mining rules, the price table, the burn and the points all live in PunkMiner. The site is told its address; everything else on this page it asked the chain for.
- 01 PunkMiner0x884c6c6e0df7cd330d77bcbbd9117607a06308bc
The collection: mining, the target, epochs, burning, PUNK points. An ERC-721 that mints to nothing but a hash below the target, paid at the entry price.
- 02 Treasuryreading…
Where
withdraw()sends the entry prices. Set once in the constructor; the contract holds the ETH until the owner calls it. - 03 ChainRobinhood Chain · id 4 663
RPC
https://rpc.mainnet.chain.robinhood.com· explorer robinhoodchain.blockscout.com. Blocks every 100 ms; block numbers and hashes come from ArbSys.
ArbSys), a 32-bit start and a 26-bit floor.Things people
ask first
10 answers about getting one, mining against a farm, and the art.
Getting one
Can I just buy one?
mine() refuses anything that is not a hash below the target. Somebody who already mined one can sell it on any marketplace, like any ERC-721 — that is the only way a Punk changes hands without work.What am I paying for, then?
Why does the price go up?
The art
Can the art disappear?
baseURI at a new home. The tokens, the work hashes and the points live on-chain regardless.What are PUNK points?
Mining against a farm
Does mining in a browser stand a chance?
Can someone steal my solution?
Can a farm grind for a rare Punk?
Does a big holder mine cheaper?
What happens when all 3 333 are mined?
mine() reverts with SoldOut for ever. Burning still works — the doors only need a later Punk and ten minutes — and points keep accruing; ids are never reissued, so the supply only shrinks from there.Real keccak256 in your browser, at the current target and the current price.
Mine a PunkEvery Punk mined so far, with the work behind each one.
Browse PunksThe one contract that holds the rules, the ids and the points.
Contract