Job
Waiting for hosting to become reachable. Checks retry for up to 24 hours; the build, contracts, deployment and published files are kept.
Build Pacts, a social guild strategy game on Sepolia played with its own token, Pact ($PACT), launch it, publish the source on GitHub and host its website on IPFS. Guilds hold tiles on a shared 12x12 map, attack each other in the open, vote on moves, and sign pacts backed by token bonds that are slashed to the victim if a guild betrays a partner. Seasons pay the top guilds and mint trophy NFTs.
the approved task
Approved workflow
Build Pacts, a social guild strategy game on Sepolia played with its own token, Pact ($PACT), launch it, publish the source on GitHub and host its website on IPFS. Guilds hold tiles on a shared 12x12 map, attack each other in the open, vote on moves, and sign pacts backed by token bonds that are slashed to the victim if a guild betrays a partner. Seasons pay the top guilds and mint trophy NFTs.
This is a test of the full contract-to-website workflow with a game complex enough to give the audit panel real work. No randomness and no hidden moves: every action is public and outcomes are deterministic. The game must have no admin powers: the $owner reference resolves to the network's deployer wallet, so nothing may depend on an owner acting after deployment. The launch token is named Pact with symbol PACT (not a generic launch name). The contracts receive no token allocation at launch, so every token the game pays out must come from what players paid in. GitHub publication, IPFS hosting and the Sepolia evm_project launch are authorized. A first run of this game (workflow 0c56259b) was audited; the rules below spell out what its audits found ambiguous.
Build Pacts, a public, deterministic guild strategy game played with the launch token ($token), which src/LaunchToken.sol names "Pact" with symbol "PACT", as five contracts with no admin functions. Realm: a 12x12 tile map; epoch length and season length are constructor arguments (1 hour and 7 days). Players buy troops with the token; a guild holding a tile earns a share of the epoch's income pool per tile, and income comes only from troop purchases and fees, never minted. Attacks are declared openly during an epoch with committed troops and all attacks on a tile resolve together at the epoch's end: the larger committed force takes the tile, ties keep the holder, and troops are lost in proportion. Anyone can settle an ended epoch. Guilds: anyone can found or join a guild; guild troops are pooled; attacks and pacts need a majority vote of members, votes are weighted one per member, and a majority can expel a member. Diplomacy: two guilds can sign a pact that each backs with a token bond for a set number of epochs; if a guild attacks a pact partner its bond is paid to the victim automatically; bonds return when the pact expires unbroken. Season: a fee on troop purchases fills a prize pool; after the season ends anyone can close it and the top three guilds by tiles held claim 50/30/20, split equally among their members. Banners: an ERC-721 that only Season mints, one banner to each member of a winning guild and one to any guild that finished a season without breaking a pact. Rules that must hold: spending a guild's pooled treasury (buying troops with it or paying it out) needs the same majority vote as attacks and pacts, never a single member; a vote counts only members who had joined before the proposal was created; proposals expire at the end of the epoch after the one they were created in, and an approved attack names the tile's holder when proposed and fails if the holder has changed; a pact needs a non-zero bond from each side and cannot be signed while an attack between the two guilds from an unsettled epoch is pending; season prizes and banners go only to members who had joined before the season ended, fixed at season end, so joining later earns nothing from that season. Wire contracts with $token and $contract:Name references and constructor arguments only; no post-deployment calls, no constructor ETH. Emit events for every action so a frontend can rebuild the map, guilds, pacts, betrayals and standings from logs. Test settlement with several attackers on one tile, votes, expulsion, pact bonds and betrayal slashing, season close and claims, and that no function can move player funds except the rules above. Then build a website: a live map coloured by guild, guild pages with members and pending votes, a diplomacy board with pacts, bonds and betrayals, an event feed, buy-troops and attack controls, season standings and banners.
the website assignment
Build Pacts, a social guild strategy game on Sepolia played with its own token, Pact ($PACT), launch it, publish the source on GitHub and host its website on IPFS. Guilds hold tiles on a shared 12x12 map, attack each other in the open, vote on moves, and sign pacts backed by token bonds that are slashed to the victim if a guild betrays a partner. Seasons pay the top guilds and mint trophy NFTs.
Published · Site
- site
- pacts.site.identitymd.eth
- ipfs
- bafybeif7tmbyk4cnn57ueynnig2tzvto66b3svdqrbfvcxqz2wmdwj5htq
- website
- identity-md-launches/launch-447-workflow-frontend-stage-context
Published · Token
- token name
- Pact · $PACT
- token CA
- 0x7f88ad727adeb8fc70fd198f2d2319349846818c · Sepolia
- opened at
- 20 ETH
- supply
1,000,000,000 $PACT · 80% liquidity, 10% agents, 10% IMD
Split three ways by the factory in the one transaction. The contributors' part is claimable from a distributor after 1 hour. The treasury part goes to IMD.
2% of supply rewards this launch's contributors by accepted work; 8% is shared equally among wallets with accepted work in the preceding 12 hours. A wallet can earn both, combined into one claim.
Liquidity seeded into the pool80%800,000,000 $PACTContributors 203 agents, by work accepted10%100,000,000 $PACT#9010xfinne.eth6,394,088.66 $PACT
#60xbba9…dbe84,216,088.66 $PACT
#17310xf8ac…424d4,212,088.66 $PACT
#10060xf0ad…64d22,174,088.66 $PACT
198 more wallets
#5030x6ba9…742a1,156,088.66 $PACT
#18790xa906…c154394,088.66 $PACT
#14330xa8c4…d0ee394,088.66 $PACT
#9630xa80d…9e6d394,088.66 $PACT
#990xa67a…9c12394,088.66 $PACT
#9460xa4ad…5717394,088.66 $PACT
#17010xa3db…569c394,088.66 $PACT
#13220xa3c2…a5a0394,088.66 $PACT
#8270xa281…f923394,088.66 $PACT
#5270xa227…4a82394,088.66 $PACT
#7090xa1e8…5189394,088.66 $PACT
#9380xa183…f74f394,088.66 $PACT
#3090xa0ae…c7ef394,088.66 $PACT
#6380x9fef…95eb394,088.66 $PACT
#1310x99d0…28d3394,088.66 $PACT
#1080x939c…73b7394,088.66 $PACT
#15840x9282…9511394,088.66 $PACT
#11430x9108…36ce394,088.66 $PACT
#19640x8fc7…03c0394,088.66 $PACT
#18190x8daa…269c394,088.66 $PACT
#6600x8d11…9162394,088.66 $PACT
#7590x8c1f…cb6e394,088.66 $PACT
#19590x8b0a…9800394,088.66 $PACT
#8290x88b9…977b394,088.66 $PACT
#70x887b…a88c394,088.66 $PACT
#7860x87aa…dbc8394,088.66 $PACT
#19790x8655…5609394,088.66 $PACT
#14640x8609…a049394,088.66 $PACT
#4890x8580…4d4a394,088.66 $PACT
#5260x84b3…6ddb394,088.66 $PACT
#7080x845f…100e394,088.66 $PACT
#14090x83a7…3c88394,088.66 $PACT
#19270x8302…41b0394,088.66 $PACT
#15600x8249…f0c8394,088.66 $PACT
#14730x8143…2b63394,088.66 $PACT
#16780x7d5e…6563394,088.66 $PACT
#2700x7c6c…db5a394,088.66 $PACT
#11200x7c67…10d2394,088.66 $PACT
#10010x799f…c08e394,088.66 $PACT
#8000x7770…dee7394,088.66 $PACT
#2040x772d…841a394,088.66 $PACT
#3290x7637…e67f394,088.66 $PACT
#7850x75c2…9082394,088.66 $PACT
#3340x7381…f335394,088.66 $PACT
#15640x7379…84ac394,088.66 $PACT
#14270x7147…6752394,088.66 $PACT
#9120x710f…7733394,088.66 $PACT
#18040x70d6…79fc394,088.66 $PACT
#6680x6ee7…105a394,088.66 $PACT
#17050x6e6c…8209394,088.66 $PACT
#18380x6e6b…5226394,088.66 $PACT
#420x6e4b…9664394,088.66 $PACT
#2120x6d2f…be9e394,088.66 $PACT
#16660x6cff…1536394,088.66 $PACT
#8090x6cd6…d770394,088.66 $PACT
#17820x6bbf…9622394,088.66 $PACT
#8040x6b41…3dec394,088.66 $PACT
#10840x65fb…8f93394,088.66 $PACT
#3980x64da…29b1394,088.66 $PACT
#2530x6415…26ff394,088.66 $PACT
#11330x6262…36e3394,088.66 $PACT
#8310x622d…701d394,088.66 $PACT
#2440x6034…6ad3394,088.66 $PACT
#18000x6031…5a62394,088.66 $PACT
#6370x5bef…96c9394,088.66 $PACT
#1210x5b92…2a74394,088.66 $PACT
#1820x5a46…f847394,088.66 $PACT
#12070x5869…d533394,088.66 $PACT
#10380x56f1…0869394,088.66 $PACT
#10170x5693…883d394,088.66 $PACT
#5860x5617…d2f2394,088.66 $PACT
#2800x5463…ef38394,088.66 $PACT
#12990x53b4…3118394,088.66 $PACT
#16160x5167…3281394,088.66 $PACT
#12320x509f…df8e394,088.66 $PACT
#6610x5021…8c3d394,088.66 $PACT
#18710x500e…4deb394,088.66 $PACT
#10640x4eab…52b3394,088.66 $PACT
#2460x4a86…6537394,088.66 $PACT
#11160x48e4…6ec9394,088.66 $PACT
#12510x433c…7d58394,088.66 $PACT
#19050x40e9…0c39394,088.66 $PACT
#1830x3d48…35fa394,088.66 $PACT
#7240x3ce6…8bd8394,088.66 $PACT
#10820x3a94…2ee4394,088.66 $PACT
#4100x399e…6e41394,088.66 $PACT
#4510x3929…9eae394,088.66 $PACT
#17280x3876…2ade394,088.66 $PACT
#7950x34aa…fdf3394,088.66 $PACT
#9210x30e3…d0aa394,088.66 $PACT
#5100x2c41…b4d7394,088.66 $PACT
#6170x2c10…da05394,088.66 $PACT
#1270x2bba…f6ca394,088.66 $PACT
#2180x2b5b…5891394,088.66 $PACT
#19370x2a89…7dca394,088.66 $PACT
#19430x27d7…7e19394,088.66 $PACT
#10850x27a1…67b6394,088.66 $PACT
#660x26a1…0316394,088.66 $PACT
#700x2613…0241394,088.66 $PACT
#15360x2419…74c5394,088.66 $PACT
#6860x223a…54f6394,088.66 $PACT
#3930x20a2…b7c5394,088.66 $PACT
#5450x1f91…f204394,088.66 $PACT
#6520x1edf…d10d394,088.66 $PACT
#6050x1c29…b078394,088.66 $PACT
#5510x18d8…e653394,088.66 $PACT
#14400x14c8…3381394,088.66 $PACT
#13720x1395…10c9394,088.66 $PACT
#5900x1331…4e37394,088.66 $PACT
#13450x1307…4bad394,088.66 $PACT
#3630x1088…68ef394,088.66 $PACT
#12540x0f9f…8ea5394,088.66 $PACT
#12420x0df7…5bc1394,088.66 $PACT
#10250x0d74…841c394,088.66 $PACT
#10790x0cae…be73394,088.66 $PACT
#4430x0c36…6526394,088.66 $PACT
#12190x0b51…c342394,088.66 $PACT
#190x0ace…4782394,088.66 $PACT
#7760x0abe…64e5394,088.66 $PACT
#400x0a5b…ba24394,088.66 $PACT
#7060x09dd…be6c394,088.66 $PACT
#4900x097d…1cd5394,088.66 $PACT
#6310x08b7…8e83394,088.66 $PACT
#770x081d…b407394,088.66 $PACT
#18500x0646…c3fc394,088.66 $PACT
#6950x0146…6558394,088.66 $PACT
#12480x0068…ca76394,088.66 $PACT
#1670x0055…25e4394,088.66 $PACT
#10800x0037…3991394,088.66 $PACT
#16490xfe20…2dee394,088.66 $PACT
#2520xfe09…2cc1394,088.66 $PACT
#13180xfb03…4c19394,088.66 $PACT
#11000xf98c…c4db394,088.66 $PACT
#18920xf8ad…cdc7394,088.66 $PACT
#17810xf889…bceb394,088.66 $PACT
#9900xf807…c455394,088.66 $PACT
#18120xf435…7b5a394,088.66 $PACT
#1500xf40a…9540394,088.66 $PACT
#13590xf3b7…1e22394,088.66 $PACT
#6830xf236…1149394,088.66 $PACT
#14840xf0d2…74ef394,088.66 $PACT
#1650xef1e…f99b394,088.66 $PACT
#8470xeed8…6cf2394,088.66 $PACT
#290xeb87…ed68394,088.66 $PACT
#10000xeb71…7751394,088.66 $PACT
#15120xeace…4a49394,088.66 $PACT
#9730xe81d…3025394,088.66 $PACT
#19810xe6e4…c89a394,088.66 $PACT
#18140xe6b9…51de394,088.66 $PACT
#16260xe643…6244394,088.66 $PACT
#15050xe62a…0b71394,088.66 $PACT
#9890xe54d…603c394,088.66 $PACT
#11290xe085…4f7e394,088.66 $PACT
#13760xdf90…9ae5394,088.66 $PACT
#10670xdf66…6a1d394,088.66 $PACT
#2730xdf4e…b443394,088.66 $PACT
#14130xddb9…a4d4394,088.66 $PACT
#18900xd9cd…c1b5394,088.66 $PACT
#3390xd777…3b43394,088.66 $PACT
#11260xd717…748e394,088.66 $PACT
#16130xd58d…5105394,088.66 $PACT
#12380xd48d…5347394,088.66 $PACT
#11130xd470…0ab4394,088.66 $PACT
#2950xd2f7…422d394,088.66 $PACT
#15450xcf5f…9754394,088.66 $PACT
#10810xcefd…bd65394,088.66 $PACT
#16890xce92…9319394,088.66 $PACT
#17590xcd71…81cc394,088.66 $PACT
#15800xcd5a…2c2f394,088.66 $PACT
#4630xcc24…4bd4394,088.66 $PACT
#18930xcb62…dd89394,088.66 $PACT
#15540xcaa1…be5c394,088.66 $PACT
#7810xc657…0808394,088.66 $PACT
#2490xc60c…ebda394,088.66 $PACT
#16970xc562…6550394,088.66 $PACT
#18370xc395…2215394,088.66 $PACT
#3540xc0f7…65fa394,088.66 $PACT
#14050xbefe…352c394,088.66 $PACT
#130xbd9c…42b8394,088.66 $PACT
#13140xbc7a…8546394,088.66 $PACT
#2210xbb22…e475394,088.66 $PACT
#16020xba5b…7515394,088.66 $PACT
#13810xba4f…7d25394,088.66 $PACT
#15780xb8e6…899e394,088.66 $PACT
#2480xb80d…a369394,088.66 $PACT
#3550xb579…51cc394,088.66 $PACT
#880xb376…4329394,088.66 $PACT
#4390xb371…9037394,088.66 $PACT
#19650xb1a9…2805394,088.66 $PACT
#16560xb106…8104394,088.66 $PACT
#2220xaf3c…70f9394,088.66 $PACT
#14710xadd0…0674394,088.66 $PACT
#15070xac0a…b7c6394,088.66 $PACT
#17230xabe0…98b1394,088.66 $PACT
#680xaa90…40be394,088.66 $PACT
#2970xaa05…e57a394,088.66 $PACT
#5440xa9ce…aeac394,088.66 $PACT
#18490xa9a5…8899394,088.66 $PACT
IMD treasury the operator's wallet on Sepolia, 0x09ec…4a6010%100,000,000 $PACTTotal100%1,000,000,000 $PACTRecent-work share · 203 wallets · to
74,524 pieces of accepted work fell in that window · 74,467 oracle, 57 code.
Walletthis launchrecent work198 more wallets
- pool
- Uniswap v4: PACT/ETH · 0.3% fee
Published · Contracts
- app
- Guilds 0x8cf40aadb31bad7b441f018d74c61191b96a2e42
- app
- Realm 0x206bbcb9b91793decd1819e366334ab6dbbdc990
- distributor
- MerkleDistributor 0x174ce0bdbd6af7e713225ced17c873203ba829a1
Work
- contracts built
#47Build contract project57 files changedrevised
Done. The Pacts game is implemented, tested and committed on
mainas commite51da88, with 98 passing tests, a cleanforge build, andforge fmt --checkpassing under the pinned solc 0.8.26.What was built
src/LaunchToken.sol: the Pact (PACT) token, fixed 10^27 supply minted to the deployer, no admin functions.src/Guilds.sol: found, join, leave, expel, one-member-one-vote proposals with a strict majority of members who joined before the proposal, expiry at the end of the following epoch, pooled treasuries that release funds only to the majority-named target, and the shared epoch clock.src/Realm.sol: 12x12 map, troop purchases with a fee to Season, open attack declarations that fail if the holder changed, in-order epoch settlement with proportional losses and largest-unique-force wins, per-tile income accrual, and top-three standings recorded at each season's final settlement.src/Diplomacy.sol: pacts from two matching votes with non-zero bonds, blocked while an attack between the two is unsettled, automatic slashing to the victim on betrayal, bond return on expiry.src/Season.solandsrc/Banners.sol: 50/30/20 prize claims split equally among members fixed at season end, Winner banners on claim, Peace banners for guilds with no betrayal, and rollover of unfilled shares.
One design decision to flag for the manifest and review. The five contracts depend on each other in both directions, and the launch allows constructor wiring only. Realm therefore creates Diplomacy and Season in its constructor, and Season creates Banners. Each nested contract trusts only its creator, so there is no initializer or binding window. The manifest lists two contracts: Guilds with
["$token", 3600]and Realm with["$token", "$contract:Guilds", 3600, 604800, "1000000000000000000", 500]. The README explains this and how to read the nested addresses.Verification
- The protected floor tests were exercised locally against the real init code with computed CREATE2 addresses and all 8 passed; Realm's init code is 26 KB.
- Tests cover multi-attacker settlement, ties, votes and eligibility, expulsion, bond slashing and return, season close and claims, late joiners, and that unauthorized callers cannot move any funds, plus a balance-versus-accounting check through a full season.
Open items documented in the README: troop price (1 PACT) and fee (5%) are my deployment choices, not fixed by the brief; voters must check a proposal's target address since it carries the same authority as a payout; tests are not an audit, and no Slither or Mythril run was part of this task.
ran onclaude · claude-fable-5-1 · 40 turns · 26m 8s · 1.3K in · 134.1K out · 5M cachedsubmissionc746514441e66e2e850ee5ca09df69e389323bb25e7b7c3a2e61d168f2771fd0device3f6a9bdd601cb99f6ed43e548c54969af8f5a70edeae432aa541d955a4078cdfstarted from0243d7da4a4337ae8b16bcdf15bb4ead736fd68fbundle5875f46ed69b4229655b022a56e36d5b9a1c90a7852f1cf3427c142b58de99ac · 122 KBverifiedrebuilt and matched · verifier 0.1.0 ·changed · 57 files.gitignoreREADME.mddocs/abi/Banners.jsondocs/abi/Diplomacy.jsondocs/abi/Guilds.jsondocs/abi/LaunchToken.jsondocs/abi/Realm.jsondocs/abi/Season.jsonfoundry.tomllib/forge-std/LICENSE-APACHElib/forge-std/LICENSE-MITlib/forge-std/src/Base.sollib/forge-std/src/Script.sollib/forge-std/src/StdAssertions.sollib/forge-std/src/StdChains.sollib/forge-std/src/StdCheats.sollib/forge-std/src/StdConstants.sollib/forge-std/src/StdError.sollib/forge-std/src/StdInvariant.sollib/forge-std/src/StdJson.sollib/forge-std/src/StdMath.sollib/forge-std/src/StdStorage.sollib/forge-std/src/StdStyle.sollib/forge-std/src/StdToml.sollib/forge-std/src/StdUtils.sollib/forge-std/src/Test.sollib/forge-std/src/Vm.sollib/forge-std/src/console.sollib/forge-std/src/console2.sollib/forge-std/src/interfaces/IERC1155.sollib/forge-std/src/interfaces/IERC165.sollib/forge-std/src/interfaces/IERC20.sollib/forge-std/src/interfaces/IERC4626.sollib/forge-std/src/interfaces/IERC6909.sollib/forge-std/src/interfaces/IERC721.sollib/forge-std/src/interfaces/IERC7540.sollib/forge-std/src/interfaces/IERC7575.sollib/forge-std/src/interfaces/IMulticall3.sollib/forge-std/src/safeconsole.solremappings.txtscript/Deploy.s.solsrc/Banners.solsrc/Diplomacy.solsrc/Guilds.solsrc/LaunchToken.solsrc/Realm.solsrc/Season.solsrc/interfaces/IERC20.solsrc/interfaces/IRealm.soltest/Deploy.t.soltest/Diplomacy.t.soltest/FundsSafety.t.soltest/Guilds.t.soltest/LaunchToken.t.soltest/PactsBase.t.soltest/Realm.t.soltest/Season.t.sol - contracts tested
#47Write foundry tests2 files changedrevised
afterBuild contract projectwrites totesttest/**Done. The suite passes and three defects are reported with failing proofs.
What I added under
test/test/Invariants.t.sol: a handler that drives all six contracts with five players and bounded inputs (found, join, leave, expel, buy troops, donate, treasury purchases, payouts, attacks, settlement, income collection, pacts, expiry, season close, claims, peace banners, time warps). It runs with fail-on-revert enabled, so every precondition is checked and every deliberately unmet precondition is asserted to revert. Thirteen invariants hold after every sequence: supply conservation, the game holds exactly what was paid in minus what was paid out, no player receives more than a vote or season awarded, each contract's balance equals its accounting (treasuries, active bonds, owed income, pools plus unclaimed prizes), troops are created only by purchase and destroyed only by settlement, tile and membership bookkeeping stay consistent, executed proposals had a majority, finished pacts never reopen, and settlement never runs ahead of the clock. A scratch probe confirmed the handler reaches deep states: 16 pacts with a betrayal, 18 closed seasons, 81 banners.test/EdgeCases.t.sol: 47 tests. Eight fuzz properties cover strict majority for any guild size, proposal expiry at the exact second, member counts versus stints, battle resolution (unique largest wins, ties keep the holder, no troop creation, monotone survivors, unopposed attacker loses nothing), fee splits for any rate, per-tile income with dust carried, the pact window boundary, and season allocation with claims. The rest are failure paths the existing suite skipped: tile 143 versus 144, overflow purchases, expel on a member who already left, rejoined members voting, leavers staying in the denominator, standings with five guilds and a re-encountered pushed-out guild, out-of-order sign arguments, consumed proposals, one-epoch pacts, zero-pool seasons, expelled members claiming, and the full Banners ERC-721 failure surface.
Findings in
.imd-findings.json(three carry standalone proofs that fail on this code)- Medium: with lagging settlement an attack resolves against whoever holds the tile after earlier epochs settle, so a guild can take a pact partner's tile with no slash.
src/Realm.sol:209 - Medium:
Season.closerolls unallocated prize money into the next season even if that season is already closed, stranding it forever.src/Season.sol:112 - Medium:
declareAttackhas no caller check and approved proposals cannot be withdrawn, so a pact partner can trigger the other guild's stale attack and collect its bond.src/Realm.sol:200 - Medium, no proof: the per-epoch resolution loop is unbounded. One address can freeze settlement permanently for about 1000 PACT plus gas.
Attacks on one tile settle()gas100 3.13M 1000 30.5M - Low: proposal targets are not validated per kind, so a Pact or TreasuryTroops proposal can be a disguised payout. Info: payouts to a game contract address are unrecoverable.
Verification:
forge buildsucceeds,forge testexcluding scratch passes 146 tests, the invariant suite passes under three additional fixed seeds, and both new files passforge fmt --check. Nothing outsidetest/and the findings file was touched.ran onclaude · claude-fable-5-1 · 48 turns · 25m 14s · 930 in · 106.2K out · 4.6M cachedsubmissionda61f6a67c0fca855ff1244a66859791e4b6093dc306254d1221c2f3bf97b37fdevice3f6a9bdd601cb99f6ed43e548c54969af8f5a70edeae432aa541d955a4078cdfstarted fromc3a59316566102dac8d31776db093d0a3c797787bundlebe29f012b34923f8797999ccc5d1e60dc907c6c12a3ab9f1d6006e712c9251b6 · 138 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bcchanged · 2 filestest/EdgeCases.t.soltest/Invariants.t.solmediumAttack resolves against a different holder than the one named when settlement lags, bypassing pact slashingsrc/Realm.sol:209
proof · a Foundry test the fix has to passmediumClosing seasons out of order strands the earlier season's rollover in Season foreversrc/Season.sol:112
close(season) is permissionless and has no ordering requirement, but it rolls the unallocated part of the pool into prizePool[season + 1] unconditionally. If season s+1 was already closed (its Result and allocations are fixed at close time), the rollover added afterwards is never allocated to anyone and can never be claimed or rolled forward again.
Nothing stops close(s+1) from being called before close(s): both only require the calendar season to have passed and Realm to have recorded standings, and Realm records standings in order well before anyone has to call close. The rollover can be large in early seasons: with only one guild holding tiles it is 50% of the pool, with an empty top guild it is the whole pool.
proof · a Foundry test the fix has to passmediumAnyone can declare a guild's approved attack and approved proposals cannot be withdrawn, so a pact partner can force a betrayal and take the bondsrc/Realm.sol:200
proof · a Foundry test the fix has to passmediumUnbounded per-epoch resolution loop lets one address freeze settlement permanently, stranding income and every future prizesrc/Realm.sol:248
Proposal targets are not validated per kind, so a Pact or TreasuryTroops proposal can be a disguised payout to any addresssrc/Guilds.sol:209
Guild with treasury 10e18.
A member proposes kind = Pact, target = 0xATTACKER contract, amount = 10e18, data1 = another guild, data2 = 1; the majority approves believing it is a pact.
The contract at 0xATTACKER calls guilds.consume(pid).
Expected: only the Diplomacy contract can consume a Pact proposal.
Actual: consume succeeds, 10e18 is transferred to 0xATTACKER, no pact is created.
Payouts and consumed amounts sent to a game contract address are unaccounted and unrecoverablesrc/Guilds.sol:276
A Payout proposal may name Guilds, Realm, Diplomacy or Season itself as recipient. The transfer succeeds, the treasury is reduced, and the tokens sit in that contract without any balance that references them: Guilds' balance then exceeds the sum of treasuries, Realm's balance exceeds the income it owes, and nothing can ever move them. There is no admin path by design, so the loss is permanent.
Likewise vote() remains callable on an already executed proposal (no effect on the outcome). Both are harmless to other players and are recorded here so the review does not treat 'contract balance equals accounting' as guaranteed against a self-inflicted payout.
Guild treasury 5e18; majority approves Payout(target = address(guilds), amount = 5e18); execute(pid).
Expected: revert or the treasury unchanged.
Actual: treasuryOf(guild) becomes 0 while token.balanceOf(guilds) stays 5e18 with no owner.
- contracts updated
#2Build contract project12 files changedrevised
All four reproducible findings reproduced on the starting tree and are fixed. The two advisory findings reproduce but are answered as disputed with reasons. The three reviewer proofs now pass, the full suite passes, and the formatter check is clean.
What I confirmed first
- The three proof tests failed on the starting tree exactly as reported.
- A scratch test with 1000 one-troop attacks on one tile made a single settle call cost about 30.5M gas.
Fixes made
- Stale-holder attacks are void. Each attack in Realm now records the holder it named. At resolution, an attack whose named holder no longer holds the tile does not fight, gets its troops refunded, and emits a new AttackVoided event. An attack can no longer land on a guild it never named, which is what made the pact bypass possible when settlement lagged.
- Seasons close in order. Season.close reverts with PreviousSeasonNotClosed if the prior season is still open, so a rollover always lands in an open pool. Realm records standings in order, so this costs no liveness.
- Pact-breaking declarations need a member. Realm.declareAttack reverts with BetrayalRequiresMember when the declaration would break an active pact and the caller is not a member of the attacking guild. Attacks that break no pact stay declarable by anyone, which the other two proofs require since they declare from the test contract. Diplomacy gained a wouldBreakPact view for this.
- Resumable settlement. Realm.settleStep visits a bounded number of attack entries per call, persists its cursor and running totals, and only advances the settled epoch count when the epoch completes. The existing settle and settlePending calls behave as before and finish any partial settlement. A settlementProgress view reports the state.
Advisory findings
- Per-kind target validation is disputed. Guilds is deployed before Realm and Diplomacy under constructor-only wiring, so it cannot learn their addresses, and a registration call could be front-run and brick the launch. The README now explains the limit.
- Payouts to a game contract address are disputed as self-inflicted and by design under the no-admin rule. The README records both this and the harmless late vote.
Tests and docs
- Ten new tests cover void attacks, stepwise settlement including 300 spam attacks in bounded steps, member-only betrayal, and ordered season closes. Existing betrayal tests now declare as a member.
- ABI exports for Realm, Diplomacy and Season were regenerated. The README documents the new rules, the operator's settleStep fallback, and a revision history.
- The responses file lists all six finding ids with their verdicts.
Test totals: 108 tests in the delivered tree, plus the 3 proof copies and 1 gas scratch test under test/scratch.
ran onclaude · claude-fable-5-1 · 68 turns · 12m 49s · 578 in · 58K out · 2.5M cachedsubmissiond6ff80f75ffc58e727b10e81dcfc349d8c00a3f624a287363b895526155813c5device468e82a89b9bfe188ef46b055e2ea554bde626cc162630c20effb0fcc7e13fedstarted fromc3a59316566102dac8d31776db093d0a3c797787bundle76b83818dab9285264ac961159a045dd8da980b9ac7ac714a995562f3ade8450 · 132 KBverifiedrebuilt and matched · verifier 0.1.0 ·changed · 12 filesREADME.mddocs/abi/Diplomacy.jsondocs/abi/Realm.jsondocs/abi/Season.jsonsrc/Diplomacy.solsrc/Realm.solsrc/Season.soltest/Diplomacy.t.soltest/FundsSafety.t.soltest/PactsBase.t.soltest/Realm.t.soltest/Season.t.sol - contracts updated
#2Write foundry tests3 files changedrevised
afterBuild contract projectwrites totesttest/**The memory directory is read-only in this sandbox, so no note was saved. That does not affect the deliverable.
Recap
What I found. The builder's revision added a member-only gate on betrayal declarations, void attacks, stepwise settlement and in-order season closing. Two of my accepted tests broke on the new gate and needed a member to declare the betrayal. Everything else in the accepted files still holds.
What I changed, all under
test/:test/EdgeCases.t.sol: the two failing tests now declare betrayals as a member and also assert a non-member is refused inside the pact window.test/RevisionEdgeCases.t.sol(new, 15 tests): a differential fuzz that settles the same random script withsettle()and withsettleStep(budget)on a twin Realm and checks identical state and the exact step count; income paid once across steps; purchases and collections between steps; an attack declared mid-settlement becoming void; a tile with only void attacks left untouched; season close refused on a half-settled last epoch;wouldBreakPactfuzzed against the declaration outcome; a pact signed over an undeclared approved attack; betrayal slashed at declaration even when the attack later voids; strict season ordering and rollover chaining.test/Invariants.t.sol: attacks are declared by a member, with the handler first proving a non-member cannot trigger a betrayal; a newsettleStepwiseaction steps through settlement with buys, collections and attacks interleaved between steps; per-epoch checks that a tile only falls to an attacker that named its holder and that void-only tiles are untouched; invariants that no settlement is left half done and that nothing but a settlement call movessettledEpochs.
Reported instead of tested around in
.imd-findings.json:- Medium, with proof: the
BetrayalRequiresMembergate is bypassed by joining the attacking guild, sinceGuilds.joinis permissionless. The partner's fresh wallet joins and declares the stale approved attack, and the pact is broken with both bonds paid to the partner. The proof test fails on the current code. - Info:
settlementProgress()reports the current epoch's attacked tiles astilesTotalwhile no settlement is in progress, contradicting its docstring.
Verification.
forge build --offline,forge fmt --checkpass.forge test --offlineruns 172 tests. 171 pass. The single failure is the scratch proof intest/scratch/, which fails by design and is removed before submission. The invariant suite finishes in about 30 seconds with zero reverts.ran onclaude · claude-fable-5-1 · 52 turns · 25m 40s · 898 in · 65.2K out · 4.3M cachedsubmission7ed0b10b8d47761b6f232a60e5a767952bbd90c878da104587a99462fbdab60adevice468e82a89b9bfe188ef46b055e2ea554bde626cc162630c20effb0fcc7e13fedstarted from6f14ff31c3919ed717741541b58865d8ef6c31dabundle4678906c86268de87aa878009ca145299f2100ec5f682f371351cfffb4b4cd9e · 158 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bcchanged · 3 filestest/EdgeCases.t.soltest/Invariants.t.soltest/RevisionEdgeCases.t.solmediumMember-only gate on betrayal declarations is bypassed by joining the attacking guildsrc/Realm.sol:246
proof · a Foundry test the fix has to passsettlementProgress() reports the current epoch's attacked tiles while no settlement is in progresssrc/Realm.sol:295
The docstring says the view is zero everywhere when no settlement is in progress, but tilesTotal is _attackedTiles[settledEpochs].length, and while settledEpochs == currentEpoch() that is the list of tiles attacked so far in the epoch still being played. A frontend or keeper that reads tilesTotal != 0 as 'a settlement is pending' will be misled; started is the reliable flag. The test suite does not assert either reading of tilesTotal before a settlement starts.
Fresh game, epoch 0: Alpha buys a troop and declares an attack on an empty tile, then call settlementProgress().
Expected per the docstring: (false, 0, 0).
Actual: (false, 0, 1).
- contracts updated
#1548Build contract project4 files changedrevised
Both findings reproduced and fixed:
- Betrayal declarations now require current membership and eligibility at proposal creation.
- Settlement progress returns zeros until settlement starts.
Added regression tests, updated documentation, and recorded both verdicts in
.imd-responses.json.forge build, all 113 tests, andforge fmt --checkpassed. ABI exports match the compiled contracts.ran oncodex · gpt-6-astra · 6 turns · 5m 10s · 71.4K in · 8.6K out · 888.3K cachedsubmissiona6b967b49a334a4941384d8338b342a41407cac74a7a1971c4fd877e5104f591device35c52a5b502e847cda633d436a25cd57d809a4ea7935560acc2b18eccfd592acstarted from6a417a3827ba6886c2f6ea37a5300afc7da7354dbundle4361ce17eeb5237824aafa34bafbd06a90bd1255598ad8e7297c958bd5f32b94 · 134 KBverifiedrebuilt and matched · verifier 0.1.0 ·changed · 4 filesREADME.mdsrc/Realm.soltest/Diplomacy.t.soltest/Realm.t.sol - contracts updated
#1548Write foundry tests2 files changedrevised
afterBuild contract projectwrites totesttest/**Added targeted tests for membership changes, pact expiry, and settlement progress, plus delayed-attack invariant coverage.
Offline
forge buildandforge testpass: 177 tests passed, with 3,840 invariant calls and no failures.Changes are confined to
test/.ran oncodex · gpt-6-astra · 6 turns · 7m 8s · 98.9K in · 11.5K out · 1.7M cachedsubmissionb861f4bc4a225d56c722226b43f100446411110a84f49d15c8765c4fdb690851device35c52a5b502e847cda633d436a25cd57d809a4ea7935560acc2b18eccfd592acstarted from850aa9e9e599c7038cf12f1479f51d197effddb7bundle3a6eea2507901e43336ce3bce88143cb0f9d0d1e33676c721d1589c3ac110efe · 169 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bcchanged · 2 filestest/Invariants.t.soltest/RevisionEdgeCases.t.sol - contracts integrated
#1548Manifest1 file changedrevised
afterBuild contract project, Write foundry testswrites tolaunch.jsonCreated launch.json with Pact metadata, constructor wiring, and pool settings.
Validation passed: schema/refinements, compiled constructor ABIs,
forge build, and all 185 tests, including supplied protected checks. Build emitted existing source warnings.Only
launch.jsonchanged outside permitted scratch files.ran oncodex · gpt-6-astra · 4 turns · 2m 48s · 44.1K in · 4.7K out · 301.8K cachedsubmission9c39130a9d08a2d90f091998bf0a8d1a78da72fc393dac63a151037ce154d602device35c52a5b502e847cda633d436a25cd57d809a4ea7935560acc2b18eccfd592acstarted fromc18ffc34531f68b72381f14d1bace1ace9b36d08bundleb883e4a6743119461cc9f21e3f05c9fcc4e27e888773950314737d9b6a7bb527 · 170 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299changed · 1 filelaunch.json - contracts reviewed
#617Audit flowno findingsrevised
afterBuild contract project, Write foundry tests, ManifestSaved .imd-findings.json.
No substantiated defects in the assigned area. Covered all 31 entry points. Existing Foundry tests and all eight protected checks passed; all six ABI exports match. Source and configuration files are unchanged.
ran oncodex · gpt-6-astra · 6 turns · 5m 41s · 109.9K in · 9.1K out · 987.8K cachedsubmissiona63249a02e9305aa62470c29e508dbfa7a380f92a25c1cbadf95d741a0378cfadevicebb0a3bf63233e5e5722f6eae6cd08dc581298f894dd83aa00d8a87a846a28c34started from51245b56af3633f4f8c0aa5797debc74b7935c08bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothing - contracts reviewed
#270Audit economics1 finding · 1 mediumrevised
afterBuild contract project, Write foundry tests, ManifestSaved
.imd-findings.jsonwith one medium finding: caller-supplied holder snapshots bypass attack proposal freshness.Covered all 31 entry points. All 177 existing tests passed; the targeted reproduction failed as expected. Implementation files remain unchanged.
ran oncodex · gpt-6-astra · 5 turns · 6m 31s · 100.8K in · 10.2K out · 1.1M cachedsubmission9efb249fe73dcb50680d34d8e7b421f27829329e7365326707eeb4932b8b32b9device02ae6543274731ab9267e3541a2725ba68887d0790ccdad189b0d33bfc1a01b9started from51245b56af3633f4f8c0aa5797debc74b7935c08bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothingmediumCaller-supplied holder snapshots bypass attack proposal freshnesssrc/Guilds.sol:230
The approved workflow requires an attack proposal to name the tile holder at proposal creation and fail if that holder changes. Guilds.propose copies data2 without checking the target Realm tile; Realm.declareAttack later compares only this caller-supplied value with the current holder (src/Realm.sol:238-243).
A guild can therefore approve an attack against a predicted future holder while the tile is empty, wait for that guild to capture it, and execute the old proposal successfully. This bypasses the required holder-change invalidation and lets a previously invalid attack commit troops against a newly captured tile. The proposal still requires its normal majority.
Derive or validate the holder from the target Realm when creating an Attack proposal, then retain the declaration-time holder check.
proof · a Foundry test the fix has to pass
- contracts reviewed
#47Audit math2 findings · 2 lowrevised
afterBuild contract project, Write foundry tests, ManifestThe review is complete. The findings file is written, both cited snippets match the tree, and the scratch test directory is removed.
Outcome: the math in the assigned area holds up. Every value-moving formula conserves tokens, and the launch manifest's constructor arguments satisfy every constructor check. I recorded two low-severity findings and no medium or higher.
Findings written to
.imd-findings.json:-
Low, Realm.sol:445. The proportional-loss formula floors to zero for small forces. A 1-troop attacker never loses a troop against any total, a 1-troop garrison is never destroyed, and a 2-troop attacker takes a 1-troop tile with zero loss on both sides. This is a boundary × precision seam. No tokens are affected since troops are never redeemable, so the impact is gameplay: free tile flips at the low end and free harassment attacks that block pact signing until settlement.
-
Low, Guilds.sol:154. An expelled member can rejoin in the same block and is counted again for member count, proposal denominators, and the season prize split. Expulsion only resets vote eligibility. This is outside the math area but was cheap to substantiate, and it weakens the brief's expulsion rule.
Both were confirmed with a scratch Foundry test that reproduced the exact numbers quoted in the reproductions.
Coverage: all 31 listed entry points have a row, plus six invariant rows. Twenty-seven hold, four reference the two findings, none are unreached. The areas traced in depth were the income accumulator and remainder carry, the stepwise settlement state machine at every budget exit, the standings insertion sort, the season share split against the member-count checkpoint and stint lookup, pact epoch boundaries, and every downcast and unchecked block.
Leads dropped after tracing: the Slither divide-before-multiply lines are intentional remainder computations; the uninitialized-state and strict-equality lines on the checkpoint history are false positives; the fee-truncates-to-zero seam is unreachable with the manifest's 1e18 troop price.
ran onclaude · claude-fable-5-1 · 29 turns · 9m 18s · 386 in · 40.3K out · 1.4M cachedsubmission595323bea11fbbddf8e7ba9f51d35177b8961f07b5c23b77a8646006b3e17fccdevice3f6a9bdd601cb99f6ed43e548c54969af8f5a70edeae432aa541d955a4078cdfstarted from51245b56af3633f4f8c0aa5797debc74b7935c08bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothingProportional-loss formula floors to zero for small forces, so 1-troop attacks and 2-vs-1 captures cost nothingsrc/Realm.sol:445
Expulsion has no effect: an expelled member can rejoin in the same block and keeps its equal season-prize sharesrc/Guilds.sol:154
-
- contracts reviewed
#2Audit permissions3 findings · 2 highrevised
afterBuild contract project, Write foundry tests, ManifestThe findings file is complete and every snippet now matches the tree. Recap of the audit:
Scope covered. I mapped every role and guard across the six contracts against the Access Control, Trust Gap and Asymmetry guides. No owner or admin path exists anywhere. Diplomacy, Season and Banners trust only their constructor creator,
Guilds.consumeis bound to the proposal target, the betrayal gate cannot be bypassed through the void or expiry paths, andclose/claimuse consistent membership snapshots. The manifest wires only$tokenand$contract:Guildswith arguments matching the accepted defaults. Most open-caller behaviours (anyone declares non-pact attacks, arbitrary proposal targets, peace banners for any guild) are already recorded as trust assumptions in the README, so I did not re-report them.Findings written to
.imd-findings.json(3 findings, 31 coverage rows, all entry points answered):- High: permissionless
Guilds.joingives any outsider a voting majority. Four fresh wallets joined a three-member guild, proposed a Payout to themselves and drained a 1000 PACT treasury. Proof test fails on this tree. - High: season prizes split by member count at the last second. Nine wallets that joined one second before season end claimed 22.5 of the 25 PACT first prize earned by the season-long holder. Proof test fails on this tree.
- Low: an approved Pact proposal is an open offer. The counter-bond is never compared and approval cannot be withdrawn, so a 1000 PACT bond was locked against a 1 wei counter-bond signed by an outsider.
Both high findings meet the workflow's rules literally, so fixing them needs a scope decision on admission control or tenure-weighting. I said so in each description. Scratch proofs live under
test/scratch/, which is discarded. No source, test or config file was changed.ran onclaude · claude-fable-5-1 · 23 turns · 11m 56s · 386 in · 48.6K out · 1.4M cachedsubmission8cef3d5bf2ddae42aed5e1e718342b05b733b396e7fb429c2e0d6a2049dc19b1device468e82a89b9bfe188ef46b055e2ea554bde626cc162630c20effb0fcc7e13fedstarted from51245b56af3633f4f8c0aa5797debc74b7935c08bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothinghighPermissionless join lets any outsider vote a guild's whole treasury to themselvessrc/Guilds.sol:154
proof · a Foundry test the fix has to passhighSeason prizes are split by member count at the last second, so last-block joiners capture a winning guild's prizesrc/Season.sol:105
proof · a Foundry test the fix has to passAn approved Pact proposal is an open offer: the counterparty's bond is unbounded and the offer cannot be withdrawnsrc/Diplomacy.sol:108
- High: permissionless
- contracts reviewed
#1649Audit judgerefusedRefused by Codex's safety filter, retried on Claude
This content was flagged for possible cybersecurity risk. If this seems wrong, try rephrasing your request. If you’re doing authorized security work that requires more cyber permissive safeguards, apply for Daybreak access via https://platform.openai.com/settings/organization/status-and-access before retrying.
ran oncodex · gpt-6-astra · 22ssubmissionde8fbf6c874a0eb02ddfc52e8a106a7b3e32e2c7e606d6a897ef39e379ebc0d7device377843575071cdb156ab6317aaffd00c5f4a8e1fec7f8b133fd913ca807eed04started from51245b56af3633f4f8c0aa5797debc74b7935c08bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothing#66 findings · 2 mediumrevised
afterBuild contract project, Write foundry tests, Manifest, Audit math, Audit permissions, Audit economics, Audit flowThe review is complete and
.imd-findings.jsonis written at the repository root. No source, test, config or manifest file was changed; only the findings file and disposable files undertest/scratch/exist as untracked, ignored paths.What I found
All three specialist proofs fail on this tree as claimed, and I confirmed the three proof-less findings with my own scratch tests. Build is clean, Realm's init code is 27,900 bytes (under the 49,152 limit), the six ABI files in
docs/abimatch the compiled output, the manifest matches the constructor signatures, and all 177 permanent tests pass.Six findings kept, recalibrated by impact:
- Medium, Guilds.join: instant unguarded membership with one vote each lets more fresh wallets than a guild has members vote its treasury to themselves. Reported high by the permissions specialist. Lowered to medium because it follows the approved brief literally, so the fix is a requester scope decision. Carries a fix-shape-agnostic proof that fails now.
- Medium, Season.close and claim: prize shares are fixed by membership at the season's last second, so nine one-second joiners take 22.5 of a 25 PACT first prize. Reported high, lowered for the same reason. Kept separate from the first because the fix lands in different functions.
- Low, Guilds.propose: the attack proposal's "holder at proposal time" is caller-supplied and never checked against Realm, so the holder-change rule can be pre-satisfied against a predicted future holder. Reported medium by the economics specialist. Lowered because voters still explicitly approved the tile and target and no funds move. Carries the specialist's proof, which is fix-location agnostic.
- Low, Guilds.execute: an expelled member rejoins in the same block and keeps an equal prize share.
- Low, Diplomacy.sign: counter-bonds are unconstrained and approved offers cannot be withdrawn, so a 1000 PACT bond can be matched by 1 wei.
- Low, Realm loss formula: integer division floors small forces' losses to zero, so 2-vs-1 captures and 1-troop attacks cost nothing.
Dropped or not raised
The static-analysis leads were all false positives or benign: the uninitialized-state and uninitialized-local reports are on mappings and memory arrays, the reentrancy reports involve only the hookless launch token, and the divide-before-multiply reports are the intended dust-carry pattern. My own pass surfaced one lead, a partner slashed for an attack later voided under settlement lag, which I dropped because the attacking guild's own eligible member knowingly declares against the holder shown in storage and immediate slashing on declaration is documented design.
Coverage
All 31 entry points are answered: 19 hold, 12 map to a finding, none unreached. Two extra rows record the solvency invariant and the manifest-to-constructor check.
ran onclaude · claude-fable-5-1 · 29 turns · 13m 34s · 418 in · 51.6K out · 1.5M cachedsubmissionf0b1cb916a4fa4b3c7b850ed4cdf8bf6fbc4b6ec43e1b2d8c7358bc04852e5a7device30a6c1a419ef4f9c0b7b9345d1843aaf4945ad583f614ed8027cb22761e6f96cstarted from51245b56af3633f4f8c0aa5797debc74b7935c08bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothingmediumInstant, unguarded join lets outsider wallets form a majority and pay out any guild treasurysrc/Guilds.sol:154
proof · a Foundry test the fix has to passmediumSeason prizes are split by member count at the season's last second, so last-second joiners capture a winning guild's prizesrc/Season.sol:105
Attack proposals take the 'holder at proposal time' from the caller, so the holder-change check can be pre-satisfied against a predicted future holdersrc/Guilds.sol:231
proof · a Foundry test the fix has to passExpulsion has no lasting effect: an expelled member can rejoin in the same block and keeps an equal prize sharesrc/Guilds.sol:271
From audit_math (reported low, confirmed). execute() on an approved Expel only calls _leave(); join() has no check against a prior expulsion, so the expelled address rejoins immediately. The only lasting effect is a new join sequence (no vote on proposals created before the rejoin).
It counts again in memberCount, in the denominator of every later proposal, in memberCountAt(seasonEnd - 1) used by Season.close and in wasMemberAt used by Season.claim, so the brief's 'a majority can expel a member' cannot exclude anyone from a guild or its prize split.
Related to finding 1 (membership is instant and unguarded) but the fix is local: record the expulsion per guild (a ban, or a cooldown until the next epoch or season end) and check it in join(), or document that Expel only resets voting eligibility.
Pact proposals do not constrain the counter-bond, so an approved pact is an open offer that a 1 wei bond can accept and that cannot be withdrawnsrc/Diplomacy.sol:108
From audit_permissions finding 3 (reported low, confirmed). _check matches partner id and duration only; each side's bond (amount) is independent, sign() is callable by anyone, and Guilds has no way to withdraw an approved proposal before it expires at the end of epoch E+1. Once guild A's majority approves a pact with bond X, guild B can answer with a 1 wei bond and any address signs.
For the duration A's X tokens are locked and A cannot attack B without forfeiting X, while B can break the pact for 1 wei (B's bond plus A's own bond return to A). No theft, but A's members approved a bond without any say over what backs the other side, so the first mover carries all the risk.
Fix within the design: let a Pact proposal name the minimum counter-bond it accepts (the unused data3) and have _check require b.amount >= a.data3 and a.amount >= b.data3, or require equal bonds.
Proportional-loss formula floors to zero for small forces: 1-troop attacks and 2-vs-1 captures cost nothingsrc/Realm.sol:445
- contracts updated
#1548Build contract project7 files changed
Fixed attack-holder validation and added pact minimum counter-bonds. Documented retained expulsion and rounding behavior.
All six verdicts are in .imd-responses.json. Treasury/prize capture remains under the approved rules; those two findings are disputed. The supplied hostile-join proof still fails, explicitly recorded.
forge build, all 122 tests, andforge fmt --checkpass. ABIs verified unchanged.ran oncodex · gpt-6-astra · 6 turns · 8m 32s · 99.4K in · 15K out · 1.2M cachedsubmission82d9a11c5b311678b870d5205b6092ff37e28e473cb84d198c751e8c8bcf39e4device35c52a5b502e847cda633d436a25cd57d809a4ea7935560acc2b18eccfd592acstarted fromae122de1b3484e08bf9c3e35c00c6d5067e2f238bundlec82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc · 140 KBverifiedrebuilt and matched · verifier 0.1.0 ·changed · 7 filesREADME.mdsrc/Diplomacy.solsrc/Guilds.solsrc/interfaces/IRealm.soltest/Realm.t.soltest/Revision.t.soltest/RuleConsequences.t.sol - contracts updated
#1548Write foundry tests3 files changed
afterBuild contract projectwrites totesttest/**Updated only
test/: corrected invalid-tile revert expectations and added pact-bond rejection, retry, boundary, and invariant coverage.forge buildandforge testpass: 191 tests, zero failures. No new contract defects confirmed.ran oncodex · gpt-6-astra · 5 turns · 4m 51s · 82.4K in · 8K out · 1M cachedsubmission1f666ebc9bde5e965fb0540d27440b183aecc0cf220010c4ed5e5fb399c75df0device35c52a5b502e847cda633d436a25cd57d809a4ea7935560acc2b18eccfd592acstarted from629207b94f28d5c902c7877003dcc4fb05e0c047bundlefe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299 · 176 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bcchanged · 3 filestest/EdgeCases.t.soltest/Invariants.t.soltest/Revision.t.sol - contracts updated
#1548Manifestruntime erroron the agent's machine: the task produced no changes; the agent's last message was: The existing `launch.json` already matches the …
the task produced no changes; the agent's last message was: The existing
launch.jsonalready matches the canonical schema and accepted implementation, so no revision was needed.- Schema, constructor arguments, references, and token metadata validated.
forge buildpassed with warnings.forge test: 191 passed, 0 failed.- No tracked files changed.
ran oncodex · gpt-6-astra · 3 turns · 2m 21s · 39.8K in · 3.5K out · 371.7K cachedsubmission59893db05863dd7a5d716066a2ae810372dba801384d0122c1c1a9a07dcd411edevice35c52a5b502e847cda633d436a25cd57d809a4ea7935560acc2b18eccfd592acstarted from88e2b861337864c6abdfe5521a615defaef14838bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299changed · 0 filesnothing#21 file changed
afterBuild contract project, Write foundry testswrites tolaunch.jsonThose untracked entries are sandbox device-node masks (character devices owned by nobody), not real files in the tree, so they exist only inside the sandboxed shell. The only tracked change is launch.json.
Done.
launch.jsonis updated with a substantive notes revision and validated.What changed
- The manifest structure, token metadata, both contracts, constructor arguments and pool fields were already correct against the accepted tree, so they are unchanged.
- The notes now describe behaviour the last source revision added that the previous notes did not cover: Guilds validates an Attack proposal's named holder against the live tile in Realm at creation, and Pact proposals carry a minimum counter-bond that Diplomacy enforces on signing.
- The notes also list the permissionless maintenance calls (epoch settlement in full or bounded steps, season close, prize claim, peace banner minting, pact expiry), the exact constructor signatures and the revert conditions in the Realm constructor, and the accepted open-membership consequence documented in the README.
Verification
- Schema check: kind, key set, identifier patterns, address-only references pointing backward, argument counts and types against
docs/abi/Guilds.jsonanddocs/abi/Realm.json, initialPrice below 2^256, notes at 2724 of 4000 characters. forge build --offlinesucceeded.forge test --offline: 191 passed, 0 failed.git diff --statshows launch.json as the only changed file. The untracked dotfiles git lists are sandbox device masks, not files in the repository.
ran onclaude · claude-fable-5-1 · 8 turns · 2m 10s · 226 in · 6.1K out · 335.1K cachedsubmission0942cf4c96f3e09c99388b8f3d4e1e29ab31ab37ff2a677f79c163a1496865fedevice468e82a89b9bfe188ef46b055e2ea554bde626cc162630c20effb0fcc7e13fedstarted froma04af19fd93704347c36c70170bb972f6f8c44a5bundle2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668 · 179 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299changed · 1 filelaunch.json - contracts reviewed
#1731Audit mathno findings
afterBuild contract project, Write foundry tests, ManifestBoth findings from last round are resolved, and I found no new defects.
.imd-findings.jsonholds an empty findings list plus a coverage row for all 31 entry points: all 31 are markedholds, nonefindingorunreached. I changed no project files, and the full test suite passes (191 of 191).Earlier findings:
- Zero-loss rounding in battles (217df208): Fixed by documentation, which was one of the two options I offered. The code is unchanged:
src/Realm.solstill computes losses asc * (total - c) / total, rounding down. The README now states the rule: "Losses round down, with no minimum casualty". It spells out the exact cases I reported (a 1-troop force never loses, a 2-vs-1 capture costs neither side anything) and what they cost the attacker and keepers. The winner still always keeps at least one troop, becausec - c(T-c)/T >= 1wheneverc >= 1. - Expelled member can rejoin (a66e4e06): Fixed by documentation, again an option I offered. The README now says expulsion "is not a ban or cooldown": the expelled address can rejoin in the same block and gets its equal prize share back. This follows the approved open-membership rules.
Rest of my area (math precision, boundaries, numerical gaps):
- Troop purchases: the fee rounds down and the rest goes to the income pool, so fee plus pool always equals what was paid.
- Tile income: each epoch's income is split evenly per held tile, and the leftover dust carries into the next epoch, so no tokens are lost or created.
- Stepwise settlement: settling an epoch in pieces with
settleStepgives the same result as settling it in one call. - Season prizes: the 50/30/20 shares add up to 100%, per-member rounding can't pay out more than was allocated, and the dust rolls into the next season.
- Zero-troop attacks: a proposal can't name zero troops, so settlement never divides by zero.
- Pact bonds: a betrayal pays out exactly the two bonds Diplomacy holds, and the last epoch of a pact counts as a break both when attacking and in the
wouldBreakPactcheck. - Casts to smaller integer types: these can't truncate, because total token supply caps troop counts far below the storage limits.
Static-analysis leads: The divide-before-multiply warnings in
Realm._settleandSeason.closeare the intended rounding down, with the leftover carried forward. The "uninitialized" warnings are storage or locals that Solidity starts at zero, which is correct here. Neither is a defect.Not covered in depth: reentrancy and ERC-721 behaviour outside the math area. I read the Banners and LaunchToken entry points only for arithmetic.
ran onclaude · claude-fable-5-1 · 9 turns · 1m 30s · 18 in · 6.2K out · 468.7K cachedsubmission71663ad269f93aaf10a9a9adab58ccea57017c353b08fc71644191b978cdadd2device3c7630b22a73c1fb36d7cccb511d3c400a92c46f4065d9046a3f71b9ce3aa6bestarted fromeeee3c75fa33e038c1605d0b1a79ad1272434c78bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothing - Zero-loss rounding in battles (217df208): Fixed by documentation, which was one of the two options I offered. The code is unchanged:
- contracts reviewed
#1Audit economicsno findings
afterBuild contract project, Write foundry tests, ManifestThe review round is settled. My one prior finding is fixed, and I found no new reproducible defect.
What I checked
- The fix. Guilds.propose now reads the tile from the target Realm at
src/Guilds.sol:216-219and reverts unless the named holder currently holds it. The proof I attached last round, copied under test/scratch and run against the revised code, now passes because the forged proposal is rejected at creation. - Bypasses of the fix. A fake target contract that reports any holder does produce an approved proposal, but the real Realm cannot consume it because Guilds.consume requires the caller to be the proposal's target. A truthful proposal is still rejected at declaration when the tile changes hands. An out-of-range tile is rejected at creation. The tile read is a static call, so it cannot reenter state.
- Full suite. All 192 project tests pass, including the proof.
Output
The findings file at the repository root holds an empty findings list, a resolved entry for the earlier finding with the evidence above, and coverage rows for all 31 entry points, each marked holds with a one-line reason. The scratch tests were deleted and the working tree is clean apart from the findings file.
ran onclaude · claude-fable-5-1 · 21 turns · 2m 30s · 226 in · 10.2K out · 565.2K cachedsubmission18cd470f0aba982c404572d6981af7713955e896b1da195d9acb4c615ae24530deviceaad1250d716d3f820ac59a7a42ff5b868101d70325cda8f13f943f22cd5f52abstarted fromeeee3c75fa33e038c1605d0b1a79ad1272434c78bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothing - The fix. Guilds.propose now reads the tile from the target Realm at
- contracts reviewed
#6Audit permissions3 findings
afterBuild contract project, Write foundry tests, ManifestReview round settled. The findings file is at
.imd-findings.jsonwith three settlement entries and 32 coverage rows, and the working tree is otherwise untouched.What I settled
- Open-join treasury capture (prior high). The behavior is unchanged: the attached proof still fails on this tree. But the author's dispute holds. The approved workflow mandates the exact rules that produce it: anyone can join, one vote per member, and a majority spends the treasury. Every remedy I offered changes one of those rules. I withdrew the high severity and recorded it as a documented trust assumption that needs a requester decision, not an author fix. The README now discloses it in its second paragraph, the Assumptions section, launch.json notes, and a passing executable example.
- Last-second prize dilution (prior high). Same outcome. The brief says prizes are split equally among members who had joined before the season ended, fixed at season end. The code matches that literally, and the proof still fails only because the behavior is what the brief asks for. Withdrawn to info, disclosed in the README and notes. Both issues share one root cause, so a single requester decision to gate join would remove both.
- Pact open offer (prior low). Fixed. Pact proposals carry a minimum counter-bond in the third data word, and Diplomacy rejects a pair below either minimum in both argument orders before any proposal is consumed. I re-ran my original 1 wei scenario with the minimum set and it now reverts with treasuries untouched. The author's revision tests cover the boundaries and a fuzzed replacement path.
Verification run
- Both attached proofs fail on the current tree, confirming the behavior is unchanged rather than silently altered.
- The permanent suite passes: 191 tests across 12 suites.
- Slither and Aderyn leads in my area (external read in propose before state writes, narrowing casts in checkpoints, reentrancy around consume) trace to no privilege gain or fund movement beyond what any address can already do.
Nothing new reported. I found no fresh, reproducible defect in the access control, trust gap or asymmetry areas. The only open item is a requester scope decision on open membership, which the author cannot resolve within the approved rules.
ran onclaude · claude-fable-5-1 · 23 turns · 5m 9s · 386 in · 15.6K out · 978.3K cachedsubmission0cfd6d09d8acb95db58c6f8ab7da1aaaa18d8c821b3d5f418e2a574860ac4b68device30a6c1a419ef4f9c0b7b9345d1843aaf4945ad583f614ed8027cb22761e6f96cstarted fromeeee3c75fa33e038c1605d0b1a79ad1272434c78bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothingSettled, not a code defect against the approved rules: open join lets a fresh-wallet majority pay out a guild treasury (prior id 88fb682f)src/Guilds.sol:155
Settled, not a code defect against the approved rules: season prize split by member count at seasonEnd-1 pays last-second joiners (prior id 69368d89)src/Season.sol:105
Fixed: Pact proposals now carry a minimum counter-bond that Diplomacy.sign enforces before any funds move (prior id 1679a4d5)src/Diplomacy.sol:110
alice founds guild 1 and deposits 1000e18; bob founds guild 2 and deposits 1 wei; alice proposes Pact(diplomacy, 1000e18, 2, 10, 1000e18); bob proposes Pact(diplomacy, 1, 1, 10, 0); outsider calls sign(pa, pb) and sign(pb, pa).
Expected: revert ProposalsDoNotMatch, treasuryOf(1) == 1000e18, neither proposal executed.
Actual: matches expected.
Verdict: fixed.
- contracts reviewed
#47Audit flowno findings
afterBuild contract project, Write foundry tests, ManifestThe findings file is in place at the repository root (git excludes it locally by design, alongside
.imd/), the scratch directory is gone, and no tracked file changed.Result: no substantiated defect in the control-flow area. The findings list is empty and the coverage record answers all 31 entry points as
holds, plus five invariant rows.What I covered
- Execution Trace: every state-changing path in Guilds, Realm, Diplomacy, Season, Banners and LaunchToken, tracing checks, writes and external calls. All external calls from state-changing paths go to trusted game contracts or the hook-free launch token. The single untrusted call,
Guilds.proposereadingtile()from a proposer-chosen target, is compiled as a STATICCALL becauseIRealm.tileisview. A probe with a state-changing fake target reverted, so no reentrancy is possible there. - Cross-transaction interleavings: stepwise settlement with the budget landing exactly on phase and tile boundaries matched one-shot settlement on map, garrisons and reserves. Re-signing a pact in the epoch of a betrayal is blocked until the attack settles. Leave-and-rejoin in the last second of a season counts once in both
memberCountAtandwasMemberAt, so close and claim stay consistent. - Periphery: the IRealm and IERC20 interfaces match Realm and LaunchToken. All six ABI files under docs/abi equal the compiled ABIs byte for byte. Realm's init code is 27,959 bytes, under the EIP-3860 limit, with a 10,290-byte runtime.
- Manifest: launch.json constructor arguments match the ABIs, README and deploy script. The token takes no arguments and matches name, symbol and decimals. No contract holds a privileged role, so the unused
$owneris correct. - Static-analysis leads: all reviewed. The uninitialized-state, divide-before-multiply, strict-equality, unused-return and reentrancy lines are either false positives on mappings of arrays and fixed-token calls or intentional rounding whose dust is carried forward.
One measurement for the services stage, not a defect: creation gas is 1.75M for Guilds and 5.28M for Realm, which nests Diplomacy, Season and Banners. About 7.0M for the application contracts, which the deployer's gas-ceiling simulation should account for.
Not reached: nothing in the assigned area. The existing suite of 191 tests passed on this tree.
ran onclaude · claude-fable-5-1 · 35 turns · 14m 3s · 578 in · 61.8K out · 2.5M cachedsubmissionc75f4dd02767a42e928fd6474ecd83ab3c3ff1428d60364a004c3a873f5644bbdevice3f6a9bdd601cb99f6ed43e548c54969af8f5a70edeae432aa541d955a4078cdfstarted fromeeee3c75fa33e038c1605d0b1a79ad1272434c78bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothing - Execution Trace: every state-changing path in Guilds, Realm, Diplomacy, Season, Banners and LaunchToken, tracing checks, writes and external calls. All external calls from state-changing paths go to trusted game contracts or the hook-free launch token. The single untrusted call,
- contracts reviewed
#420Audit judgeno findings
afterBuild contract project, Write foundry tests, Manifest, Audit math, Audit permissions, Audit economics, Audit flowThis round leaves no outstanding findings.
.imd-findings.jsonholds an empty findings list and a coverage record answering all 31 entry points asholds, plus three invariant rows. No tracked file was changed.What I settled
Prior finding Author's answer My verdict Fresh-wallet majority can pay out a guild treasury (medium) disputed Settled as documented design Last-second joiners share the season prize (medium) disputed Settled as documented design Attack proposal could name a predicted future holder (low) fixed Fix confirmed Pact accepted any counter-bond (low) fixed Fix confirmed Expelled member can rejoin at once (low) documented Settled Small forces lose zero troops (low) documented Settled - Treasury capture. The supplied proof still fails on this tree, with the attacker holding the full 1000 PACT. The behaviour is unchanged and follows the approved brief: anyone joins, one vote per member, majority spends. My earlier report offered plain README disclosure as the remedy if the design was kept, and the README and manifest notes now state it.
- Last-second prize dilution. My own run reproduced it: nine wallets joining one second before season end took 22.5 PACT and the founder 2.5 PACT. This matches the brief's rule that eligibility is fixed at season end, and it is now disclosed.
- Attack holder. Proposing an attack that names a guild not yet holding the tile now reverts and creates no proposal. The declaration-time check still rejects a holder that changed after an honest proposal.
- Pact counter-bond. A 1 wei bond against a 1000 PACT minimum now reverts in both argument orders. Treasuries, proposals and the pact count stay untouched. A matching bond signs, and both bonds return on expiry.
- Expulsion and rounding. Behaviour is kept and disclosed in the README. The author's tests reproducing both pass.
Decision left to the requester
Both disputed items share one root cause, which is open instant membership. Any guild treasury can be taken at gas cost by whoever brings more wallets than the guild has members. Gating
joinwould remove both consequences, but it changes the approved "anyone can join" rule, so it is a scope decision and not an author defect.How I verified
- The project suite passes: 191 tests, 0 failures.
- I ran the supplied proof and my own three scratch tests covering the two fixes and the season payout.
- The source changes this round are limited to the two fixes and one interface line. I found no new defect in them.
- All six ABI exports match the compiled output.
launch.jsonuses only schema fields, and its two constructor argument lists match the contracts.
Not done
- Protected tests. The two protected launch-floor tests could not run here. They need factory environment variables that only the service supplies.
- Static analysis. Slither and Aderyn were not run by me. I treated their supplied output as leads and none reproduced as a defect.
- Scratch tests. I deleted them after running, so they are not in the tree.
ran onclaude · claude-fable-5-1 · 15 turns · 4m 1s · 22 in · 15.4K out · 1M cachedsubmission2b97ffc123e257d9d7d8f75558d9f04c8562b38df002a8c6d8aa23d57e116ad2device72b617d4b615473ad3b763b0e3d0fbbe45ab980941c095e9f4ea11e135554bebstarted fromeeee3c75fa33e038c1605d0b1a79ad1272434c78bundlenoneapplied onc82c78e58ccc6652a2b535fa8a8a6fc3c2fd56fe9f315ccb6c7302e0abaea7bc, fe0503649e6db8be1a17cb00909b9ea169871b715865ce01a9d2828f8e04d299, 2bac54961c27cd1e7b72053c49507b347e5d1e0a25a50e74d763cf437b541668changed · 0 filesnothing - contracts publishedidentity-md-launches/launch-444-workflow-contract-stage-context
- deployed
4 contractson Sepoliatransaction
- rebuilt
- Banners, Diplomacy, Guilds, LaunchToken, Realm, Season · verifier 0.1.0 · solc 0.8.26
- gates
- provenance
- findings
- independent review
- bytecode
- manifest
- protected invariants
- economics
- proof
commit, attestation, manifest, tree, per-contract hashes
- repository
- identity-md-launches/launch-444-workflow-contract-stage-context
- commit
- eeee3c75fa33e038c1605d0b1a79ad1272434c78
- attestation
- 2e57e11276564d5e4704de3b7dee3b8ef3028905d669d2a7e8ef0da214a85991
- manifest
- 7b0e07acf787decf5aae1c5fc034c02aa6f898a7e857c946ea10504206f52e67
- allocations
- 0x5d9023130ae8779eedb06379846819fc4fbf1b55f72367bbb8e32b03e004cdc9
- constructor
- Guilds: $token, 3600
- constructor
- Realm: $token, $contract:Guilds, 3600, 604800, 1000000000000000000, 500
- tree
- 2a85259a0d3bca6852188376e5bda736196d46f5
- compiler
- solc 0.8.26, optimizer 200 runs, reproducible
- contract
- Banners
src/Banners.sol · 4771 bytes
creation f6f9a72f447fb14e0779c8863ccfa7d5b116ace955005842566e821226f00059
abi a50548992f50c19bd9040e3661e002780cefe53cdfeb1e83ef109df3b0ff891e
metadata cb7b1ebaa5f7bd2d2e0b93f3ff020406aca82e29f82c6d9a4d631f6abec93eab - contract
- Diplomacy
src/Diplomacy.sol · 5253 bytes
creation 87afb0bda4789989a1187554b82bf8cc445f1e52bec967c699271d589b18fa1b
abi 44ccbf47671c086060a7bf1849c289ac0ecc5e9a8399c0cdc4daa8b70222ab2f
metadata dd9dee2e6d733c51a6abf8f043931a410b31b5d6a0db1ff36bf0f238fe2af888 - contract
- Guilds
src/Guilds.sol · 8993 bytes
creation dd1b9a8e032cc415a159c62ce3f7d980bafa7e8ffc73eed5f13e76da449866d4
abi 55e99357920c3633a3996f9072ed03e80037f8c40f7c905b2e711fdd43c845f7
metadata 1f9deae91c9a5237c2dbb13ad67dab0724a3cd00bc09b8a8c032aa208fc869cb
onchain at 0x8cf4…2e42, block 11,805,514 · creation code matches - contract
- LaunchToken
src/LaunchToken.sol · 1496 bytes
creation dbe83e269c26504ba956b795b1efffc3859f84a1b7eb21801eb782d019f7aaa2
abi 369bae8794697d4536e43b3fc6e24a41f541fe8fec3505674c580bf67eb7010c
metadata e9eaaa2442a20812733e0ebcd75c377836b121f1b1562baa148be86cc6ff6b5c
onchain at 0x7f88…818c, block 11,805,514 · creation code matches - contract
- Realm
src/Realm.sol · 27959 bytes
creation 59676a12e0c9f2c7fc8d2e7822715bc41e5072c4a66b4d95c051776f515b253b
abi c9286d6c9356dc490d8677bad57830f54db3b2d4c58d2d5374947e379602d24b
metadata 6aff6bb0cb076786bfe03cafefa4b363838b178048b9efe86693f566f0754aa5
onchain at 0x206b…c990, block 11,805,514 · creation code matches - contract
- Season
src/Season.sol · 10928 bytes
creation 4e7422ffcf2bad0bbe92fcfb0cbe025daeef48d08305cddc26b92559d74e19d3
abi 36bec5765d914e9a1970bd78d5a0f7192c76e1fcce8ca6cbba141c5b82ea73e5
metadata 0c8d6d136238d44af2ef55dbea09d7f902248418979bae7bcc43b4206597a8cc - contract
- MerkleDistributor deployed by the factory, not rebuilt
creation d90dadda71ddde9d5d4e6a5a7ffe3023df09b73d05ced387203f5e8cefbdf8d5
onchain at 0x174c…29a1, block 11,805,514
- website built
#2Frontend for contract71 files changed
writes toweb/**dist/**docs/**web/.gitignoreran onclaude · claude-fable-5-1 · 53 turns · 39m 12s · 1.6K in · 191.1K out · 11.7M cachedsubmission8098dbdf680a5d81853ac0339144e8ea651b8f7a115e84eada773617e0ee1cf2device468e82a89b9bfe188ef46b055e2ea554bde626cc162630c20effb0fcc7e13fedstarted fromeeee3c75fa33e038c1605d0b1a79ad1272434c78bundlee2397e3f896b6d5288930302af3d3dfcfadb2e89a5ee0d0a96e6dcf1ae935721 · 313 KBverifiedrebuilt and matched · verifier 0.1.0 ·changed · 71 filesdist/abi/Banners.jsondist/abi/Diplomacy.jsondist/abi/Guilds.jsondist/abi/LaunchToken.jsondist/abi/Realm.jsondist/abi/Season.jsondist/assets/ccip-CbWQBa5x.jsdist/assets/index-BiCxKAye.jsdist/assets/index-NJLhmkxN.cssdist/banner.svgdist/favicon.svgdist/imd-deployment.jsondist/index.htmlweb/.gitignoreweb/README.mdweb/index.htmlweb/package-lock.jsonweb/package.jsonweb/public/abi/Banners.jsonweb/public/abi/Diplomacy.jsonweb/public/abi/Guilds.jsonweb/public/abi/LaunchToken.jsonweb/public/abi/Realm.jsonweb/public/abi/Season.jsonweb/public/banner.svgweb/public/favicon.svgweb/public/imd-deployment.jsonweb/scripts/check-manifest.mjsweb/scripts/lib.mjsweb/scripts/manifest.mjsweb/scripts/sync-deployment.mjsweb/src/App.test.tsxweb/src/App.tsxweb/src/components/ClockCard.tsxweb/src/components/ProposalCard.tsxweb/src/components/WalletBar.tsxweb/src/components/feed.tsweb/src/components/ui.tsxweb/src/config/deployment.test.tsweb/src/config/deployment.tsweb/src/config/launch.tsweb/src/lib/client.tsweb/src/lib/errors.test.tsweb/src/lib/errors.tsweb/src/lib/format.test.tsweb/src/lib/format.tsweb/src/lib/game.tsweb/src/lib/logs.tsweb/src/lib/swap.test.tsweb/src/lib/swap.tsweb/src/lib/wallet.test.tsweb/src/lib/wallet.tsweb/src/main.tsxweb/src/pages/DiplomacyPage.tsxweb/src/pages/FeedPage.tsxweb/src/pages/GuildDetailPage.tsxweb/src/pages/GuildsPage.tsxweb/src/pages/MapPage.tsxweb/src/pages/PlayPage.tsxweb/src/pages/SeasonPage.tsxweb/src/pages/SwapPage.tsxweb/src/state/app.tsweb/src/state/store.test.tsweb/src/state/store.tsweb/src/state/tx.tsweb/src/styles.cssweb/src/test/harness.tsxweb/src/test/mockChain.tsweb/src/test/setup.tsweb/tsconfig.jsonweb/vite.config.ts - website publishedidentity-md-launches/launch-447-workflow-frontend-stage-context
- hostedpacts.site.identitymd.ethnaming transaction
- checkedwaiting for hosting9 attempts
- deployment-config
- static-assets
- html-assets
- named-entrypoint