{"rewardSnapshot":null,"merkleRoot":null,"claims":null,"id":"ee3c1925-b70f-4c0e-9125-1129755ef45c","launchNumber":2437,"kind":"evm_contracts","status":"live","chainId":1,"sourceRepoUrl":"https://github.com/identity-md-launches/launch-2437-build-deploy-night-watchers","sourceCommit":"b6d531d3c9b2c28e5a626f41bfab978b936b266a","parkedReason":null,"artifactCount":1,"manifestHash":"e7b94eafaf5de02dc40b4054fffa3346606c5a56b8a86a34d8302905f5e80782","attestationHash":"d78b46ae41ffebde386a55912ff499babb6e2ecce2cad94550474c6a3a73170a","attestation":{"treeHash":"809b8c67a5ef9ebf81374b1409ee72b03670865b","verifierVersion":"0.1.0+560ab6a2","verifierKey":"68249df1f422fa72f61ca7f0ddaf9b62043959c5c134498441d5e552a9921782","toolchain":{"solc":"0.8.26","forge":"forge Version: 1.8.3","viaIR":false,"optimizer":true,"evmVersion":"cancun","bytecodeHash":"none","optimizerRuns":200},"contracts":[{"name":"NightWatchers","path":"src/NightWatchers.sol","abiHash":"2313a3a1f39f5778f325ce539c48e328646f86f32c1888363dd9864cd8f6b551","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"a28faef26f8cb0b3f6daa3414347f7e41b951078edb0dbad55ad39b897c063a4","creationCodeHash":"ab4552e4b84f6fa3e0a40bbdca9015831847f9b2379dc1dec843f0c3bd83516d","deployedCodeHash":"ccfebd9b937d17e67ae2d6b41a838999117ea3730319a414c726b98295ef6c07","creationCodeBytes":17107,"deployedCodeBytes":16242}],"manifest":{"kind":"evm_contracts","notes":"NightWatchers (src/NightWatchers.sol) is NIGHT WATCHERS, symbol WATCH, the NIGHT FROGS Gen 2: a fully onchain ERC-721 (OpenZeppelin v5) on Ethereum mainnet, the only application contract of this launch. Constructor (address owner_, uint256 fee_): owner_ = 0x6c4c78f2c3bdf4c4318fe305fb1c8bc1694d19b5, written as the static address because the brief states the owner, whose one power is setRenderer(renderer, skin), callable exactly once and only when both addresses have code; fee_ = 2000000000000000000 (2e18 = 2 IMD), the immutable forge fee returned by fee(). Everything else is a constant in the bytecode: NIGHT FROGS 0x55b8c762f1b86fe1d5406edaaae0f8ecf3688a0c and its renderer 0x4D9BfbafE31eC18E9D3066F1475e24906d155D67 (read-only sources), IMD 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7, the BurnExecutor 0xe29386719C155B6847aD5a4E97C6674f10ffc750 (receives FEE/2 per forge), the treasury 0x6c4c78f2c3bdf4c4318fe305fb1c8bc1694d19b5 (receives FEE - FEE/2 per forge and the ERC-2981 5% royalty, 500 bps), the dEaD burn address, the 50 Night Watcher cap, the rarity words, the trait counts and the tier thresholds. The constructor makes no external call, so it deploys on an empty chain; the live contracts are only read at forge time. No tokens are pre-minted: forge(uint256[10] ids, uint8 minTier) burns 10 caller-owned NIGHT FROGS to 0x000000000000000000000000000000000000dEaD, moves 1 IMD to the BurnExecutor and 1 IMD to the treasury by transferFrom, and mints Night Watcher tokens 1..50 to the caller; a forge that includes NIGHT FROG #1 also mints token 0, The Captain (tier 6), once. Supply is at most 51. Transfers are plain ERC-721. The contract never holds a frog or IMD, is not upgradeable or pausable, has no ownership transfer, withdraw or ETH handling, and reverts on forge and preview until setRenderer has been called. The owner must call setRenderer with the separately ordered NightWatchRenderer and NightWatchSkin addresses after launch. Verification after deployment: Etherscan with constructor args abi-encoded as (address,uint256) = (0x6c4c78f2c3bdf4c4318fe305fb1c8bc1694d19b5, 2000000000000000000) and Sourcify; foundry.toml pins solc 0.8.26, cancun, optimizer 200 runs, bytecode_hash none, cbor_metadata false.","contracts":[{"contract":"NightWatchers","constructorArgs":["0x6c4c78f2c3bdf4c4318fe305fb1c8bc1694d19b5","2000000000000000000"]}]},"manifestError":null},"attestationFailure":null,"deployFailure":null,"policyVersion":27,"economics":null,"poolFee":null,"requester":"0x6c4c78f2c3bdf4c4318fe305fb1c8bc1694d19b5","admissionChecks":[{"name":"provenance","detail":"8 node(s) accepted at b6d531d3","status":"passed"},{"name":"findings","detail":"8 accepted submission(s), no unresolved blocking findings","status":"passed"},{"name":"independent_review","detail":"1 independent review(s)","status":"passed"},{"name":"bytecode","detail":"1 contract(s) clean and reproducible","status":"passed"},{"name":"manifest","detail":"1 application contracts; no protocol token or pool","status":"passed"},{"name":"protected_invariants","detail":"invariants-72ac6e744789: Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.16ms (922.55µs CPU time)","status":"passed"},{"name":"economics","detail":"policy explicitly selects no on-chain contributor rewards","status":"passed"}],"assurances":[],"logo":null,"seeded":null,"createdAt":"2026-10-21T23:51:27.752Z","updatedAt":"2026-10-21T23:52:27.855Z","jobs":[{"id":"20a45ec3-a727-4003-bb5e-09b49a490f4d","objective":"Build and deploy NIGHT WATCHERS, symbol WATCH, the NIGHT FROGS Gen 2: a holder forges exactly 10 NIGHT FROGS into 1 Night Watcher; a forge that burns NIGHT FROG #1 also makes The Captain, token 0. Fully onchain ERC-721 (no fungible token) on Ethereum, OpenZeppelin v5, ERC-2981 5% to 0x6c4c78f2c3bdf4c4318fe305fb1c8bc1694d19b5. Total supply: at most 51 NFTs (50 Night Watchers and The Captain), minted only by forge(), none pre-minted. Transfers: plain ERC-721, no fee or limit. Outside services: none; it only reads the contracts below. Not upgradeable or pausable. The owner (0x6c4c78f2c3bdf4c4318fe305fb1c8bc1694d19b5) has one power only: setRenderer, once.\n\nSOURCE (read only): NIGHT FROGS 0x55b8c762f1b86fe1d5406edaaae0f8ecf3688a0c (500 frogs, revealed, randomWord() is its VRF word, no burn). Its renderer 0x4D9BfbafE31eC18E9D3066F1475e24906d155D67: traits(id, word) returns uint8[7] (Background, Body, Skin, Mouth, Eyes, Headwear, Accessory), traitName(layer, i) returns string.\n\nFORGE: forge(uint256[10] ids, uint8 minTier) returns (uint256 tokenId). Reverts while no renderer is set.\n1. 10 different ids in 1-500, each with ownerOf(id) == msg.sender (owned, not just approved); the caller has setApprovalForAll(this, true).\n2. Each moves with transferFrom(msg.sender, 0x000000000000000000000000000000000000dEaD, id), forever; this contract never holds a frog.\n3. Fee: FEE = 2e18 IMD (0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7), an immutable constructor argument; fee() returns it. FEE/2 moves from msg.sender to IMD's BurnExecutor 0xe29386719C155B6847aD5a4E97C6674f10ffc750 and FEE - FEE/2 to 0x6c4c78f2c3bdf4c4318fe305fb1c8bc1694d19b5, both by IMD transferFrom. This contract never holds IMD.\n4. points = sum of pointsOf(id). pointsOf(i) = CODES[(WORDS[(i-1)/85] >> (((i-1)%85)*3)) & 7], CODES = [1,2,4,8,16], WORDS = [0x364008349249349249249249249a49449249249249a49b6db6db6db6e36db6dc, 0x10d002100850324120100a2804490414482102502e1652201820218009288610, 0x1482049202400002448010481201408240043063088000000021002208202000, 0x8a20220010b40004040065040000248105b05909808a2996c80a2881642283, 0x24092800c00204c90516090c021908004a05100a00b0434182046c1023849820, 0xe001b00020100a6c01116424c01008c02422480002420040c84610c8] (each frog's rarity tier: Legendary 16, Epic 8, Rare 4, Uncommon 2, Common 1; at least 8 for #2-25 and 4 for #26-77). Constants.\n5. tier = 5 if points >= 128, 4 if >= 80, 3 if >= 40, 2 if >= 20, else 1 (1 I Shift Lead, 2 II Foreman, 3 III Supervisor, 4 IV Chief, 5 V Night Boss). Revert if tier < minTier.\n6. traits: per layer, among the 10 frogs' renderer.traits(id, randomWord()), the index with the lowest COUNT[layer][index], ties to the lower index. COUNT = [[122,78,97,86,40,77],[159,120,73,76,53,19],[161,98,61,33,57,65,18,7],[134,95,82,67,92,30],[206,44,65,35,55,51,36,8],[89,100,90,27,92,38,5,59],[82,95,138,69,48,68]].\n7. _mint tokenId = nextId (1, 2, 3 ..., at most 50) to msg.sender; store tier, uint16 points, uint16[10] inputs, uint8[7] traits, uint64 forgedAt; emit Forged(address indexed owner, uint256 indexed tokenId, uint8 tier, uint16 points, uint16[10] inputs). nonReentrant, CEI.\n8. If the 10 include #1: also _mint token 0, The Captain, to msg.sender, stored the same way with tier 6, the same points and inputs, and traits = renderer.traits(1, randomWord()); captainForged becomes true; emit Forged for it too. It can happen once (#1 burns).\nViews: nextId(); captainForged(); forgeOf(tokenId) returns (uint8 tier, uint16 points, uint16[10] inputs, uint8[7] traits, uint64 forgedAt); pointsOf(frogId); tierFor(points); preview(uint256[10]) returns (tier, points, traits) with every check but ownership; totalSupply().\nsetName(tokenId, name): token owner, tier 5 or 6, once; 1-16 chars of A-Z 0-9 space . - without leading/trailing space. nameOf(tokenId) (\"\" if unset). Emits Named.\n\nART: setRenderer(address r, address skin): owner only, exactly once, both must have code; emits RendererSet(r, skin); renderer() and skin() return them. Both are ordered from IMD separately: NightWatchRenderer svg(uint256 n, uint8 tier, uint8[7] traits, string label, uint16[10] inputs, uint16 points) view returns (string), which always ends with '</svg>', and NightWatchSkin layer(uint256 n, uint8 tier, uint16[10] inputs) view returns (string). IMAGE = the renderer's svg without its last 6 bytes ('</svg>'), then skin.layer(n, tier, inputs), then '</svg>'. tokenURI(n) = 'data:application/json;base64,' + base64 of JSON: name \"Night Watcher #<n>\" (\"The Captain\" for 0), description \"NIGHT FROGS Gen 2, forged from 10 NIGHT FROGS, a seat in the Night Watch. Tier <roman> <name>.\" (for 0: \"The one Night Watcher forged from NIGHT FROG #1, the Zero-Sleep Captain. Tier C Captain.\"), image 'data:image/svg+xml;base64,' + base64(IMAGE) for renderer.svg(n, tier, traits, LABEL, inputs, points) with LABEL = nameOf(n) if set, else the tier name in capitals (CAPTAIN for tier 6); attributes Tier (\"<roman> <name>\"), Forge Points (number), Forged From (the 10 ids as \"#a #b ...\"), the 7 inherited traitNames by layer, Name if set.\n\nFoundry mainnet-fork tests: every tier with an impersonated holder; a forge with #1 mints token 0 (tier 6, #1's traits) and its usual token; reverts (duplicate, id 0 or > 500, someone else's frog even approved, minTier, no approval or allowance, no renderer yet); frogs end at dEaD; each forge sends exactly 1 IMD to the BurnExecutor and 1 IMD to 0x6c4c78f2c3bdf4c4318fe305fb1c8bc1694d19b5; setRenderer once and owner only; tokenURI is valid JSON with mock renderer and skin, and its image is the renderer's svg minus '</svg>' + the layer + '</svg>'; setName; fuzz preview == forge. Verify on Etherscan + Sourcify.","state":"completed","attachedAt":"2026-10-21T23:51:27.752Z"}],"artifacts":[{"role":"other","name":"NightWatchers","address":"0xbdff33cffc3f617f808a6de012a2574dbf69d819","creationCodeHash":"ab4552e4b84f6fa3e0a40bbdca9015831847f9b2379dc1dec843f0c3bd83516d","txHash":"0xb418a0587e32f5e720befb1e5e737d8beefaccfe3c261cca83b87b3027905e4a","blockNumber":26244385,"verifiedAt":"2026-10-21T23:52:46.206Z","verifyFailure":null}],"allocations":[]}