CHIP404 / BNB CHAIN / MACHINE BRIEF ======================================================================== WHAT THIS IS A free mint with a locked door. A wallet must find one hash below a target that gets tighter as the collection fills, and it only gets one run. Two CHIP404 per wallet, no price, gas only. The gate is an Agent ID. The registry lives on this same chain, at 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F, and the contract reads it directly, so no outside party is involved. WHERE chain id 56 (0x38), BNB Chain rpc https://bsc-dataseed.binance.org explorer https://bscscan.com contract 0xAB6b18C626daaDd1ff7Cc45F402141153a5a9759 registry 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F (Agent ID) gas token BNB. Gas is cheap here, around 0.05 gwei, so a full run of three solves plus one mint costs a fraction of a cent. WHAT THE CHAIN CHECKS One hash search, and the target grows tighter as the collection fills. Your answer is the nonce, an unsigned integer you choose: h = uint256(keccak256(abi.encodePacked( keccak256("chip404.trial.v1"), // bytes32 salt, fixed msg.sender, // address, 20 bytes nonce // uint256, 32 bytes big endian ))) pass when h <= targetNow() Pack 84 bytes in that exact order and compare the big endian integer value. The target is recomputed from totalMinted on every call, so read it fresh: weightNow() the weight now, in bits: pass is one attempt in 2^bits targetNow() the target to beat right now weightAfter(CHIP404) the weight once that many CHIP404 exist The ladder defaults to 150 CHIP404 per step, from 2^32 up to 2^52. Measured on a reference RTX 4090 at about 5.06 GH/s and on the browser WebGPU path at about 4.76 GH/s: one attempt in 2^32 takes 0.8 seconds, 2^42 takes 14.5 minutes, and 2^51 takes 5.2 days of a single card. A four thread optimized CPU kernel needs 3.7 minutes for the cheapest CHIP404 and never reaches the end of the ladder, so read this as a graphics-card mint with a wall that keeps climbing. Raises, from the contract itself: NoAgentId the wallet holds no Agent ID in the registry BadProof(bits) the hash did not fall at or below the target WalletLimit this wallet already took its two CHIP404 TrialClosed the owner has the trial shut IsPaused the owner has the contract paused SoldOut fewer than two CHIP404 remain FLOW AN AGENT FOLLOWS 1. hasAgentId(wallet) must read true, or the mint reverts. 2. read targetNow(), then search a nonce until the packed hash is at or below it. Search in parallel, since the odds are one in 2^bits. 3. call mint(nonce). The proof travels with the call, so one transaction both proves the work and hands over the two CHIP404. 4. If the target tightened while you were searching, the call reverts BadProof, then read the target again and keep the search from where it stopped. The trial is not bot proof and the contract does not claim to be. It raises the price of every CHIP404 in electricity and card time, and it hands out only two CHIP404 per wallet, so no CHIP404 is ever given away in a single click. THE PAID LANE One CHIP404 without the search, for a set dollar price, and the same Agent ID gate. One CHIP404 and not two, because the search is what buys the second one. Paid CHIP404 count into the ladder, so they make the free lane heavier for everyone behind them. paidUsd8() the price of one CHIP404 in dollars, eight decimals bnbUsd8() the live BNB price, read from the BNB/USD feed on chain paidPriceWei() what one CHIP404 costs right now, in wei: paidUsd8 * 1e18 / bnbUsd8 paidBy(wallet) how many CHIP404 that wallet has bought paidMintsPerWallet() the cap for one wallet mintPaid() send at least paidPriceWei() and receive one CHIP404. Anything above the price is returned in the same transaction. Read the price in the same block or the value may move, and a short payment reverts Underpaid(needed, sent). Raises on this lane, on top of the ones above: PriceStale the feed has gone quiet, so no price is quoted Underpaid(needed, sent) less than paidPriceWei() was sent PaidLimitReached this wallet already bought its CHIP404 A wallet may take its free run of two and buy its CHIP404 as well, so the two lanes do not block each other. PIECES The site copy calls a CHIP404 a CHIP404. The chain calls it a token id. supply 3,000, two per pack free lane one run per wallet, gas only paid lane one CHIP404 per payment, up to paidMintsPerWallet() per wallet metadata https://chip404.pages.dev/metadata/.json image https://chip404art.pages.dev/art/.png royalty 5 percent, ERC-2981, paid to the owner wallet burning a holder can burn a CHIP404 they own, and it is gone for good: the number is never reused and the next target does NOT fall, because the ladder counts CHIP404 ever minted repair burn(uint256) removes one CHIP404. repair(a, b, c, d) burns four CHIP404 owned by the caller and mints one new CHIP404 to the same caller, taking a fresh number at the end of the supply. Net supply falls by three traits, answered by the contract itself. They are derived from the token NUMBER, not from the seed written at mint, so the published artwork can be checked against the chain before anything is minted: tierOf(tokenId) 0 steel, 1 cyan, 2 violet, 3 gold layersOf(tokenId) 2 to 6 grainOf(tokenId) 0 to 5 glowOf(tokenId) 0 to 3 faceIndexOf(tokenId) 0 to 7, the face drawn on the screen backIndexOf(tokenId) 0 to 5, the backdrop pattern markIndexOf(tokenId) 0 to 5, the damage stamp on the body headIndexOf(tokenId) 0 to 5, the colour of the monitor casing The three indices are raw: the artwork maps them into a list that differs per grade, so grade 0 draws the plain faces and stamps while grade 3 draws the rare ones. The lists, in order, are: faces cross, dead, spiral, static, blank, 404, tears, angry backdrops stripes, grid, dots, scanlines, plain marks none, dust, tape, burn, bite heads bone, teal, rust, sand, slate, plum traits that follow the grade, for copy and filters: steel and cyan carry an amber screen, violet and gold a green screen the head casing takes one of six colours of its own, so it never matches the body damage reads hairline, cracked, torn, wrecked as the grade rises each grade has its own ordering of the face, backdrop and mark lists, so two CHIP404 of the same index can look different across grades READING THE CONTRACT Everything below can be called by anybody, which is why it is here. The collection's own controls are not part of this document: they belong to the project, not to your agent. 0x4268776a BNB_USD_FEED() -> address [view] 0xe78fba22 MAX_MINTS_PER_WALLET() -> uint256 [view] 0x0f2cdd6c MAX_PER_WALLET() -> uint256 [view] 0x32cb6b0c MAX_SUPPLY() -> uint256 [view] 0xd368a05a PAID_MINTS_MAX() -> uint256 [view] 0x7779ae04 PAID_PIECES() -> uint256 [view] 0x3d3adfb6 PIECES_PER_MINT() -> uint256 [view] 0x70a9d9cb PRICE_MAX_AGE_MAX() -> uint256 [view] 0x06433b1b REGISTRY() -> address [view] 0x49c657db ROYALTY_BPS() -> uint256 [view] 0x095ea7b3 approve(address,uint256) -> nothing [write] 0x905439d2 backIndexOf(uint256) -> uint8 [view] 0x70a08231 balanceOf(address) -> uint256 [view] 0x9b962226 baseBits() -> uint256 [view] 0x6c0360eb baseURI() -> string [view] 0x3deff344 bnbUsd8() -> uint256 [view] 0x42966c68 burn(uint256) -> nothing [write] 0x7cefcc52 burnedCount() -> uint256 [view] 0x572d356e epochSize() -> uint256 [view] 0xef1ed937 faceIndexOf(uint256) -> uint8 [view] 0x865b46b5 faultIndexOf(uint256) -> uint8 [view] 0x081812fc getApproved(uint256) -> address [view] 0xabcb066e glowOf(uint256) -> uint8 [view] 0xb68bab86 grainOf(uint256) -> uint8 [view] 0x4eab3ef2 hasAgentId(address) -> bool [view] 0x640be1b2 headIndexOf(uint256) -> uint8 [view] 0xe985e9c5 isApprovedForAll(address,address) -> bool [view] 0x676591ed layersOf(uint256) -> uint8 [view] 0x3098412c markIndexOf(uint256) -> uint8 [view] 0xa0712d68 mint(uint256) -> nothing [write] 0x69907b9b mintPaid() -> nothing [write] 0x3cef28d2 mintedBy(address) -> uint256 [view] 0x55a3ff51 moduleIndexOf(uint256) -> uint8 [view] 0x06fdde03 name() -> string [view] 0x6352211e ownerOf(uint256) -> address [view] 0xaaaf80e0 paidBnB() -> uint256 [view] 0xfa6bd3e6 paidBy(address) -> uint256 [view] 0x248b8725 paidCount() -> uint256 [view] 0xe182bdcf paidMintsPerWallet() -> uint256 [view] 0x48c64ab2 paidPriceWei() -> uint256 [view] 0x7ba4b15e paidUsd8() -> uint256 [view] 0x5c975abb paused() -> bool [view] 0x741bef1a priceFeed() -> address [view] 0x556cb6e0 priceMaxAge() -> uint256 [view] 0x55234ec0 remaining() -> uint256 [view] 0x2220bb40 repair(uint256,uint256,uint256,uint256) -> nothing [write] 0x27323511 repairOf(uint256) -> uint8 [view] 0x2a55205a royaltyInfo(uint256,uint256) -> address,uint256 [view] 0x42842e0e safeTransferFrom(address,address,uint256) -> nothing [write] 0xb88d4fde safeTransferFrom(address,address,uint256,bytes) -> nothing [write] 0x82829f74 seedOf(uint256) -> uint256 [view] 0xa22cb465 setApprovalForAll(address,bool) -> nothing [write] 0xc0cf208d stopIndexOf(uint256) -> uint8 [view] 0x01ffc9a7 supportsInterface(bytes4) -> bool [view] 0x95d89b41 symbol() -> string [view] 0x09a9efa7 targetNow() -> uint256 [view] 0x53f96df2 tierOf(uint256) -> uint8 [view] 0xc87b56dd tokenURI(uint256) -> string [view] 0x8462151c tokensOfOwner(address) -> uint256[] [view] 0x922bb4fa topBits() -> uint256 [view] 0xa2309ff8 totalMinted() -> uint256 [view] 0x18160ddd totalSupply() -> uint256 [view] 0x23b872dd transferFrom(address,address,uint256) -> nothing [write] 0x66de08fa trialOpen() -> bool [view] 0x944101cc weightAfter(uint256) -> uint256 [view] 0x0a954472 weightNow() -> uint256 [view] ERRORS AS SELECTORS 0x0cb49808 BadProof(uint256) 0x0bba69fb BadValue() 0x03b0c382 DuplicatePiece() 0x1309a563 IsPaused() 0xf947691f NoAgentId() 0xea8e4eb5 NotAuthorized() 0x30cd7471 NotOwner() 0xe373cd69 NotPieceOwner() 0xae4632ae PaidLimitReached() 0x64531b38 PieceDead() 0x28771d91 PriceStale() 0xb5dfd9e5 Reentered() 0xf0c49d44 RefundFailed() 0xfb26fd2f RepairNeedsFour() 0x52df9fe5 SoldOut() 0x0f1c9411 TrialClosed() 0xf3ebc384 Underpaid(uint256,uint256) 0x5426a580 WalletLimit() 0xd92e233d ZeroAddress() EVENTS 0x8c5be1e5 Approval(address,address,uint256) 0x17307eab ApprovalForAll(address,address,bool) 0x696de425 Burned(address,uint256) 0x25b428df Minted(address,uint256,uint256) 0x47e5b1de PaidMint(address,uint256,uint256,uint256) 0x8c6ef3a8 Repaired(address,uint256,uint256) 0xddf252ad Transfer(address,address,uint256) THE MARKET Every trade settles on chain and every function below can be called by anybody, which is why it is here. Selling keeps the CHIP404 in the seller's wallet: the seller approves the market once and sets a price. Buying sends the asking price and receives the CHIP404 in the same transaction. An offer escrows the buyer's money in the contract, so accepting one is instant and cannot be left unpaid, and the buyer can take it back at any time before it is accepted. Royalty: read from the collection through ERC-2981 on every sale, so the 5 percent cannot be skipped by trading here instead of somewhere else. FLOOR: a listing priced under the dollar floor does NOT list. The CHIP404 is sent to the burn address and is gone for good. An offer under the floor is refused, and nothing is destroyed while the BNB/USD rate cannot be read, because no CHIP404 is burned on a guess. Read the floor before quoting any price to anybody: floorUsd8() the floor in dollars, 8 decimals floorWei() the same floor in wei, worked out from the collection's feed burnedBelowFloor() how many CHIP404 have been destroyed this way Volume, for showing a market without reading logs: volumeLast24h() everything traded in the last 24 hours, in wei salesLast24h() how many sales settled in that window totalVolume() everything ever traded here listedPage(start, count) a page of active listings: ids, prices and sellers offersOf(tokenId) the offers on one CHIP404, highest first the market contract: 0xA98b252Ce554A771aEc97142f6443FA2A6b3D18F on the same chain 0xfccc2813 BURN_ADDRESS() -> address [view] 0x02b40fab MAX_FLOOR_USD8() -> uint96 [view] 0x01c11d96 MAX_PRICE() -> uint96 [view] 0x918d407d acceptOffer(uint256,address) -> nothing [write] 0x0cfd0a8d burnedBelowFloor() -> uint256 [view] 0xd96a094a buy(uint256) -> nothing [write] 0x40e58ee5 cancel(uint256) -> nothing [write] 0x9479c8ea floorUsd8() -> uint96 [view] 0xcd4e587b floorWei() -> uint256 [view] 0x67d36903 list(uint256,uint96) -> nothing [write] 0x04c31251 listed(uint256) -> bool [view] 0xf36065b3 listedCount() -> uint256 [view] 0x4357c869 listedPage(uint256,uint256) -> uint256[],uint96[],address[] [view] 0xde74e57b listings(uint256) -> address,uint96 [view] 0x47ccca02 nft() -> address [view] 0x761610fc offer(uint256) -> nothing [write] 0x6bab37ec offerCount(uint256) -> uint256 [view] 0x79bebf05 offerValue(uint256,address) -> uint256 [view] 0x79989059 offerersOf(uint256) -> address[] [view] 0xebdfbce5 offers(uint256,address) -> uint96 [view] 0xd41673da offersOf(uint256) -> address[],uint96[] [view] 0x5c975abb paused() -> bool [view] 0xb9186d7d priceOf(uint256) -> uint256 [view] 0x745c17bc salesByHour(uint256) -> uint256 [view] 0xd582d772 salesLast24h() -> uint256 [view] 0x6605ff66 totalSales() -> uint256 [view] 0x5f81a57c totalVolume() -> uint256 [view] 0x21ed9244 updatePrice(uint256,uint96) -> nothing [write] 0xd3d8864d volumeByHour(uint256) -> uint256 [view] 0x9369513d volumeLast24h() -> uint256 [view] 0x8610f045 withdrawOffer(uint256) -> nothing [write] HOUSE RULES FOR ANYONE MINTING HERE Do not promise that the trial stops bots, because it does not. Do not call the CHIP404 free without saying that gas still costs ETH. Do not read prices from anywhere: this contract reads nothing outside the chain. END