{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"2c2059ae-65a5-4dd9-959b-b656da13de30","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"106ee38a6df999fd46a7ca06e4ffa9adf773ea90f06c5c8e6a9648fb70d35c32","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"bfd1eefdca29163e288a56d2c8ed21557344f5f37fb16d8a2ed576abf1936d1b","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"77b8dc757653c9a0b6e1053a993415de932fdd666cbfa574a07a44e263c5e167","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","subagents":4,"tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"09f9d370b92307675c0fb9966e284fe1557698c2310ecfec92c9ede3916d68ff","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"21b671079e45443c3e4e5700d517ac429bb9a7c1791c06b4d5637d01bec99734","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"dcd0e849a1cbdccbf02ce0671cdfaf48f6b4f21451a51ca7932ffbc19c0fac7a","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"15b04fc8f60521936b9e2b37c09a804685ec689fc98cd5b04510d986d3106a15","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"15b04fc8f60521936b9e2b37c09a804685ec689fc98cd5b04510d986d3106a15","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"6712a3824ea1040723705a8411499f0cb7da270087223e7484e9ff5b3e1e13fb","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"9540a21320705ed0d980fb6ebaacc078e4b3dd208b662be0d22833274490237a","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"606842ccca0e7c5d3017a54684625438eab9b351eb51dcf0cf88c43d1ea41464","skillId":"write-foundry-tests","subagents":4,"tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"606842ccca0e7c5d3017a54684625438eab9b351eb51dcf0cf88c43d1ea41464","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: Mutually Assured Destruction (MAD).\nToken name: Mutually Assured Destruction\nToken symbol: MAD\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.","parentJobId":null,"planHash":"ae49931f8b653459b608aec7249a843955244df1649e977b5b24ec458f733287","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"2c2059ae-65a5-4dd9-959b-b656da13de30","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2791-mutually-assured-destruction"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52223","feedbackHash":"69f10b34cb9d5d5b1607159f526cd2b51f9374a19cd3b0536463e7e4ea24ba02","nodeKey":"audit_economics","submissionHash":"106ee38a6df999fd46a7ca06e4ffa9adf773ea90f06c5c8e6a9648fb70d35c32","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52222","feedbackHash":"fa9b7dcee0266f5175f61b5a211262387bc95ede992f651b2715d21b0dee855d","nodeKey":"audit_flow","submissionHash":"bfd1eefdca29163e288a56d2c8ed21557344f5f37fb16d8a2ed576abf1936d1b","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52479","feedbackHash":"0d854b1d12913e27503d8cd6f28e261416142949aec9bac14c53631f4cf5fd7a","nodeKey":"audit_judge","submissionHash":"77b8dc757653c9a0b6e1053a993415de932fdd666cbfa574a07a44e263c5e167","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51465","feedbackHash":"76766eccf94b218dda118fd728ff2b4ef48e21945af57f4118caa60d1db118c4","nodeKey":"audit_math","submissionHash":"09f9d370b92307675c0fb9966e284fe1557698c2310ecfec92c9ede3916d68ff","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52613","feedbackHash":"f1b56e202b438e5a1e329b674281a691687f7d20dbc80d99c53a56d85aa8c7ed","nodeKey":"audit_permissions","submissionHash":"21b671079e45443c3e4e5700d517ac429bb9a7c1791c06b4d5637d01bec99734","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52734","feedbackHash":"fec3c8b3bc15fbe2acc5d9c0a7cd5c951a0433409f79d3521960357d871648c8","nodeKey":"build_contract_project","submissionHash":"dcd0e849a1cbdccbf02ce0671cdfaf48f6b4f21451a51ca7932ffbc19c0fac7a","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52397","feedbackHash":"682c9a68f81ac8154357d59b00e09ffd367e3a536b5b6fcde381a3c8a501b72d","nodeKey":"manifest","submissionHash":"6712a3824ea1040723705a8411499f0cb7da270087223e7484e9ff5b3e1e13fb","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51426","feedbackHash":"ec073efcc9ebca740e7ead95404ea3e03795eb1eae9716ca2ff3dad8ad454c6b","nodeKey":"write_foundry_tests","submissionHash":"9540a21320705ed0d980fb6ebaacc078e4b3dd208b662be0d22833274490237a","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"f3dd269b46048e4b1b308646b3f80868d9244279c5608beb523895d9ec9dc60c","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f0c4ae5b8ada215c","findings":[{"citation":"resolved","description":"The token inherits OpenZeppelin v5.4.0 ERC20 unchanged. In ERC20._spendAllowance the check is `if (currentAllowance < value)`, so with currentAllowance == 0 and value == 0 the check passes, and _update then emits Transfer(from, to, 0). Any caller can therefore emit a Transfer(victim, attacker, 0) event naming an arbitrary `from` that never approved them, and a Transfer(victim, address(0), 0) via burnFrom. Balances, allowances and totalSupply are unchanged, so no funds are at risk. ERC-20 requires zero-value transfers to be treated as normal transfers and this is the standard OpenZeppelin behaviour; it is reported only so the operator knows that off-chain tooling that trusts Transfer events as proof of an approval relationship can be poisoned. Boundary: _spendAllowance with (allowance=0, value=0). Assumption: a transferFrom from an account implies that account approved the caller. Actual: the zero case passes with no approval. No change is recommended; if the requester wants to suppress it, an `_update` override that reverts on value == 0 would also refuse legitimate zero transfers and break ERC-20 conformance, so this is a documentation item.","line":20,"path":"src/MADToken.sol","reproduction":"State: fresh MADToken deployed by `deployer` (holds 1e27). Caller `alice` (balance 0, allowance(bob -> alice) == 0). Call `vm.prank(alice); token.transferFrom(bob, alice, 0)`. Expected by a naive integrator: revert ERC20InsufficientAllowance. Actual: returns true and emits Transfer(bob, alice, 0). Likewise `vm.prank(alice); token.burnFrom(deployer, 0)` succeeds and emits Transfer(deployer, address(0), 0); totalSupply stays 1000000000000000000000000000. Verified in test/scratch/MathBoundary.t.sol: test_zeroTransferFromEmptyAccount and test_zeroBurnFromWithoutAllowance both pass on this tree.","severity":"info","snippet":"contract MADToken is ERC20, ERC20Burnable, ERC20Permit {","title":"Zero-value transferFrom and burnFrom succeed without allowance and emit Transfer events from any account (ERC-20-conformant; address-poisoning vector for indexers, no fix required)"}],"hash":"09f9d370b92307675c0fb9966e284fe1557698c2310ecfec92c9ede3916d68ff","nodeId":"857d882c-7089-45ee-9b70-1c460758b4ad","outcome":"completed","summary":"The review is complete and the findings file is written and validated. The working tree has no tracked changes.\n\n**Outcome: no defects in the math area.** The MAD token is OpenZeppelin v5.4.0 `ERC20 + ERC20Burnable + ERC20Permit` with no custom arithmetic, so the three guides (Math Precision, Boundary, Numerical Gap) have very little surface to attack. One info-level note is recorded; it needs no fix.\n\n**What I checked**\n- **Library integrity.** The vendored OpenZeppelin and forge-std files differ textually from upstream, but only by formatter rewraps. Compiling the token against pristine upstream v5.4.0 and forge-std v1.10.0 tarballs produced byte-identical creation and runtime bytecode.\n- **Math Precision.** The only arithmetic is the compile-time constant for the supply, which evaluates to exactly 1e27. There is no division, no scale conversion, no downcast. The supply fits in uint128, so Uniswap v4 liquidity accounting cannot overflow.\n- **Boundary.** No external calls except the ecrecover precompile, no payable path, no bytes decoding. A scratch suite of 25 tests drove every entry point at zero, max, one-wei-over, exact-allowance, infinite-allowance, deadline-equals-now, high-s, bad-v, zero owner or spender, and chain-id change. All behaved as the standard specifies.\n- **Numerical Gap.** A fuzz over mixed transfers and burns held the sum-of-balances equals totalSupply invariant on every run. Allowance is checked before balance, and a balance revert leaves the allowance untouched.\n- **Forbidden opcodes.** A reachability scan of the runtime bytecode finds no DELEGATECALL, CALLCODE or SELFDESTRUCT. Sending ETH reverts.\n- **Static analysis lead.** The aderyn large-literal note on line 28 is not a defect; the constant is asserted exact.\n\n**Recorded finding (info only)**\nZero-value `transferFrom` and `burnFrom` succeed with no allowance and emit a Transfer event naming any `from` address. Balances and supply are untouched. This is ERC-20-conformant OpenZeppelin behaviour and is noted only as an address-poisoning vector for off-chain indexers.\n\n**Coverage.** All six entry points have rows, plus five invariant rows. Not reached: nothing within my area. Outside it, I did not assess the deploy script's broadcast path or launch manifest contents, which belong to the other specialists.","treeHash":null,"usage":{"cachedInputTokens":1074673,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":22532,"runtime":"claude","turns":39,"wallClockMs":278343}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f20ec62b0213db3f","findings":[{"citation":"resolved","description":"MADToken inherits OpenZeppelin ERC20Permit unchanged (lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol:42-60). permit() is callable by anyone holding a valid signature and consumes the owner's nonce. If a relayer or MEV searcher submits a holder's signature before the holder's own transaction, the holder's bundled call (permit followed by transferFrom in one tx, the common router pattern) reverts with ERC2612InvalidSigner because the nonce has moved. The allowance is still granted to the intended spender, so no tokens are lost or redirected; the cost is one failed transaction and gas. This is the documented property of every ERC-2612 token and is not a defect of MADToken itself. It is recorded so integrators (routers, vaults) built on MAD wrap permit in try/catch or check allowance first, as OpenZeppelin recommends. No change to the token is needed.","line":20,"path":"src/MADToken.sol","reproduction":"State: deployer deployed MADToken and transferred 100e18 MAD to holder H (key k). H signs Permit(owner=H, spender=S, value=50e18, nonce=0, deadline=now+1h) over DOMAIN_SEPARATOR(). Step 1: attacker A (any address) calls token.permit(H, S, 50e18, deadline, v, r, s) -> succeeds, allowance(H,S)=50e18, nonces(H)=1. Step 2: S's own transaction calls token.permit(H, S, 50e18, deadline, v, r, s) with the same signature -> reverts ERC2612InvalidSigner (nonce now 1, recovered signer != H), so any logic bundled after it in the same tx is also reverted. Expected by an integrator: permit succeeds in its own tx. Actual: revert. Step 3: S calls transferFrom(H, S, 50e18) in a fresh tx -> succeeds; balanceOf(S)=50e18. Verified in test/scratch/EconScratch.t.sol::test_permitFrontRunGriefsBundledCall (passes on the current code, i.e. the behaviour is present).","severity":"info","snippet":"contract MADToken is ERC20, ERC20Burnable, ERC20Permit {","title":"ERC-2612 permit can be front-run so an integrator's bundled permit+transferFrom reverts (standard behaviour, no fund loss)"}],"hash":"106ee38a6df999fd46a7ca06e4ffa9adf773ea90f06c5c8e6a9648fb70d35c32","nodeId":"9afdf09a-9247-4f10-898f-686832aef6d3","outcome":"completed","summary":"The findings file is valid JSON and no tracked file in the repository changed. The review is complete.\n\n**Outcome: no economic defect found.** The token is OpenZeppelin v5.4.0 `ERC20 + ERC20Burnable + ERC20Permit` with constants only and no custom transfer logic, so none of the failure modes in the Economic Security, Invariant or Flow Gap guides has a surface to land on. The findings file holds one informational entry and a full coverage record.\n\n**What I checked and how**\n\n- **Economic Security guide.** No external dependencies, oracles, callbacks or price-dependent paths exist. The launch flows (factory to distributor, distributor to claimant, pool manager seed and both swap directions, remainder to the requester) move exactly what they say because there is no fee, tax, blocklist or pause. ERC-20 and ERC-2612 compliance were traced through the vendored code and the project's 40 tests, which all pass.\n- **Invariant guide.** I wrote a Foundry invariant test with a handler driving random transfer, approve, transferFrom, burn, burnFrom and permit calls across five signers and the factory. The conservation law (sum of balances equals totalSupply, which equals initial supply minus burned) never broke. Supply is monotone non-increasing and no mint path exists after the constructor. The 10/50/40 split of 1e27 is dust-free.\n- **Flow Gap guide.** The constructor takes no arguments and makes no external call, so the single-transaction launch cannot be derailed by it. The protected floor tests for supply, decimals, swarm share, seed and swaps, no supply growth, and no privileged freeze would all pass on this code by inspection.\n- **Supply chain.** Because the library is vendored as plain files, I diffed every Solidity file against the upstream v5.4.0 tag. All differences are `forge fmt` reformatting, including in the files that compile into this token, so the library is semantically v5.4.0.\n\n**The one entry, severity info.** Anyone can submit a holder's permit signature first, which makes the holder's own bundled permit-plus-transferFrom transaction revert. The allowance still lands with the intended spender and no funds move, so this is the documented ERC-2612 property rather than a MAD defect. I recorded it with a reproduction so integrators building routers on MAD know to wrap `permit` in try/catch.\n\n**Coverage.** All six verifier entry points have rows (five `holds`, permit marked `finding` pointing at the info entry), plus rows for the conservation invariant, the launch split, the constructor mint, the vendored-library check, and the documented stuck-tokens note. Nothing was left unreached. The scratch tests live in `test/scratch/EconScratch.t.sol`, which is not part of the submission.","treeHash":null,"usage":{"cachedInputTokens":1212446,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":20915,"runtime":"claude","turns":34,"wallClockMs":314125}},{"artifacts":[],"attempt":2,"bundleHash":null,"device":"7eaf1cd0fb3df712","findings":[{"citation":"resolved","description":"The fuzz test transfers from `deployer` to a fuzzed `to` and asserts balanceOf(to) + balanceOf(deployer) == SUPPLY. It excludes only address(0), not `deployer`. On a self-transfer the token is correct (OZ _update debits and credits the same slot, so the balance stays at SUPPLY), but the assertion adds the same balance twice and gets 2 * SUPPLY. Forge's fuzzer reuses addresses from the test's storage and reliably finds this input, so `forge test` on the delivered tree reports 1 failed and 39 passed. The contract has no defect here. The deliverable's own check is red, which hides real regressions behind a known failure. Fix: add `vm.assume(to != deployer);` (the sibling fuzz test at line 455 already excludes deployer) or keep a separate self-transfer branch.","line":406,"path":"test/MADToken.t.sol","reproduction":"Run `forge test --match-test testFuzz_transferConservesSupply`. Counterexample: to = 0xaE0bDc4eEAC5E950B67C6819B118761CaAF61946 (= makeAddr(\"deployer\"), checked with `cast wallet address --private-key $(cast keccak deployer)`), amount = 19742. Expected: the test passes, since the self-transfer keeps the balance at 1e27 and totalSupply at 1e27. Actual: `assertion failed: 2000000000000000000000000000 != 1000000000000000000000000000` at line 406.","severity":"low","snippet":"        assertEq(token.balanceOf(to) + token.balanceOf(deployer), SUPPLY);","title":"Project test suite fails: testFuzz_transferConservesSupply double-counts the balance when the fuzzed recipient is the deployer"}],"hash":"21b671079e45443c3e4e5700d517ac429bb9a7c1791c06b4d5637d01bec99734","nodeId":"f06a0151-4226-4794-890e-c89be26fcf37","outcome":"completed","summary":"I found no access-control, trust-gap or asymmetry defect in `MADToken`. The one finding I wrote up is a bug in the project's own test suite: `forge test` currently reports 1 failed and 39 passed. The results are in `.imd-findings.json`, with 1 finding and coverage rows for all 6 entry points plus 2 invariants. I changed no repository files.\n\n**What the token is:** `src/MADToken.sol` is OpenZeppelin v5.4.0 `ERC20`, `ERC20Burnable` and `ERC20Permit`, with only the name, symbol, decimals and supply fixed. There is no owner, role, mint, pause, blocklist or fee. The constructor takes no arguments, calls no other contract, and mints the full 1e27 to `msg.sender`, which is the factory.\n\n**Permission checks (Access Control, Trust Gap, Asymmetry), all `holds`:**\n- **No privileged powers.** Nothing in the contract can raise the supply, and no one can move or freeze another holder's balance.\n- **`burnFrom` is not a privileged burn.** It spends an allowance first, so the factory or anyone without approval gets `ERC20InsufficientAllowance`. It follows the same rules as `transferFrom`, including leaving a max allowance unchanged.\n- **The paired operations behave the same way.**\n  - `approve` and `permit` both reject a zero spender.\n  - `burn` and `transfer` both check the sender's balance.\n  - `permit` checks the deadline, uses each nonce once, rebuilds its signing domain if the chain id changes, rejects malleable signatures, and requires the signer to be the owner.\n- **Launch flows arrive whole.** Transfers carry no fee, so the factory, distributor and PoolManager flows move exactly the amount sent and need no exemptions.\n- **The vendored libraries are genuine.** I compared the OZ files the token uses with a fresh copy of upstream v5.4.0; the only differences are formatting.\n\n**Finding 1 (low), `test/MADToken.t.sol:406`:** `testFuzz_transferConservesSupply` excludes only `address(0)` as the recipient. When the fuzzer picks `to = deployer` (0xaE0bDc4e…F61946, which I confirmed is `makeAddr(\"deployer\")`) with `amount = 19742`, the test adds the same balance twice and gets 2e27 instead of 1e27. The token itself handles the self-transfer correctly. The fix is `vm.assume(to != deployer);`, which the fuzz test at line 455 already does.\n\nThe static-analysis lead (aderyn's large-numeric-literal at line 28) is just a constant and not a defect. As instructed, I didn't run Slither or the protected floor tests; the floor's harness imports aren't in this repository. Nothing in my area was left unchecked.","treeHash":null,"usage":{"cachedInputTokens":420673,"inputTokens":23,"model":"claude-opus-5-5","outputTokens":7042,"runtime":"claude","turns":12,"wallClockMs":88680}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"b97527597dd934a0","findings":[],"hash":"49a0531f7a6f2c0881323b01c6143b027b55bd4e0b695b97d75cd61d4b8059e7","nodeId":"f06a0151-4226-4794-890e-c89be26fcf37","outcome":"failed","summary":"Claude Code can't use your Claude subscription, usually because a payment is past due · Pay or renew at https://claude.ai/… (if you just paid, try again shortly), or use an Anthropic API key instead","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"claude","turns":1,"wallClockMs":1365}},{"artifacts":[],"attempt":1,"bundleHash":"6e0783320ac4e4a98ea848d12d367e7151f25e5d7f06e6c052f48b4de2f2216a","device":"827152cce766ca0d","findings":[],"hash":"6712a3824ea1040723705a8411499f0cb7da270087223e7484e9ff5b3e1e13fb","nodeId":"32a7642f-91db-489f-b4c0-54c77b5a9805","outcome":"completed","summary":"I wrote `launch.json` for the Mutually Assured Destruction (MAD) token, but I couldn't commit it. Git on this machine has no author name or email set, and I didn't change that setting, so the file is in the working tree but uncommitted. It is the only file changed.\n\nWhat the manifest says:\n- **Token:** the contract is `MADToken`, named \"Mutually Assured Destruction\", symbol \"MAD\", 18 decimals. Its constructor takes no arguments, so `constructorArgs` is `[]`. `totalSupply` is `\"1000000000000000000000000000\"`, which is exactly what the constructor mints to the deployer.\n- **Application contracts:** none, because the accepted code only contains the token.\n- **Pool:** pair token `0xa0df17b5ac76ababa36e1450e2cbcd18a620c845`, fee 12500, tick spacing 60, starting price `79228162514264337593543950336` (one to one).\n- **Economics:** your object, copied exactly.\n- **Notes:** they describe the token: a fixed supply minted once, no owner or admin, no pause, no transfer fee, and holders can burn only their own tokens or ones they have approved.\n\n**Checks:** the JSON parses, `forge build` succeeds, and `forge test` passed all 40 tests with the required fuzz seed. Those tests are the project's own. The two required check files expect `src/LaunchLiquidity.sol` and two other `src/` contracts that aren't in this tree, so I couldn't run them here.","treeHash":"2f80c87ec21395dfc01e97db5a1dcdcab5fd6aee","usage":{"cachedInputTokens":84434,"inputTokens":10,"model":"claude-opus-5-5","outputTokens":1857,"runtime":"claude","turns":6,"wallClockMs":30853}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"dfa08759ca0424de","findings":[{"citation":"resolved","description":"MADToken inherits OpenZeppelin v5.4.0 ERC20Permit unchanged (verified: the token compiled against the pristine npm @openzeppelin/contracts@5.4.0 package produces byte-identical creation and runtime bytecode). permit() is callable by any address holding a valid signature and consumes the owner nonce. A third party can relay a holder signature before the intended spender does; the allowance is still granted to the intended spender, so no tokens are lost or redirected, but a contract that calls permit() then transferFrom() in the same transaction without try/catch reverts with ERC2612InvalidSigner because the nonce has advanced. This is the documented ERC-2612/OpenZeppelin caveat and is inherent to the permit feature the brief asked for. No code change is recommended; integrators should check allowance first or wrap permit in try/catch, and the README permit guidance may mention it. The two specialist reports (audit_flow id 3f4767..., audit_economics id 8110f1...) describe the same root cause and are merged here.","line":17,"path":"src/MADToken.sol","reproduction":"State: deployer deploys MADToken; alice (key k) holds 1000 MAD. Integrator contract I has permitAndPull(owner,value,deadline,v,r,s) = { token.permit(owner,address(I),value,deadline,v,r,s); token.transferFrom(owner,address(I),value); }. alice signs Permit(owner=alice, spender=I, value=5e18, nonce=0, deadline=now+1h) over token.DOMAIN_SEPARATOR(). Step 1: bob (any address) calls token.permit(alice, I, 5e18, deadline, v, r, s) -> succeeds; nonces(alice)==1; allowance(alice,I)==5e18. Step 2: I.permitAndPull(alice, 5e18, deadline, v, r, s). Expected by the integrator: pulls 5e18. Actual: reverts (digest recomputed with nonce 1 recovers a different signer -> ERC2612InvalidSigner). Step 3: I calls transferFrom(alice, I, 5e18) in a fresh call -> succeeds, balanceOf(I)==5e18, so nothing is lost. Reproduced by the judge in test/scratch/JudgeInfo.t.sol::test_permitFrontRunRevertsBundledCall (passes on this tree, i.e. the behaviour is present).","severity":"info","snippet":"///      - ERC-2612 `permit` is included so holders can grant gasless approvals by signature.","title":"Inherited ERC-2612 permit can be submitted by anyone first, so an integrator that bundles permit()+transferFrom() in one call reverts (standard OpenZeppelin behaviour, no loss; merged from audit_flow "},{"citation":"resolved","description":"MADToken inherits OpenZeppelin v5.4.0 ERC20.approve, which sets the allowance to the new value rather than adjusting it, and OZ v5 ships no increaseAllowance/decreaseAllowance. A spender who sees a pending approve that lowers its allowance can spend the old allowance first and then the new one. This is the well-known ERC-20 race inherent to the standard and identical in every OZ v5 token; it is not a defect of this contract and no code change is recommended. Reported at info level only so the README operational notes can advise holders to set an allowance to 0 before changing it, or to use permit with a short deadline.","line":20,"path":"src/MADToken.sol","reproduction":"State: alice holds 1000 MAD and has called approve(bob, 100e18). Step 1: alice broadcasts approve(bob, 50e18) intending to lower the allowance. Step 2: bob front-runs with transferFrom(alice, bob, 100e18) -> succeeds, allowance now 0. Step 3: alice approve(bob, 50e18) lands, allowance 50e18. Step 4: bob transferFrom(alice, bob, 50e18) -> succeeds. Expected by alice: bob can move at most 50e18 in total. Actual: balanceOf(bob)==150e18. Reproduced by the judge in test/scratch/JudgeInfo.t.sol::test_approveRace.","severity":"info","snippet":"contract MADToken is ERC20, ERC20Burnable, ERC20Permit {","title":"Inherited ERC-20 approve() overwrite allows the allowance front-running race when lowering an allowance (standard behaviour, not a code defect)"},{"citation":"resolved","description":"OpenZeppelin ERC20._spendAllowance checks `if (currentAllowance < value)`, so with allowance 0 and value 0 it passes and _update emits Transfer(from, to, 0). Any caller can therefore emit a Transfer event naming a from address that never approved them, including Transfer(victim, address(0), 0) through burnFrom. Balances, allowances and totalSupply are unchanged; no funds are at risk. ERC-20 requires zero-value transfers to be treated as normal transfers, so this is conformant and no change is recommended. Off-chain tooling that treats a Transfer event as proof of an approval relationship can be poisoned; that is a documentation item for indexers, not a contract fix (refusing value == 0 in _update would break ERC-20 conformance).","line":20,"path":"src/MADToken.sol","reproduction":"State: fresh MADToken, alice holds 1000e18, allowance(alice, bob)==0. Call vm.prank(bob); token.transferFrom(alice, bob, 0). Expected by a naive integrator: revert ERC20InsufficientAllowance. Actual: returns true and emits Transfer(alice, bob, 0). Likewise vm.prank(bob); token.burnFrom(alice, 0) succeeds and emits Transfer(alice, address(0), 0); balanceOf(alice) stays 1000e18 and totalSupply stays 1000000000000000000000000000. Reproduced by the judge in test/scratch/JudgeInfo.t.sol::test_zeroValueTransferFromWithoutAllowance.","severity":"info","snippet":"contract MADToken is ERC20, ERC20Burnable, ERC20Permit {","title":"Zero-value transferFrom() and burnFrom() succeed without any allowance and emit Transfer(from, to, 0) naming an arbitrary from (ERC-20-conformant OpenZeppelin behaviour; event-poisoning note only)"}],"hash":"77b8dc757653c9a0b6e1053a993415de932fdd666cbfa574a07a44e263c5e167","nodeId":"669be588-83ed-454d-bb54-ad140ce308dc","outcome":"completed","summary":"The findings file is written and valid, with the snippets copied from the source lines they cite. The review is complete.\n\n**Outcome: no defect in MADToken. Three info notes kept, one specialist finding dropped, nothing blocks the launch.**\n\nWhat I verified against the code:\n\n- **The token is pure OpenZeppelin 5.4.0.** Compiling the same source against the pristine npm package yields byte-identical creation and runtime bytecode, so the vendored copy's formatter-only diffs change nothing.\n- **Launch floor holds.** A scratch test mirroring the protected floor passes: CREATE2 from a factory stand-in mints the whole supply to the factory, decimals are 18, swarm and claim flows move exactly, no admin selector raises supply, no privileged call from the deployer moves or freezes a holder, burnFrom without allowance reverts, no receive or fallback, and a reachable-opcode scan finds no DELEGATECALL, CALLCODE or SELFDESTRUCT. Runtime is 4353 bytes, far under the limit.\n- **Project suite is green.** All 82 tests pass, with the fuzz contract at 1000 runs.\n- **Manifest is consistent.** Schema keys only, empty constructorArgs matching the no-arg constructor, totalSupply equal to the minted constant, lowercase addresses, short notes. Whether economics match the job verbatim is admission's check and not visible from here.\n\nHow I settled the specialists:\n\n- **Merged** the audit_flow and audit_economics permit front-run reports into one info finding. Reproduced in my own scratch test. Inherent to ERC-2612, no loss.\n- **Kept as info** the approve race and the zero-value transferFrom event note. Both reproduced. Both are standard ERC-20 behaviour, no change recommended.\n- **Dropped** the audit_permissions low about the failing fuzz test. The cited test already carries the self-transfer branch, added in the test commit after that specialist ran, and the suite passes.\n\nCoverage: all six entry points marked holds, plus rows for the constructor, bytecode, manifest and the dropped finding. The result is in .imd-findings.json at the repository root. Scratch tests under test/scratch are mine and not part of the submission.","treeHash":null,"usage":{"cachedInputTokens":1081815,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":27764,"runtime":"claude","turns":26,"wallClockMs":363300}},{"artifacts":[],"attempt":1,"bundleHash":"e040ef793afc14bd6643ef6f33dd20d53fb03ce4e13b90b82485324ef737968f","device":"6d41a24119881b34","findings":[],"hash":"9540a21320705ed0d980fb6ebaacc078e4b3dd208b662be0d22833274490237a","nodeId":"a91ce874-2c4d-4d73-a543-d468c1e08ba6","outcome":"completed","summary":"Added failure-path, permit, fuzz, and stateful invariant tests. Fixed the existing self-transfer assertion. All changes are under `test/`.\n\nOffline verification with the required seed passed: build successful, 82 tests passing, and three invariants checked across 32,768 random calls.\n\nNo implementation defects found.","treeHash":"bf0e4652bd32bb382b32312fece76c06a723ca77","usage":{"cachedInputTokens":1868672,"inputTokens":79877,"model":"gpt-6-astra","outputTokens":27133,"runtime":"codex","turns":8,"wallClockMs":574226}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"357c46e3781993d4","findings":[{"citation":"resolved","description":"MADToken inherits OpenZeppelin v5.4.0 ERC20.approve (lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol:120), which overwrites the allowance rather than adjusting it, and OZ v5 no longer ships increaseAllowance/decreaseAllowance. This is the well-known ERC-20 approve race, inherent to the standard and identical in every OZ v5 token; it is NOT a defect in this contract and no code change is recommended. Reported at info level only because the README's 'Operational responsibilities' section discusses permit hygiene but not allowance hygiene; holders wishing to reduce an allowance to an untrusted spender should set it to 0 first (or use permit with a short deadline) and the author may wish to document this. Verified against the vendored OZ copy, which compiles to bytecode byte-identical to pristine npm @openzeppelin/contracts@5.4.0.","line":20,"path":"src/MADToken.sol","reproduction":"State: alice holds 1000 MAD and has approved bob for 100 MAD. Step 1: alice broadcasts approve(bob, 50 MAD) intending to lower the allowance. Step 2: bob observes it and front-runs with transferFrom(alice, bob, 100 MAD) (succeeds, allowance now 0). Step 3: alice's approve(bob, 50 MAD) lands and sets allowance to 50. Step 4: bob calls transferFrom(alice, bob, 50 MAD). Expected by alice: bob can move at most 50 MAD in total. Actual: bob moved 150 MAD. Confirmed in a Foundry scratch test (balanceOf(bob) == 150 ether afterwards).","severity":"info","snippet":"contract MADToken is ERC20, ERC20Burnable, ERC20Permit {","title":"Inherited ERC-20 allowance race: lowering an allowance with approve() can be front-run so the spender moves old + new amount (standard behaviour, not a code defect)"},{"citation":"resolved","description":"ERC20Permit.permit (lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sol:42-60) is callable by anyone with a valid signature and consumes the owner's nonce, so a third party can relay a signed permit before the intended integrator does. The allowance is still granted to the intended spender (no theft, no loss), but a contract that calls permit() then transferFrom() in one transaction without try/catch reverts with ERC2612InvalidSigner because the nonce has already advanced. This is the documented OpenZeppelin/ERC-2612 caveat and is inherent to the design the brief asked for; no code change is recommended. Noted so that integrators (and the README's permit guidance) are aware that permit submissions must tolerate an already-consumed permit, e.g. by checking allowance before calling permit or wrapping permit in try/catch.","line":17,"path":"src/MADToken.sol","reproduction":"State: signer holds 10 MAD; Integrator contract I has permitAndPull(owner,value,deadline,v,r,s) = { token.permit(owner, address(I), value, deadline, v, r, s); token.transferFrom(owner, address(I), value); }. Signer signs a permit for spender=I, value=5 MAD, nonce=0, deadline=now+1h. Step 1: bob (any address) calls token.permit(signer, I, 5 MAD, deadline, v, r, s) -> succeeds, nonces(signer)=1, allowance(signer,I)=5 MAD. Step 2: I.permitAndPull(signer, 5 MAD, deadline, v, r, s). Expected by the integrator: pulls 5 MAD. Actual: reverts (permit recomputes the digest with nonce 1, recovers a different address, ERC2612InvalidSigner). Confirmed in a Foundry scratch test; allowance(signer,I) remains 5 MAD so the holder loses nothing.","severity":"info","snippet":"///      - ERC-2612 `permit` is included so holders can grant gasless approvals by signature.","title":"Inherited ERC-2612 permit front-running: anyone may submit a holder's valid permit first, which makes an integrator's bundled permit+transferFrom transaction revert (standard behaviour, not a code def"}],"hash":"bfd1eefdca29163e288a56d2c8ed21557344f5f37fb16d8a2ed576abf1936d1b","nodeId":"f50e9cee-4128-4350-ae07-cbf846d16c55","outcome":"completed","summary":"The review is complete and the findings file is written. No defects were found in the MAD token.\n\n**Outcome.** The token is OpenZeppelin v5.4.0 ERC20 + ERC20Burnable + ERC20Permit with constant name, symbol, decimals and a one-time constructor mint of 1e27 units to msg.sender. The control-flow area (Execution Trace, Periphery, First Principles) is clean. The file `.imd-findings.json` holds two informational notes and ten coverage rows, all six listed entry points answered.\n\n**What I checked and how:**\n- **Execution trace.** Traced approve, transfer, transferFrom, burn, burnFrom and permit through the vendored ERC20 core to their guards and state writes. Zero-address checks, balance and allowance reverts, infinite-allowance handling, nonce consumption, deadline, domain separator and signature malleability all behave as the standard specifies. A scratch Foundry test confirmed each edge case and was removed afterwards.\n- **Periphery.** The vendored OpenZeppelin tree differs from the npm 5.4.0 tarball in many files, but only by forge-fmt reformatting. Compiling the same MADToken against the pristine npm package produced byte-identical creation bytecode, runtime bytecode and ABI, so no library tampering reaches the deployed contract.\n- **First principles.** Supply constant evaluates to exactly 1,000,000,000 × 10^18. No mint path exists after construction. No external calls other than the ecrecover precompile, no receive or fallback, and an opcode walk of the runtime with the floor test's algorithm found no reachable DELEGATECALL, CALLCODE or SELFDESTRUCT. The launch flows move exactly what they send since there is no fee, hook or blocklist. The project's 40 tests pass.\n\n**The two info notes** are inherent ERC-20 and ERC-2612 behaviours, not code defects, and recommend no code change: the approve overwrite race, and permit relay front-running that can revert an integrator's bundled permit-plus-transferFrom. Each has a concrete reproduction so the author can decide whether to document them.\n\n**Static analysis leads.** Slither reported nothing. Aderyn's \"large numeric literal\" at line 28 is a style note on a correct compile-time constant and was not promoted.\n\n**Not reached.** Nothing in the assigned area. The manifest was not reviewed because no launch.json exists in the tree yet.","treeHash":null,"usage":{"cachedInputTokens":746515,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":22287,"runtime":"claude","turns":39,"wallClockMs":322626}},{"artifacts":[],"attempt":1,"bundleHash":"a974d16e2382bafcb08cdc1508a54ae56bac88df6113e037c997347c8e5e1afe","device":"d32559488518f947","findings":[],"hash":"dcd0e849a1cbdccbf02ce0671cdfaf48f6b4f21451a51ca7932ffbc19c0fac7a","nodeId":"3c95e428-8bf9-4109-9e61-47d6e6c7a1fb","outcome":"completed","summary":"The MAD token project is complete and verified.\n\n**What was built**\n\n- `src/MADToken.sol`: contract `MADToken`, name \"Mutually Assured Destruction\", symbol \"MAD\", 18 decimals. The constructor takes no arguments, calls no other contract, and mints the full supply once to the deployer. It is OpenZeppelin v5.4.0 ERC20 + ERC20Burnable + ERC20Permit with no owner, no mint path, no pause, no blocklist, and no fee on transfer. The supply can only shrink, and only a holder or an approved spender can burn.\n- `test/MADToken.t.sol`: 40 tests covering metadata and supply constants, the single constructor mint, absence of any mint or admin entry point, transfer and allowance success and failure paths, burns, permit (valid, expired, wrong signer, replay, domain binding) and six fuzz properties.\n- `script/DeployMADToken.s.sol`: a local deploy helper whose function the tests call directly. Nothing reads the environment.\n- `README.md`: assumptions, deployment parameters, launch settings for reference, the empty \"After launch\" section, operational responsibilities and security notes.\n- `foundry.toml` pins solc 0.8.26, optimizer on, `bytecode_hash = \"none\"`, `cbor_metadata = false`, no ffi and no fs permissions. `lib/` vendors forge-std v1.10.0 and OpenZeppelin v5.4.0 as plain files, with no git metadata inside.\n\n**Verification results**\n\n- `forge build`, `forge test` with the verifier's fuzz seed and with an empty environment, and `forge fmt --check` all pass.\n- A scratch mirror of the protected floor passed: CREATE2 deploy from a factory stand-in leaves the whole supply on the factory, the ten percent swarm flow arrives and claims whole, no admin selector grows supply or moves a holder, and the reachable runtime contains no DELEGATECALL, CALLCODE or SELFDESTRUCT.\n- Runtime is 4,353 bytes and the artefact carries no metadata hash.\n\n**Notes**\n\n- No application contracts were requested, so none were added. Pool seeding and swaps could not be exercised locally since v4-core is the verifier's harness dependency, but the token has no transfer hooks, so those flows move exactly what they send.\n- Slither is not available on this machine. The contract has no custom logic that touches its rejected detectors.\n- I did not commit, since .git/ is off limits. All deliverables are ordinary files in the working tree, and the untracked dotfiles at the root are sandbox artefacts, not mine.","treeHash":"0eab3c023e28758f40752c2f770daa812b872704","usage":{"cachedInputTokens":641531,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":22210,"runtime":"claude","turns":24,"wallClockMs":273810}}],"verification":[{"checks":[{"durationMs":1343,"exitCode":0,"name":"build","output":"Compiling 43 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.25s\nCompiler run successful!\n","passed":true},{"durationMs":158,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 40 tests for test/MADToken.t.sol:MADTokenTest\n[PASS] testFuzz_burnOnlyShrinksSupply(uint256,uint256) (runs: 256, μ: 123684, ~: 124453)\nLogs:\n  Bound result 20532\n  Bound result 2506\n\n[PASS] testFuzz_strangerCannotMoveHolderBalance(address,uint256) (runs: 256, μ: 131188, ~: 131178)\nLogs:\n  Bound result 11345\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 86479, ~: 86700)\nLogs:\n  Bound result 260832638334696197851658946\n\n[PASS] testFuzz_transferFromOverAllowanceReverts(uint256,uint256) (runs: 256, μ: 95301, ~: 95729)\nLogs:\n  Bound result 4290\n  Bound result 50000000000000000000\n\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 141259, ~: 142751)\nLogs:\n  Bound result 436449953334820991001130904\n  Bound result 246685739064142433131664698\n\n[PASS] testFuzz_transferOverBalanceReverts(uint256) (runs: 256, μ: 41990, ~: 42315)\nLogs:\n  Bound result 115792089237316195423570985008687907853269984665639564039457584007945197004791\n\n[PASS] test_approveAndTransferFrom() (gas: 162223)\n[PASS] test_approveZeroSpenderReverts() (gas: 32950)\n[PASS] test_burnFromRevertsWithoutAllowance() (gas: 101266)\n[PASS] test_burnFromSpendsAllowance() (gas: 122827)\n[PASS] test_burnReducesSupplyAndBalance() (gas: 111939)\n[PASS] test_burnRevertsOverBalance() (gas: 35058)\n[PASS] test_constructorEmitsSingleMintTransfer() (gas: 8173)\n[PASS] test_constructorMintsToAContractDeployer() (gas: 129916)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 32703)\n[PASS] test_deployScriptMintsToItsCaller() (gas: 2535790)\n[PASS] test_deployerCannotPullFromHolderWithoutAllowance() (gas: 95385)\n[PASS] test_domainSeparatorBindsChainAndContract() (gas: 20246)\n[PASS] test_eachDeploymentIsIndependent() (gas: 33543)\n[PASS] test_maxAllowanceIsNotDecremented() (gas: 120579)\n[PASS] test_metadata() (gas: 53144)\n[PASS] test_noMintOrAdminEntryPointsExist() (gas: 586129)\n[PASS] test_permitCannotBeReplayed() (gas: 138012)\n[PASS] test_permitGrantsAllowanceAndBumpsNonce() (gas: 115928)\n[PASS] test_permitRevertsOnWrongSigner() (gas: 74974)\n[PASS] test_permitRevertsWhenExpired() (gas: 53272)\n[PASS] test_supplyConstantsAgree() (gas: 28263)\n[PASS] test_supplyNeverReturnsAfterBurn() (gas: 85022)\n[PASS] test_tokenRejectsEther() (gas: 38722)\n[PASS] test_transferDoesNotTaxAnyParty() (gas: 182526)\n[PASS] test_transferFromRevertsOverAllowance() (gas: 88044)\n[PASS] test_transferFromRevertsOverBalanceEvenWithAllowance() (gas: 91710)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 38499)\n[PASS] test_transferMovesExactAmount() (gas: 87037)\n[PASS] test_transferRevertsByOneWeiOverBalance() (gas: 38053)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 37885)\n[PASS] test_transferToSelfKeepsBalance() (gas: 40667)\n[PASS] test_transferToZeroAddressReverts() (gas: 32959)\n[PASS] test_transferWholeBalance() (gas: 72313)\n[PASS] test_transferZeroAmountSucceeds() (gas: 44510)\nSuite result: ok. 40 passed; 0 failed; 0 skipped; finished in 24.08ms (127.57ms CPU time)\n\nRan 1 test suite in 24.80ms (24.08ms CPU time): 40 tests passed, 0 failed, 0 skipped (40 total tests)\n","passed":true},{"durationMs":58,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MADToken.approve(address,uint256)\",\"MADToken.burn(uint256)\",\"MADToken.burnFrom(address,uint256)\",\"MADToken.permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\",\"MADToken.transfer(address,uint256)\",\"MADToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":146,\"foundry.toml\":26,\"launch.json\":24,\"remappings.txt\":2,\"script/DeployMADToken.s.sol\":25,\"src/MADToken.sol\":45,\"test/MADToken.t.sol\":467},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"6712a3824ea1040723705a8411499f0cb7da270087223e7484e9ff5b3e1e13fb","verifiedTreeHash":"2f80c87ec21395dfc01e97db5a1dcdcab5fd6aee","verifierVersion":"0.1.0+a6eb4461"},{"checks":[{"durationMs":3185,"exitCode":0,"name":"build","output":"Compiling 48 files with Solc 0.8.26\nSolc 0.8.26 finished in 3.06s\nCompiler run successful!\n","passed":true},{"durationMs":15226,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 41 tests for test/MADToken.t.sol:MADTokenTest\n[PASS] testFuzz_burnOnlyShrinksSupply(uint256,uint256) (runs: 1000, μ: 123863, ~: 124429)\nLogs:\n  Bound result 220660758995153043520304629\n  Bound result 146091846619247187419993243\n\n[PASS] testFuzz_strangerCannotMoveHolderBalance(address,uint256) (runs: 1000, μ: 131209, ~: 131146)\nLogs:\n  Bound result 63815621385447139051\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 1000, μ: 87036, ~: 87302)\nLogs:\n  Bound result 474227420035322036824613783267407375199928536775\n  Bound result 831068198934772901950617013\n\n[PASS] testFuzz_transferFromOverAllowanceReverts(uint256,uint256) (runs: 1000, μ: 95607, ~: 95705)\nLogs:\n  Bound result 4560\n  Bound result 14531\n\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 1000, μ: 141272, ~: 142727)\nLogs:\n  Bound result 830\n  Bound result 46\n\n[PASS] testFuzz_transferOverBalanceReverts(uint256) (runs: 1000, μ: 41944, ~: 42281)\nLogs:\n  Bound result 417787602777858907470090060623838060231824251134591391159388266697802\n\n[PASS] test_approveAndTransferFrom() (gas: 162179)\n[PASS] test_approveZeroSpenderReverts() (gas: 32950)\n[PASS] test_burnFromRevertsWithoutAllowance() (gas: 101311)\n[PASS] test_burnFromSpendsAllowance() (gas: 122827)\n[PASS] test_burnReducesSupplyAndBalance() (gas: 111939)\n[PASS] test_burnRevertsOverBalance() (gas: 35058)\n[PASS] test_constructorEmitsSingleMintTransfer() (gas: 8151)\n[PASS] test_constructorMintsToAContractDeployer() (gas: 129894)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 32681)\n[PASS] test_deployScriptMintsToItsCaller() (gas: 2535768)\n[PASS] test_deployerCannotPullFromHolderWithoutAllowance() (gas: 95472)\n[PASS] test_domainSeparatorBindsChainAndContract() (gas: 20334)\n[PASS] test_eachDeploymentIsIndependent() (gas: 33521)\n[PASS] test_maxAllowanceIsNotDecremented() (gas: 120557)\n[PASS] test_metadata() (gas: 53122)\n[PASS] test_noMintOrAdminEntryPointsExist() (gas: 586129)\n[PASS] test_permitCannotBeReplayed() (gas: 138035)\n[PASS] test_permitGrantsAllowanceAndBumpsNonce() (gas: 115906)\n[PASS] test_permitRevertsOnWrongSigner() (gas: 74952)\n[PASS] test_permitRevertsWhenExpired() (gas: 53250)\n[PASS] test_supplyConstantsAgree() (gas: 28263)\n[PASS] test_supplyNeverReturnsAfterBurn() (gas: 85022)\n[PASS] test_tokenRejectsEther() (gas: 38722)\n[PASS] test_transferConservationIncludesSelfRecipient() (gas: 56999)\nLogs:\n  Bound result 993628893877528486849555332510785747059138238790\n  Bound result 1000000000000000000000000000\n\n[PASS] test_transferDoesNotTaxAnyParty() (gas: 182504)\n[PASS] test_transferFromRevertsOverAllowance() (gas: 88089)\n[PASS] test_transferFromRevertsOverBalanceEvenWithAllowance() (gas: 91710)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 38565)\n[PASS] test_transferMovesExactAmount() (gas: 87015)\n[PASS] test_transferRevertsByOneWeiOverBalance() (gas: 38119)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 37885)\n[PASS] test_transferToSelfKeepsBalance() (gas: 40634)\n[PASS] test_transferToZeroAddressReverts() (gas: 32937)\n[PASS] test_transferWholeBalance() (gas: 72291)\n[PASS] test_transferZeroAmountSucceeds() (gas: 44488)\nSuite result: ok. 41 passed; 0 failed; 0 skipped; finished in 183.03ms (533.05ms CPU time)\n\nRan 18 tests for test/MADTokenPermit.t.sol:MADTokenPermitTest\n[PASS] testFuzz_modifyingAnySignedFieldInvalidatesPermit(uint256,uint8) (runs: 1000, μ: 194450, ~: 193959)\nLogs:\n  Bound result 1\n\n[PASS] testFuzz_permitAndApprovalReplaceRatherThanAccumulate(uint256,uint256) (runs: 1000, μ: 434571, ~: 434354)\n[PASS] testFuzz_permitAuthorizesExactlyTheSharedSpendingBudget(uint256,uint256,uint256) (runs: 1000, μ: 236517, ~: 239062)\nLogs:\n  Bound result 2454211\n  Bound result 903607\n\n[PASS] test_chainChangeRejectsOldSignatureAndAcceptsNewDomain() (gas: 334463)\n[PASS] test_domainIntrospectionMatchesSigningDomain() (gas: 21239)\n[PASS] test_expiredSignaturePreservesAllowanceAndNonce() (gas: 289312)\n[PASS] test_futureNonceMustWaitForPrecedingPermit() (gas: 356815)\n[PASS] test_highSSignatureIsRejectedWithoutConsumingNonce() (gas: 302627)\n[PASS] test_invalidRecoveryIdRollsBackNonce() (gas: 314558)\n[PASS] test_maximumPermitRemainsInfiniteForBothSpendingFunctions() (gas: 208193)\n[PASS] test_nonceIsPerOwnerAndSharedBetweenSpenders() (gas: 305507)\n[PASS] test_permitIsValidAtExactDeadlineAndEmitsApproval() (gas: 164907)\n[PASS] test_permitRevocationPreventsTransferAndBurn() (gas: 213439)\n[PASS] test_replayCannotRestoreARevokedAllowance() (gas: 220465)\n[PASS] test_signatureCannotBeReplayedOnAnotherDeployment() (gas: 323577)\n[PASS] test_validSignatureForZeroSpenderRevertsAndRollsBackNonce() (gas: 324596)\n[PASS] test_wrongSignerCannotConsumeNonceOrReplaceAllowance() (gas: 153228)\n[PASS] test_zeroOwnerCannotApproveWithEmptySignature() (gas: 167466)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 183.08ms (563.11ms CPU time)\n\nRan 21 tests for test/MADTokenEdges.t.sol:MADTokenEdgesTest\n[PASS] testFuzz_burnFromOverAllowanceIsAtomic(uint256,uint256) (runs: 1000, μ: 158754, ~: 158855)\nLogs:\n  Bound result 869456540942010790586518424\n  Bound result 913804213405924469855348067\n\n[PASS] testFuzz_directBurnCannotUseAnotherHoldersTokens(uint256,uint256) (runs: 1000, μ: 117754, ~: 118158)\nLogs:\n  Bound result 6072\n  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129635305\n\n[PASS] testFuzz_failedDelegatedSpendRestoresArbitraryFiniteAllowance(uint256,bool) (runs: 1000, μ: 163069, ~: 161609)\nLogs:\n  Bound result 115792089237316195423570985008687907853269984665639564039457584007913129662656\n\n[PASS] testFuzz_selfTransferStillChecksBalance(uint256) (runs: 1000, μ: 98452, ~: 98793)\nLogs:\n  Bound result 115792089237316195423570985008687907853269984665639564039457584007913129639946\n\n[PASS] testFuzz_splitTransfersAndBurnsConserveEveryWei(uint256,uint256,uint256) (runs: 1000, μ: 192573, ~: 192965)\nLogs:\n  Bound result 110357627248505572615856655\n  Bound result 44023092937299354876525738\n  Bound result 101487171576795565375469154\n\n[PASS] testFuzz_transferRoundTripHasNoFeeOrRounding(uint256,uint8) (runs: 1000, μ: 431931, ~: 370928)\nLogs:\n  Bound result 9\n  Bound result 3\n\n[PASS] test_allowanceIsSpecificToOwnerAndSpender() (gas: 310445)\n[PASS] test_approveReplacesAndRevokesWithoutChangingBalances() (gas: 293951)\n[PASS] test_constructorEmitsExactlyOneMint() (gas: 9469)\n[PASS] test_dustThenFullBurnLeavesAnEmptyTokenThatCannotBeSpent() (gas: 299977)\n[PASS] test_failedBurnFromRestoresAllowance() (gas: 222060)\n[PASS] test_failedTransferFromRestoresAllowance() (gas: 241633)\n[PASS] test_failedTransferToZeroRestoresAllowance() (gas: 155639)\n[PASS] test_holderNeedsAllowanceForDelegatedCallsToItself() (gas: 226347)\n[PASS] test_maximumFiniteAllowanceIsSpentButInfiniteAllowanceIsNot() (gas: 316039)\n[PASS] test_transferFromAndBurnFromShareOneAllowance() (gas: 233239)\n[PASS] test_transferFromToOwnerConsumesAllowanceWithoutMovingBalances() (gas: 154656)\n[PASS] test_uint256MaximumCannotWrapBalancesOrSupply() (gas: 240292)\n[PASS] test_zeroAmountDoesNotBypassZeroReceiverValidation() (gas: 121657)\n[PASS] test_zeroApprovalDoesNotBypassZeroSpenderValidation() (gas: 99465)\n[PASS] test_zeroOperationsWorkWithoutFundsOrApproval() (gas: 210815)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 183.15ms (1.08s CPU time)\n\nRan 2 tests for test/MADTokenInvariant.t.sol:MADTokenInvariantTest\n[PASS]\nMADTokenInvariantTest invariants:\n[PASS] invariant_allowancesAndNoncesMatchAuthorizedOperations\n[PASS] invariant_balancesMatchIndependentLedgerAndSumToSupply\n[PASS] invariant_supplyEqualsInitialSupplyMinusAuthorizedBurns\n MADTokenInvariantTest invariants (runs: 256, calls: 32768, reverts: 0)\n\n╭-----------------+--------------------+-------+---------+----------╮\n| Contract        | Selector           | Calls | Reverts | Discards |\n+===================================================================+\n| MADTokenHandler | advanceTime        | 2449  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | approve            | 2598  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | burn               | 2542  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | burnFrom           | 2533  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | permitAndReplay    | 2518  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | rejectAdminCall    | 2420  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | rejectOverBalance  | 2541  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | rejectPermit       | 2553  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | rejectUnauthorized | 2527  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | rejectZeroReceiver | 2533  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | roundTrip          | 2565  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | transfer           | 2521  | 0       | 0        |\n|-----------------+--------------------+-------+---------+----------|\n| MADTokenHandler | transferFrom       | 2468  | 0       | 0        |\n╰-----------------+--------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 3\n  Bound result 2\n  Bound result 10750\n  Bound result 2\n  Bound result 0\n  Bound result 2\n  Bound result 11795\n  Bound result 0\n  Bound result 0\n  Bound result 2\n  Bound result 2\n  Bound result 1\n  Bound result 3\n  Bound result 3\n  Bound result 2\n  Bound result 1\n  Bound result 2\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 2\n  Bound result 1\n  Bound result 3\n  Bound result 0\n  Bound result 8407\n  Bound result 2\n  Bound result 4\n  Bound result 1259\n  Bound result 1\n  Bound result 3955\n  Bound result 1\n  Bound result 0\n  Bound result 28\n  Bound result 544000\n  Bound result 1\n  Bound result 0\n  Bound result 8126\n  Bound result 1056000\n  Bound result 0\n  Bound result 3\n  Bound result 2827\n  Bound result 0\n  Bound result 3\n  Bound result 115792089237316195423570985008687907853269984665640314039457584007913129640928\n  Bound result 3\n  Bound result 3\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 179\n  Bound result 1\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 12924197971004627\n  Bound result 3\n  Bound result 2\n  Bound result 149261847193797762853232925\n  Bound result 2\n  Bound result 3\n  Bound result 0\n  Bound result 0\n  Bound result 711342883659342359424074255\n  Bound result 1\n  Bound result 1\n  Bound result 3\n  Bound result 1\n  Bound result 1039\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 249999999999999999999996041\n  Bound result 3\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 3\n  Bound result 3\n  Bound result 0\n  Bound result 3\n  Bound result 6\n  Bound result 2\n  Bound result 1\n  Bound result 1\n  Bound result 3\n  Bound result 638\n  Bound result 2\n  Bound result 3\n  Bound result 115792089237316195423570985008687907853269984665640463301304777805675982874732\n  Bound result 0\n  Bound result 2\n  Bound result 3\n  Bound result 11\n  Bound result 1\n  Bound result 0\n  Bound result 2\n  Bound result 2\n  Bound result 115792089237316195423570985008687907853269984665640164777610390210216949826386\n  Bound result 3\n  Bound result 3\n  Bound result 3\n  Bound result 0\n  Bound result 0\n  Bound result 2827\n  Bound result 0\n  Bound result 0\n  Bound result 659918\n  Bound result 3\n  Bound result 3\n  Bound result 100738152806202237146767075\n  Bound result 3\n  Bound result 0\n  Bound result 5\n  Bound result 0\n  Bound result 1\n  Bound result 3\n  Bound result 3\n  Bound result 2\n  Bound result 1\n  Bound result 0\n  Bound result 2\n  Bound result 1\n  Bound result 13\n  Bound result 0\n  Bound result 0\n  Bound result 121454482798792318183180696\n  Bound result 2519298\n  Bound result 3\n  Bound result 1\n  Bound result 2\n  Bound result 2887\n  Bound result 0\n  Bound result 3\n  Bound result 2\n  Bound result 115792089237316195423570985008687907853269984665640164777610390213245455793595\n  Bound result 3\n  Bound result 0\n  Bound result 0\n  Bound result 153266460195375165158895197\n  Bound result 0\n  Bound result 1\n  Bound result 51216615910171245916143981\n  Bound result 1\n  Bound result 3\n  Bound result 0\n  Bound result 2\n  Bound result 2\n  Bound result 3\n  Bound result 13899\n  Bound result 3\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 2\n  Bound result 0\n  Bound result 0\n  Bound result 3\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640365256073494179159045787263\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 430\n  Bound result 0\n  Bound result 2\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 775\n  Bound result 3\n  Bound result 3\n  Bound result 0\n  Bound result 3\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 3\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 4\n  Bound result 0\n  Bound result 3\n  Bound result 0\n  Bound result 2827\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 10750\n  Bound result 3\n  Bound result 0\n  Bound result 1\n  Bound result 7275\n  Bound result 1\n  Bound result 0\n  Bound result 6619\n  Bound result 2\n  Bound result 0\n  Bound result 7082526\n  Bound result 2\n  Bound result 0\n  Bound result 13\n  Bound result 3\n  Bound result 1\n  Bound result 526056007139814453535035460\n  Bound result 3\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640365256084494179159045779366\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 2\n  Bound result 2\n  Bound result 704629313983574\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 8183\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 2\n  Bound result 1\n  Bound result 1\n  Bound result 0\n  Bound result 15\n  Bound result 1\n  Bound result 3\n  Bound result 3\n  Bound result 2\n  Bound result 2\n  Bound result 1\n  Bound result 2\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 91948313017356537446988468\n  Bound result 3\n  Bound result 1\n  Bound result 0\n  Bound result 10869\n  Bound result 3\n  Bound result 2\n  Bound result 0\n  Bound result 0\n  Bound result 3\n  Bound result 308\n  Bound result 0\n  Bound result 1\n  Bound result 230\n  Bound result 1\n  Bound result 1\n  Bound result 3\n  Bound result 0\n  Bound result 1\n  Bound result 12\n  Bound result 0\n  Bound result 3\n  Bound result 0\n  Bound result 91948313017356537446988469\n  Bound result 3\n  Bound result 3\n  Bound result 0\n  Bound result 2\n  Bound result 2\n  Bound result 872957948294437473857967840\n  Bound result 2\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640365256073494179159045790263\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 2811\n  Bound result 2\n  Bound result 0\n  Bound result 684831254781382325029624772\n  Bound result 1\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 3\n  Bound result 0\n  Bound result 1429148\n  Bound result 2\n  Bound result 3\n  Bound result 1\n  Bound result 0\n  Bound result 3\n  Bound result 7000000000000000000\n  Bound result 3\n  Bound result 3\n  Bound result 1\n  Bound result 0\n  Bound result 3\n  Bound result 3\n  Bound result 1\n  Bound result 999999999999999999999999997\n  Bound result 3\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 2827\n  Bound result 0\n  Bound result 2\n  Bound result 1\n  Bound result 3\n\n[PASS] test_handlerExercisesMeaningfulStateTransitions() (gas: 2363800)\nLogs:\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 0\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 3\n  Bound result 3\n  Bound result 4\n  Bound result 0\n  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129639935\n  Bound result 0\n  Bound result 1\n  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129639935\n  Bound result 1\n  Bound result 2\n  Bound result 1000000000000000000000000000\n  Bound result 2\n  Bound result 3\n  Bound result 1000000000000000000000000000\n  Bound result 3\n  Bound result 0\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 3\n  Bound result 0\n  Bound result 1\n  Bound result 3\n  Bound result 0\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 1\n  Bound result 2\n  Bound result 3\n  Bound result 3\n  Bound result 2\n  Bound result 0\n  Bound result 1\n  Bound result 1\n  Bound result 2592000\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 15.06s (15.06s CPU time)\n\nRan 4 test suites in 15.07s (15.61s CPU time): 82 tests passed, 0 failed, 0 skipped (82 total tests)\n","passed":true},{"durationMs":75,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MADToken.approve(address,uint256)\",\"MADToken.burn(uint256)\",\"MADToken.burnFrom(address,uint256)\",\"MADToken.permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\",\"MADToken.transfer(address,uint256)\",\"MADToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":146,\"foundry.toml\":26,\"remappings.txt\":2,\"script/DeployMADToken.s.sol\":25,\"src/MADToken.sol\":45,\"test/MADToken.t.sol\":476,\"test/MADTokenEdges.t.sol\":309,\"test/MADTokenInvariant.t.sol\":116,\"test/MADTokenPermit.t.sol\":260,\"test/README.md\":63,\"test/handlers/MADTokenHandler.sol\":279,\"test/helpers/MADTokenTestBase.sol\":78},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"9540a21320705ed0d980fb6ebaacc078e4b3dd208b662be0d22833274490237a","verifiedTreeHash":"bf0e4652bd32bb382b32312fece76c06a723ca77","verifierVersion":"0.1.0+a6eb4461"},{"checks":[{"durationMs":1445,"exitCode":0,"name":"build","output":"Compiling 43 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.35s\nCompiler run successful!\n","passed":true},{"durationMs":146,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 40 tests for test/MADToken.t.sol:MADTokenTest\n[PASS] testFuzz_burnOnlyShrinksSupply(uint256,uint256) (runs: 256, μ: 123684, ~: 124453)\nLogs:\n  Bound result 4290\n  Bound result 624\n\n[PASS] testFuzz_strangerCannotMoveHolderBalance(address,uint256) (runs: 256, μ: 131188, ~: 131178)\nLogs:\n  Bound result 999999999999999999999999997\n\n[PASS] testFuzz_transferConservesSupply(address,uint256) (runs: 256, μ: 86479, ~: 86700)\nLogs:\n  Bound result 260832638334696197851658946\n\n[PASS] testFuzz_transferFromOverAllowanceReverts(uint256,uint256) (runs: 256, μ: 95301, ~: 95729)\nLogs:\n  Bound result 4290\n  Bound result 50000000000000000000\n\n[PASS] testFuzz_transferFromWithinAllowance(uint256,uint256) (runs: 256, μ: 141259, ~: 142751)\nLogs:\n  Bound result 436449953334820991001130904\n  Bound result 246685739064142433131664698\n\n[PASS] testFuzz_transferOverBalanceReverts(uint256) (runs: 256, μ: 41990, ~: 42315)\nLogs:\n  Bound result 115792089237316195423570985008687907853269984665639564039457617491025503589424\n\n[PASS] test_approveAndTransferFrom() (gas: 162223)\n[PASS] test_approveZeroSpenderReverts() (gas: 32950)\n[PASS] test_burnFromRevertsWithoutAllowance() (gas: 101266)\n[PASS] test_burnFromSpendsAllowance() (gas: 122827)\n[PASS] test_burnReducesSupplyAndBalance() (gas: 111939)\n[PASS] test_burnRevertsOverBalance() (gas: 35058)\n[PASS] test_constructorEmitsSingleMintTransfer() (gas: 8173)\n[PASS] test_constructorMintsToAContractDeployer() (gas: 129916)\n[PASS] test_constructorMintsWholeSupplyToDeployer() (gas: 32703)\n[PASS] test_deployScriptMintsToItsCaller() (gas: 2535790)\n[PASS] test_deployerCannotPullFromHolderWithoutAllowance() (gas: 95385)\n[PASS] test_domainSeparatorBindsChainAndContract() (gas: 20246)\n[PASS] test_eachDeploymentIsIndependent() (gas: 33543)\n[PASS] test_maxAllowanceIsNotDecremented() (gas: 120579)\n[PASS] test_metadata() (gas: 53144)\n[PASS] test_noMintOrAdminEntryPointsExist() (gas: 586129)\n[PASS] test_permitCannotBeReplayed() (gas: 138012)\n[PASS] test_permitGrantsAllowanceAndBumpsNonce() (gas: 115928)\n[PASS] test_permitRevertsOnWrongSigner() (gas: 74974)\n[PASS] test_permitRevertsWhenExpired() (gas: 53272)\n[PASS] test_supplyConstantsAgree() (gas: 28263)\n[PASS] test_supplyNeverReturnsAfterBurn() (gas: 85022)\n[PASS] test_tokenRejectsEther() (gas: 38722)\n[PASS] test_transferDoesNotTaxAnyParty() (gas: 182526)\n[PASS] test_transferFromRevertsOverAllowance() (gas: 88044)\n[PASS] test_transferFromRevertsOverBalanceEvenWithAllowance() (gas: 91710)\n[PASS] test_transferFromRevertsWithoutAllowance() (gas: 38499)\n[PASS] test_transferMovesExactAmount() (gas: 87037)\n[PASS] test_transferRevertsByOneWeiOverBalance() (gas: 38053)\n[PASS] test_transferRevertsOnInsufficientBalance() (gas: 37885)\n[PASS] test_transferToSelfKeepsBalance() (gas: 40667)\n[PASS] test_transferToZeroAddressReverts() (gas: 32959)\n[PASS] test_transferWholeBalance() (gas: 72313)\n[PASS] test_transferZeroAmountSucceeds() (gas: 44510)\nSuite result: ok. 40 passed; 0 failed; 0 skipped; finished in 17.16ms (127.82ms CPU time)\n\nRan 1 test suite in 17.88ms (17.16ms CPU time): 40 tests passed, 0 failed, 0 skipped (40 total tests)\n","passed":true},{"durationMs":67,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MADToken.approve(address,uint256)\",\"MADToken.burn(uint256)\",\"MADToken.burnFrom(address,uint256)\",\"MADToken.permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\",\"MADToken.transfer(address,uint256)\",\"MADToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":146,\"foundry.toml\":26,\"remappings.txt\":2,\"script/DeployMADToken.s.sol\":25,\"src/MADToken.sol\":45,\"test/MADToken.t.sol\":467},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":2311,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":992,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/MADToken.sol:28: Large Numeric Literal","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"dcd0e849a1cbdccbf02ce0671cdfaf48f6b4f21451a51ca7932ffbc19c0fac7a","verifiedTreeHash":"0eab3c023e28758f40752c2f770daa812b872704","verifierVersion":"0.1.0+a6eb4461"}]}