{"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":"545ed900-ef42-4381-9457-a275ce15b21e","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"c5b0a53b1161279b500a77b732eaf911e2d71ec2f64bf626e437e77893024f6e","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b037a7b6601e883cf8a906c1520c0624817d42d8310b65c2f43679204608af3","skillId":"adversarial-review","tools":[]},"key":"adversarial_review","kind":"code","role":"review","skillHash":"6b037a7b6601e883cf8a906c1520c0624817d42d8310b65c2f43679204608af3","skillId":"adversarial-review","state":"accepted"},{"acceptedSubmissionHash":"ffeb4148d3adaf3589cba0391948150d3d80c370a2c02e26ecc28e1ad07ffe02","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"816fe39c7efd64504a19175b0f4dd9186d61069f37a22684c90358a18c60bddc","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"816fe39c7efd64504a19175b0f4dd9186d61069f37a22684c90358a18c60bddc","skillId":"build-contract-project","state":"accepted"}],"objective":"Add the payer contract of this burn tracker to this repository: a Foundry project under contracts/ (its own foundry.toml, dependencies inside contracts/), with every other file unchanged (dist/, refresh/, package.json). The contract is BurnTracker, plus BurnTrackerTest, which inherits BurnTracker and adds nothing, because the first deployment is a test. A later launch from this repository deploys BurnTrackerTest on Ethereum mainnet with these constructor arguments: intake 0xa43e6f75ee006411f79ac1c84120606c2330de82, asset 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7, openAction \"job.open@job-1\" and continueAction \"job.continue@job-1\" as bytes32 strings, bodyPrefix and bodySuffix = the UTF-8 bytes of the continuation template before and after its {{PARENT}} placeholder, cooldown 86400, staleAfter 172800; the owner role goes to that launch's payer. No token, no pool, no other contracts.\n\nWHAT IT DOES. Its owner calls open(bytes body) once: the contract orders job.open@job-1 through IMD Intake v2 (0xa43e6f75ee006411f79ac1c84120606c2330de82) with that body, paying the Intake's live price in IMD (0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7) taken from the owner. That makes the contract the hosted site's payer; the plane accepts job.continue only from the address that paid the project, so only this contract can order later versions. After every completed version anyone may call updateBurntracker(bytes resultJson, uint256 maxPrice) with the result document (result.json) of the last completed job as its proof: the contract accepts the proof only if its keccak256 equals the result hash the Intake handed to onResult for that completion, reads the parent job id from it, and orders job.continue@job-1 with its stored body template around that id, paid by the caller at the live price, never above maxPrice (a higher price reverts before any token moves). Callers supply only this proof and cannot change what the swarm is asked to do.\n\nINTERFACE (exact; existing tools call it): open(bytes) returns (bytes32 requestId); updateBurntracker(bytes,uint256) returns (bytes32); recover(string parentJobId) returns (bytes32); setResultHash(bytes32); onResult(bytes32 requestId, bytes32 resultHash, string uri); onFailure(bytes32 requestId, uint8 status, bytes32 reason, uint16, uint16, bytes); parentJobIdOf(bytes) pure returns (bytes); views price() and nextUpdateAt(); status() returns (uint8 state, uint8 pendingKind, uint40 lastDone, uint40 orderedAt, uint40 staleAt, uint32 cooldown, uint32 staleAfter); public owner, intake, asset, openAction, continueAction, bodyPrefix, bodySuffix, resultHash, lastRequestId; owner-only setBody(bytes,bytes), setActions(bytes32,bytes32), setIntake(address,address), setTiming(uint32,uint32), withdraw(address token, address to, uint256 amount), two-step transferOwnership and acceptOwnership; events Ordered(bytes32 indexed requestId, uint8 kind, address indexed payer, uint256 amount, string parentJobId), Updated(bytes32 indexed requestId, bytes32 resultHash, string uri), Failed(bytes32 indexed requestId, uint8 status, bytes32 reason, uint8 newState). States UNOPENED 1, IDLE 2, PENDING 3, STUCK 4; kinds open 1, continue 2, recover 3.\n\nRULES. One order at a time. updateBurntracker needs IDLE and the cooldown passed since the last completion. Callbacks count only from the Intake, only for the order awaited, only once. onResult stores the hash, returns to IDLE and restarts the cooldown. onFailure status 1 (refused): a refused update returns to IDLE and restarts the cooldown, a refused open returns to UNOPENED, a refused recover goes to STUCK; status 2 (failed) goes to STUCK. open() is allowed again after the hosting job failed (STUCK) or stayed pending past its stale time. Blocked jobs never call back, so once an order has been pending past staleAfter (fixed when it is placed), or in IDLE or STUCK, the owner may recover(jobId), a continuation of the job it names paid by the owner, or setResultHash(hash) to adopt a completion whose callback was lost. A callback for an order no longer awaited is refused. cooldown 1 hour to 30 days, staleAfter 1 hour to 30 days.\n\nMEASURED FACTS (do not adapt them away): the Intake calls back with exactly 200,000 gas, and since Glamsterdam a storage slot written from zero costs about 111,000 of it, so every slot a callback writes must already be nonzero from the constructor on. result.json is canonical key-sorted JSON whose keccak256 is the hash onResult receives, 750 to 4,545 bytes, with the key \"jobId\" exactly once and a lowercase UUID as its value; the contract rejects a document without exactly one such key or with a malformed id. The launch's empty-chain check deploys only this contract, so the constructor must not require code at the Intake or the token.\n\nDECIDE, DO NOT ASK: a question blocks the job and costs the payer; where this text is silent, choose and report it.","parentJobId":"6889442f-768a-4b4f-b0c3-5d281269839f","planHash":"2017689ad1518d3f41bfc59b39e348f0d0976239db1641eb72ac6cb0218f6cc0","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"6889442f-768a-4b4f-b0c3-5d281269839f","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2523-port-imd-burn-tracker-s"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51154","feedbackHash":"826ce1779f5df877d029fa44db39d7c27d6424ad73c1e74ffbdc8a4351dc52f5","nodeKey":"adversarial_review","submissionHash":"c5b0a53b1161279b500a77b732eaf911e2d71ec2f64bf626e437e77893024f6e","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51731","feedbackHash":"1edec43ab3bef2db11219924aee36394b67e33e7a8102f508af2d38bb19c7621","nodeKey":"build_contract_project","submissionHash":"ffeb4148d3adaf3589cba0391948150d3d80c370a2c02e26ecc28e1ad07ffe02","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"455f531b4ede274b8b1272d0dfc01f2a55d5d1612fb9c49a264f41896690e654","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"27168b1ff68f84d2","findings":[{"citation":"resolved","description":"The objective allows open() again only 'after the hosting job failed (STUCK) or stayed pending past its stale time'. _isStale() does not look at pendingKind, so after any PENDING order has passed staleAt the owner may call open(). For a stale job.continue that is slow but still running, this orders a second job.open: the owner pays the open price for a brand-new project, lastRequestId moves to the new order, and the continuation's later onResult is refused as UnexpectedCallback, so its completion hash is lost and the hosted project's lineage splits. The owner is the only actor and pays with their own IMD, so this is a spec deviation and foot-gun, not an exploit. The same line also lets open() run from STUCK reached by a failed update or recover (exercised deliberately by test_FailedUpdateAndRecoverGoStuck), which creates a second project rather than repairing the first; recover()/setResultHash() are the intended tools there.","line":131,"path":"contracts/src/BurnTracker.sol","reproduction":"State: IDLE with a valid proof; alice calls updateBurntracker(proof, 0.5e18) -> PENDING kind 2. Warp 172800 s (staleAfter). Owner calls open(OPEN_BODY): expected InvalidState (pending order is not the hosting job); actual: succeeds, owner is charged 0.5 IMD, status().pendingKind == 1, and the Intake's later onResult(oldId, hash, uri) reverts UnexpectedCallback. See contracts/test/scratch/Review.t.sol testOpenAllowedAfterStaleContinue (passes on current code, demonstrating the behaviour).","severity":"low","snippet":"        if (state != UNOPENED && state != STUCK && !_isStale()) revert InvalidState();","title":"open() is accepted while a stale CONTINUE or RECOVER order is pending, not only a stale hosting job"},{"citation":"resolved","description":"_checkRecoverable accepts STUCK regardless of how it was reached. After the first open() fails with status 2 the contract is STUCK but has never paid for a project, so this address is nobody's payer. recover(anyUuid) then orders job.continue paid by the owner; the plane must refuse it (admission_refused) because the payer never opened a project, the price is spent, and the refused recover returns to STUCK. setResultHash from this state moves to IDLE and lets third parties pay for the same refused continuation. Only the owner can trigger this and the loss is the owner's (and, after setResultHash, any caller's) 0.5 IMD per attempt; the constructor-time guard for UNOPENED shows the authors intended to block recovery before a project exists.","line":380,"path":"contracts/src/BurnTracker.sol","reproduction":"Fresh deployment. Owner open(body) -> id; Intake calls onFailure(id, 2, 'failed', 0, 0, '') -> state STUCK. Owner calls recover('4c5dbeb7-9acb-4a64-b204-9f55e6d78ada'): expected InvalidState (nothing to continue); actual: succeeds and 0.5 IMD leaves the owner for an order the plane refuses. See contracts/test/scratch/Review.t.sol testRecoverAllowedWhenNeverOpened.","severity":"low","snippet":"        if (_status.state != IDLE && _status.state != STUCK && !_isStale()) revert InvalidState();","title":"recover() and setResultHash() are allowed from STUCK reached by a failed open(), when no project exists yet"},{"citation":"resolved","description":"setResultHash is a documented owner power (adopt a completion whose callback was lost) and is correctly restricted to IDLE, STUCK or stale-pending. Its hash is unverified by construction, so an owner who adopts the hash of any JSON containing one 'jobId' key (an old document, or a document for a job this contract never paid for) makes every subsequent updateBurntracker a refused order: each caller loses the live price and the refusal returns to IDLE with the same proof, so it repeats once per cooldown until the owner acts. This is within the agreed design (the owner is trusted and verifies the parent off chain); it is recorded so the operator knows that callers' funds, not only the owner's, ride on that off-chain verification. No code change is required for the agreed scope; an optional mitigation that preserves the design is for the hosted site to refuse to submit when the adopted hash does not match the newest result.json it can fetch.","line":162,"path":"contracts/src/BurnTracker.sol","reproduction":"IDLE after a real completion with resultHash H1. Owner calls setResultHash(keccak256('{\"jobId\":\"00000000-0000-0000-0000-000000000000\"}')). Warp past nextUpdateAt. alice calls updateBurntracker(that document, 0.5e18): accepted on chain, 0.5 IMD spent, plane refuses (parent not in this payer's project), onFailure(id,1,...) returns to IDLE; bob repeats the loss after the next cooldown.","severity":"info","snippet":"    function setResultHash(bytes32 hash) external onlyOwner nonReentrant {","title":"Trust observation: setResultHash lets the owner redirect third-party payments to a continuation the plane will refuse"}],"hash":"c5b0a53b1161279b500a77b732eaf911e2d71ec2f64bf626e437e77893024f6e","nodeId":"a8448483-4eb6-48ea-8136-3f19490f253a","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds three findings plus a 30-row coverage record. No file under `contracts/` was changed; the scratch tests I used were removed.\n\n**Answers to the five questions**\n\n- **Order a job the owner did not define:** No. The only non-owner path is `updateBurntracker`. The body it sends is the owner's prefix, a 36-byte lowercase UUID, and the owner's suffix. The UUID alphabet cannot close the JSON string, and the proof document is pinned by its keccak256 against the hash the Intake delivered. The parser counts `jobId` keys everywhere and rejects duplicates, escapes, and malformed ids. Real documents from mainnet are used as fixtures.\n- **Pay more than the live price:** No. The price is read first, `PriceTooHigh` reverts before any token call, and the order path checks that exactly that amount left the caller and nothing stays approved or held. Confirmed by a scratch test with the price raised by one wei.\n- **Lose a payment to a job the plane must refuse:** Not through any third-party action. A second caller in the same block reverts before paying. The paths that can send money to a refused order are owner-only and are my two low findings.\n- **Block updates for good:** No. Foreign requests naming this contract as callback carry a different request id and are refused. Every pending state expires at the fixed stale time, after which the owner can recover or adopt a hash. STUCK requires a real failure callback from the awaited request.\n- **Make a callback run out of gas:** No. Both callbacks write only `resultHash`, preset to 1, and the single packed status slot, which stays nonzero for life. The existing gas tests record every write under a real 200,000 gas call and a 4 KiB URI.\n\n**Findings, by severity**\n\n1. **Low.** `open()` at `contracts/src/BurnTracker.sol:131` is allowed after any stale pending order, not only a stale hosting job, and from STUCK of any cause. The owner can orphan a slow-but-running continuation and pay for a second project. Reproduced: update, warp past staleAfter, owner open succeeds and the old completion is then refused.\n2. **Low.** `recover()` and `setResultHash()` at line 380 are accepted from STUCK reached by a failed first `open()`, when no project exists. The owner pays for a continuation the plane must refuse. Reproduced.\n3. **Info.** Trust observation on `setResultHash`: an owner who adopts a non-completion hash turns every later third-party update into a refused order that repeats once per cooldown. Within the agreed design, recorded for the operator.\n\nNothing at medium or above was found, so no proof tests were attached. The static analysis leads for the contract were checked: the \"ETH send\" flag on line 137 is a false positive on an ERC-20 pull, and the centralization items are the documented owner role.","treeHash":null,"usage":{"cachedInputTokens":398421,"inputTokens":194,"model":"claude-fable-5-1","outputTokens":20451,"runtime":"claude","turns":13,"wallClockMs":385752}},{"artifacts":[],"attempt":1,"bundleHash":"2b793dd7dc8ca40d0fc5c9004075b67ca3177afbf0f955a378538080472e30da","device":"6960837f8e61d811","findings":[],"hash":"ffeb4148d3adaf3589cba0391948150d3d80c370a2c02e26ecc28e1ad07ffe02","nodeId":"2eb06b44-2bc6-4336-9264-a45c850b2467","outcome":"completed","summary":"Repaired both reported failures.\n\n- `forge build` and `forge fmt --check` pass.\n- 66 offline tests pass in both compiler modes; both mainnet-fork tests pass.\n- 4,545-byte update: **287,984 gas** on the fork; **299,240 gas** unoptimized.\n- Complete runtime bytecode matches under the pinned settings.\n\nChanges stay within `contracts/`. Build configuration, dependencies, and site files are unchanged. Verification and deployment notes are updated.","treeHash":"0737d5b8449a6af327313d39f061ff2b226d862c","usage":{"cachedInputTokens":10340224,"inputTokens":295230,"model":"gpt-6-astra","outputTokens":106509,"runtime":"codex","turns":19,"wallClockMs":3034752}}],"verification":[{"checks":[{"durationMs":1470,"exitCode":0,"name":"build","output":"Compiling 48 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.37s\nCompiler run successful!\n","passed":true},{"durationMs":255,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for contracts/test/UpdateGas.t.sol:UpdateGasTest\n[PASS] test4545ByteRealProofUnder300000ExecutionGasOffline() (gas: 1238823)\nLogs:\n  4545-byte proof execution gas with protocol mock: 299240\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.00ms (529.73µs CPU time)\n\nRan 1 test for contracts/test/fork/MainnetFork.t.sol:MainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 2.55ms (0.00ns CPU time)\n\nRan 2 tests for contracts/test/CallbackGas.t.sol:CallbackGasTest\n[PASS] testAllFailureKindsAndStatusesWriteOnlyPreexistingSlotsWithinStipend() (gas: 56764380)\nLogs:\n  cold callback gas including call overhead: 37448\n  cold callback gas including call overhead: 37985\n  cold callback gas including call overhead: 37656\n  cold callback gas including call overhead: 37223\n  cold callback gas including call overhead: 37223\n  cold callback gas including call overhead: 37223\n\n[PASS] testFirstAndSubsequentResultsWriteOnlyPreexistingSlotsWithinStipend() (gas: 839223)\nLogs:\n  cold callback gas including call overhead: 42567\n  cold callback gas including call overhead: 90143\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 16.80ms (17.99ms CPU time)\n\nRan 9 tests for contracts/test/Administration.t.sol:AdministrationTest\n[PASS] testAllAdministrationAndManualActionsAreOwnerOnly() (gas: 281416)\n[PASS] testBodyBoundsAndMalformedRecoveryParent() (gas: 4308937)\n[PASS] testConfigurationIsUsedForFutureOrders() (gas: 4098111)\n[PASS] testConstructorRejectsInvalidParameters() (gas: 6911991)\n[PASS] testFuzzTimingRange(uint32,uint32) (runs: 256, μ: 41739, ~: 41476)\n[PASS] testOwnershipRequiresNewOwnerAcceptanceAndCanReplaceNominee() (gas: 528199)\n[PASS] testRejectsZeroAddressesAndActions() (gas: 235640)\n[PASS] testTimingBoundsInclusiveAndCurrentCooldownChangesImmediately() (gas: 541641)\n[PASS] testWithdrawOnlyMovesNamedTokenAndAmount() (gas: 144199)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 48.70ms (54.41ms CPU time)\n\nRan 36 tests for contracts/test/BurnTracker.t.sol:BurnTrackerBehaviorTest\n[PASS] testAStaleButNotAbandonedOrderCanStillComplete() (gas: 336821)\n[PASS] testAnOlderCompletedProofCannotBeReusedAfterANewCompletion() (gas: 1001619)\n[PASS] testAuthenticatedDuplicateAndEscapedFakeKeysCannotOrder() (gas: 470597)\n[PASS] testBalanceReadRejectsShortReturnAndBubblesTokenRevert() (gas: 403891)\n[PASS] testCannotRecoverOrAdoptBeforeOpeningOrAdoptZero() (gas: 436873)\n[PASS] testConstructorWorksOnEmptyChainAndUsesExplicitOwner() (gas: 5610836)\n[PASS] testCooldownInclusiveBoundaryAndRestartsAtCompletion() (gas: 717704)\n[PASS] testEventsExposeOrderCompletionAndFailure() (gas: 657325)\n[PASS] testExactLaunchTemplateMatchesPinnedBytes() (gas: 5968)\n[PASS] testFeeTokenCannotSpendPreviouslyDonatedTokens() (gas: 221735)\n[PASS] testHashMatchedInvalidJsonStillCannotOrder() (gas: 373837)\n[PASS] testIntakeOrTokenRevertRollsBackWholeOrder() (gas: 389393)\n[PASS] testNonReturningAndZeroFirstApprovalToken() (gas: 377082)\n[PASS] testOneOrderAtATimeAndOpenUnavailableWhenIdle() (gas: 529421)\n[PASS] testOpenAfterStaleOrderRejectsLateCallback() (gas: 610533)\n[PASS] testOpenPaysOwnerLivePriceAndRegistersTrackerAsPayer() (gas: 443487)\n[PASS] testPaymentRejectsMalformedTokenReturnsAndBubblesTransferRevert() (gas: 585933)\n[PASS] testPendingOrderKeepsOriginalIntakeAuthentication() (gas: 2586133)\n[PASS] testPriceCeilingRevertsBeforeAnyTokenCall() (gas: 495927)\n[PASS] testRealDocumentsMatchOnchainHashesParseAndAuthorizeProofs() (gas: 4222093)\n[PASS] testRecoverFromIdleIgnoresCooldownAndUsesOwnerPayment() (gas: 727021)\n[PASS] testRecoverOnlyAfterFixedStaleDeadlineAndRejectsOldCallbacks() (gas: 754944)\n[PASS] testRefusedOpenReturnsToUnopenedAndCanRetry() (gas: 629191)\n[PASS] testRefusedRecoverGoesStuck() (gas: 712746)\n[PASS] testRefusedUpdateRestartsCooldownAndKeepsLastProof() (gas: 1000065)\n[PASS] testRejectedApprovalRollsBackPulledTokens() (gas: 430271)\n[PASS] testSetResultHashFromStalePendingIdleAndStuck() (gas: 1084896)\n[PASS] testTestDeploymentHasIdenticalRuntimeBytecode() (gas: 5593775)\n[PASS] testTokenReentrancyAndSynchronousCallbackCannotSettle() (gas: 965010)\n[PASS] testUpdateAuthenticatesProofPaysExactlyLivePriceAndUsesExactTemplate() (gas: 787737)\n[PASS] testWrongProofAndAnyByteChangeAreRejected() (gas: 433594)\n[PASS] testWrongSenderUnknownAndDuplicateCallbacksRejected() (gas: 512349)\n[PASS] testZeroPriceCannotMoveTokens() (gas: 664966)\n[PASS] test_FailedHostingJobAllowsNewOpen() (gas: 615637)\n[PASS] test_FailedUpdateAndRecoverGoStuck() (gas: 1236056)\n[PASS] test_FailureConsumesCallbackOnceAndInvalidStatusDoesNot() (gas: 481602)\nSuite result: ok. 36 passed; 0 failed; 0 skipped; finished in 55.91ms (34.78ms CPU time)\n\nRan 18 tests for contracts/test/Parser.t.sol:ParserTest\n[PASS] testAuthenticatedReaderIgnoresTrailingCalldataOutsideDocument() (gas: 17333)\n[PASS] testAuthenticatedReaderMatchesStrictReaderOnEveryRealDocument() (gas: 1381748)\n[PASS] testAuthenticatedReaderRejectsMissingDuplicateAndMalformedKeys() (gas: 68385)\n[PASS] testBoundsAndDepthCannotExhaustUnboundedGas() (gas: 204205)\n[PASS] testEscapedQuotesAndBackslashesCannotForgeKeys() (gas: 99932)\n[PASS] testEveryTruncationOfRealDocumentIsRejected() (gas: 114242434)\n[PASS] testFuzzArbitraryInputNeverPanics(bytes) (runs: 256, μ: 22572, ~: 11664)\n[PASS] testFuzzAuthenticatedReaderCountsDuplicateKeys(bytes16,uint8) (runs: 256, μ: 53418, ~: 47898)\n[PASS] testFuzzMalformedUuidCharacter(bytes16,uint8) (runs: 256, μ: 46334, ~: 46334)\n[PASS] testFuzzValidUuidAndEscapedValue(bytes16,uint8) (runs: 256, μ: 81874, ~: 75737)\n[PASS] testFuzzWordScannerAcrossChunkBoundariesAndBorrowCandidates(bytes16,uint16) (runs: 256, μ: 327235, ~: 163005)\n[PASS] testMalformedGrammarRejected() (gas: 333732)\n[PASS] testMalformedUuidRejected() (gas: 138391)\n[PASS] testMissingDuplicateNestedDuplicateAndWrongTypeRejected() (gas: 177787)\n[PASS] testStringValueNamedJobIdIsNotAKey() (gas: 35536)\n[PASS] testUuidClassifierEveryByteAtEveryPosition() (gas: 12255739)\n[PASS] testUuidClassifierIgnoresMemoryPadding() (gas: 4172)\n[PASS] testValidNestedJsonWhitespaceEscapesNumbersAndUnicode() (gas: 50052)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 118.25ms (255.78ms CPU time)\n\nRan 6 test suites in 120.35ms (244.22ms CPU time): 66 tests passed, 0 failed, 1 skipped (67 total tests)\n","passed":true},{"durationMs":117,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"BurnTracker.acceptOwnership()\",\"BurnTracker.onFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"BurnTracker.onResult(bytes32,bytes32,string)\",\"BurnTracker.open(bytes)\",\"BurnTracker.recover(string)\",\"BurnTracker.setActions(bytes32,bytes32)\",\"BurnTracker.setBody(bytes,bytes)\",\"BurnTracker.setIntake(address,address)\",\"BurnTracker.setResultHash(bytes32)\",\"BurnTracker.setTiming(uint32,uint32)\",\"BurnTracker.transferOwnership(address)\",\"BurnTracker.updateBurntracker(bytes,uint256)\",\"BurnTracker.withdraw(address,address,uint256)\",\"BurnTrackerTest.acceptOwnership()\",\"BurnTrackerTest.onFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"BurnTrackerTest.onResult(bytes32,bytes32,string)\",\"BurnTrackerTest.open(bytes)\",\"BurnTrackerTest.recover(string)\",\"BurnTrackerTest.setActions(bytes32,bytes32)\",\"BurnTrackerTest.setBody(bytes,bytes)\",\"BurnTrackerTest.setIntake(address,address)\",\"BurnTrackerTest.setResultHash(bytes32)\",\"BurnTrackerTest.setTiming(uint32,uint32)\",\"BurnTrackerTest.transferOwnership(address)\",\"BurnTrackerTest.updateBurntracker(bytes,uint256)\",\"BurnTrackerTest.withdraw(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"README.md\":14,\"contracts/.gitignore\":3,\"contracts/LICENSE\":21,\"contracts/README.md\":114,\"contracts/VERIFICATION.md\":89,\"contracts/continuation-template.json\":1,\"contracts/foundry.toml\":20,\"contracts/script/LaunchParameters.sol\":24,\"contracts/script/embed-fixtures.py\":34,\"contracts/src/BurnTracker.sol\":398,\"contracts/src/BurnTrackerTest.sol\":23,\"contracts/src/interfaces/IIntake.sol\":20,\"contracts/src/libraries/ResultJson.sol\":391,\"contracts/test/Administration.t.sol\":182,\"contracts/test/BurnTracker.t.sol\":620,\"contracts/test/CallbackGas.t.sol\":80,\"contracts/test/Parser.t.sol\":245,\"contracts/test/UpdateGas.t.sol\":24,\"contracts/test/fixtures/08f07d6f.json\":1,\"contracts/test/fixtures/1bcce3a7.json\":1,\"contracts/test/fixtures/1d29e49a.json\":1,\"contracts/test/fixtures/9381ffcc.json\":1,\"contracts/test/fixtures/9624f208.json\":1,\"contracts/test/fixtures/99d8dd2d.json\":1,\"contracts/test/fixtures/b7d61120.json\":1,\"contracts/test/fixtures/provenance.json\":86,\"contracts/test/fixtures/template-preflight-completed-parent.json\":1,\"contracts/test/fixtures/template-preflight.json\":1,\"contracts/test/fork/MainnetFork.t.sol\":147,\"contracts/test/helpers/Mocks.sol\":166,\"contracts/test/helpers/RealResults.sol\":63,\"contracts/test/helpers/ResultReaderHarness.sol\":10,\"contracts/test/helpers/TrackerFixture.sol\":93,\"contracts/test/helpers/UpdateCaller.sol\":22,\"contracts/vendor/forge-std/LICENSE-APACHE\":203,\"contracts/vendor/forge-std/LICENSE-MIT\":25,\"contracts/vendor/forge-std/src/Base.sol\":42,\"contracts/vendor/forge-std/src/Script.sol\":28,\"contracts/vendor/forge-std/src/StdAssertions.sol\":685,\"contracts/vendor/forge-std/src/StdChains.sol\":286,\"contracts/vendor/forge-std/src/StdCheats.sol\":829,\"contracts/vendor/forge-std/src/StdConstants.sol\":30,\"contracts/vendor/forge-std/src/StdError.sol\":15,\"contracts/vendor/forge-std/src/StdInvariant.sol\":122,\"contracts/vendor/forge-std/src/StdJson.sol\":277,\"contracts/vendor/forge-std/src/StdMath.sol\":43,\"contracts/vendor/forge-std/src/StdStorage.sol\":473,\"contracts/vendor/forge-std/src/StdStyle.sol\":333,\"contracts/vendor/forge-std/src/StdToml.sol\":277,\"contracts/vendor/forge-std/src/StdUtils.sol\":209,\"contracts/vendor/forge-std/src/Test.sol\":34,\"contracts/vendor/forge-std/src/Vm.sol\":2369,\"contracts/vendor/forge-std/src/console.sol\":1552,\"contracts/vendor/forge-std/src/console2.sol\":4,\"contracts/vendor/forge-std/src/interfaces/IERC1155.sol\":105,\"contracts/vendor/forge-std/src/interfaces/IERC165.sol\":12,\"contracts/vendor/forge-std/src/interfaces/IERC20.sol\":43,\"contracts/vendor/forge-std/src/interfaces/IERC4626.sol\":190,\"contracts/vendor/forge-std/src/interfaces/IERC6909.sol\":72,\"contracts/vendor/forge-std/src/interfaces/IERC721.sol\":164,\"contracts/vendor/forge-std/src/interfaces/IERC7540.sol\":144,\"contracts/vendor/forge-std/src/interfaces/IERC7575.sol\":241,\"contracts/vendor/forge-std/src/interfaces/IMulticall3.sol\":70,\"contracts/vendor/forge-std/src/safeconsole.sol\":13937,\"contracts/vendor/openzeppelin/LICENSE\":22,\"contracts/vendor/openzeppelin/contracts/token/ERC20/IERC20.sol\":79,\"contracts/vendor/openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":83,\"contracts/vendor/openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":118,\"contracts/vendor/openzeppelin/contracts/utils/Address.sol\":159,\"dist/d3.v7.9.0.min.js\":2,\"dist/data/imd-base-split.json\":16,\"dist/data/imd-burn-breakdown.json\":34,\"dist/data/imd-burn-coins.json\":2618,\"dist/data/imd-burn-history.json\":1,\"dist/data/imd-burnkeepers.json\":167,\"dist/data/imd-burns.json\":44,\"dist/data/imd-executor-bridges.json\":713,\"dist/data/imd-executor-sources.json\":92,\"dist/data/imd-refresh-status.json\":9,\"dist/data/imd-supply.json\":15,\"dist/fonts.css\":4,\"dist/index.html\":1065,\"package.json\":11,\"refresh/PORT.md\":194,\"refresh/check.mjs\":240,\"refresh/compare.mjs\":43,\"refresh/keccak.mjs\":50,\"refresh/refresh.mjs\":564,\"refresh/refresh_imd.py\":550},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":388,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":3701,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at contracts/vendor/forge-std/src/StdChains.sol:76: `abi.encodePacked()` Hash Collision (16 places)\n[high] eth-send-unchecked-address at contracts/src/BurnTracker.sol:137: ETH transferred without address checks\n[high] experimental-encoder at contracts/vendor/forge-std/src/StdAssertions.sol:3: Experimental ABI Encoder (9 places)\n[high] incorrect-shift-order at contracts/vendor/forge-std/src/StdStorage.sol:320: Incorrect Assembly Shift Parameter Order\n[high] reused-contract-name at contracts/vendor/forge-std/src/interfaces/IERC20.sol:6: Contract Name Reused in Different Files (2 places)\n[high] storage-array-memory-edit at contracts/vendor/forge-std/src/StdStorage.sol:37: Storage Array Edited with Memory\n[high] tautology-or-contradiction at contracts/vendor/forge-std/src/StdStorage.sol:126: Tautology or Contradiction in comparison\n[low] boolean-equality at contracts/vendor/forge-std/src/StdCheats.sol:222: Boolean equality is not required (2 places)\n[low] centralization-risk at contracts/src/BurnTracker.sol:129: Centralization Risk (9 places)\n[low] internal-function-used-once at contracts/vendor/forge-std/src/StdAssertions.sol:75: Internal Function Used Only Once (52 places)\n[low] literal-instead-of-constant at contracts/src/BurnTracker.sol:132: Literal Instead of Constant (724 places)\n[low] non-reentrant-not-first at contracts/src/BurnTracker.sol:129: `nonReentrant` is Not the First Modifier (9 places)\n[low] redundant-statement at contracts/vendor/forge-std/src/StdCheats.sol:827: Redundant Statement\n[low] state-variable-could-be-constant at contracts/vendor/forge-std/src/Script.sol:27: State Variable Could Be Constant (3 places)\n[low] unchecked-return at contracts/vendor/forge-std/src/StdStorage.sol:417: Unchecked Return\n[low] unsafe-erc20-operation at contracts/vendor/openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol:37: Unsafe ERC20 Operation (4 places)\n[low] unspecific-solidity-pragma at contracts/vendor/forge-std/src/Base.sol:2: Unspecific Solidity Pragma (21 places)\n[low] unused-import at contracts/vendor/forge-std/src/Script.sol:8: Unused Import (23 places)\n[low] unused-public-function at contracts/src/BurnTracker.sol:194: Public Function Not Used Internally","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"ffeb4148d3adaf3589cba0391948150d3d80c370a2c02e26ecc28e1ad07ffe02","verifiedTreeHash":"0737d5b8449a6af327313d39f061ff2b226d862c","verifierVersion":"0.1.0+ad64f8c4"}]}