{"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":"59146633-2425-4a48-8310-456019e2d15e","kind":"impl_tests_review","nodes":[{"acceptedSubmissionHash":"f7c6def6a1d9ebdf14de127a19bcc4d4e65e174f781050471ed1d41091ff793d","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d37537abb20af46832b24602788d7895021ecaac20c6934313dc4f8aba4ad047","skillId":"implement-contract","tools":[]},"key":"impl","kind":"code","role":"implement","skillHash":"d37537abb20af46832b24602788d7895021ecaac20c6934313dc4f8aba4ad047","skillId":"implement-contract","state":"accepted"},{"acceptedSubmissionHash":"4d15c04bbdce8efa7c3c57d238e4a472e49acbde65acd4bfff0a9c1ed93c4986","dependsOn":["impl","tests"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"c26edc76dc7a76e09a42c3634054429c1679c6e247747d647a03f77e5b332d7e","skillId":"adversarial-review","tools":[]},"key":"review","kind":"code","role":"review","skillHash":"c26edc76dc7a76e09a42c3634054429c1679c6e247747d647a03f77e5b332d7e","skillId":"adversarial-review","state":"accepted"},{"acceptedSubmissionHash":"469bf7b9231747a84b23ac790e1eab6c3cf99f8defcfa184b06ef8167b22ea9f","dependsOn":["impl"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"5891004c5c81aca68ad1dcc551c7bc98f3ec10c61fce5561aee8956a26e95588","skillId":"write-foundry-tests","tools":[]},"key":"tests","kind":"code","role":"tests","skillHash":"5891004c5c81aca68ad1dcc551c7bc98f3ec10c61fce5561aee8956a26e95588","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Build the Pledge contract project, based on the HabitPledge concept: a pledger stakes PLDG on a goal with a number of weekly check-ins and a beneficiary; each week the pledger must check in within its window; a missed week forfeits that week's slice to the beneficiary; completing every week returns the full stake. Deliver Solidity source, a full Foundry test suite, and an independent adversarial review. Pledge is a fixed-supply ERC-20 named Pledge (PLDG), with 18 decimals and a zero-argument constructor minting 1,000,000,000 tokens to its deployer; there is no later minting. HabitPledge takes only the token address in its constructor. Use seven-day windows starting when each pledge is created, permit at most one check-in per window by the pledger, and allow settlement after the final window. At settlement pay the beneficiary the missed-week slices and return the remainder to the pledger; define and test integer-rounding behavior so no stake is stranded. Validate positive stake, positive bounded week count, and a nonzero beneficiary. No administrator, fees or upgradeability; follow checks-effects-interactions, guard reentrancy and emit events for state changes. Cover successful completion, missed weeks, early and late calls, duplicate check-ins, wrong callers, insufficient allowance/balance, multiple pledges, rounding, and a malicious token. Return source and review through the normal job artifacts; this request is for building and testing the contracts.","parentJobId":null,"planHash":"72a1b83fb18efd033be3b33b21defb60d71820610cafef85c05200248fd302c6","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"59146633-2425-4a48-8310-456019e2d15e","publication":{"commit":null,"deliveredAt":null,"repoUrl":null},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"50906","feedbackHash":"bfbdd5cda4f84dded13073bd4df98f2304a9dedd9d221c5825ca01702a87c701","nodeKey":"impl","submissionHash":"f7c6def6a1d9ebdf14de127a19bcc4d4e65e174f781050471ed1d41091ff793d","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"50971","feedbackHash":"717612111bb58bda4d0c4985b2796ba02c1492905f1538aff65f86535b31dd75","nodeKey":"review","submissionHash":"4d15c04bbdce8efa7c3c57d238e4a472e49acbde65acd4bfff0a9c1ed93c4986","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50974","feedbackHash":"ed96ab338ab90a545150e6b257f261f02c77e8084db005d968d8b6f7f7555029","nodeKey":"tests","submissionHash":"469bf7b9231747a84b23ac790e1eab6c3cf99f8defcfa184b06ef8167b22ea9f","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"7962a60e7bcaf6d0d3605b086df03183fcb5a4371e758b08c7d4b1dd8f9ccaf2","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"90f1f5c3374333a0","findings":[],"hash":"05eae84908cfc0911bb27d73769270440cedaa5366727c1691eda84d03f5edeb","nodeId":"42f0c2cd-9eb1-407a-b0f2-a52f0e74a68d","outcome":"failed","summary":"wall-clock budget exhausted","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":"gpt-6-astra","outputTokens":0,"runtime":"codex","turns":1,"wallClockMs":7272997}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"5b3b071249317936","findings":[],"hash":"0fc070068402eeecc91f433c5199488f937ab050a030632eaad5ec57ded47b18","nodeId":"5cc678d5-a0a7-40f0-b55f-4aa47f7494c5","outcome":"failed","summary":"runtime reported swe-2, not the required premium model gpt-6-astra","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":"swe-2","outputTokens":0,"runtime":"codex","turns":1,"wallClockMs":607956}},{"artifacts":[],"attempt":2,"bundleHash":"874cf6a02363618f5193ab1487e3f5779a99258c23a1ebffd517bb5ce44ab29b","device":"98b4506bef931d13","findings":[{"description":"Not a defect in the accepted implementation and consistent with its NatSpec ('no escrow can guarantee payouts from a token that lies about its balances or arbitrarily refuses transfers'). Recorded so the behaviour is explicit: _pay() verifies exact balance deltas and reverts with UnexpectedTokenAmount / TokenTransferFailed, and settle() rolls back the settled flag, so the pledge stays open until the token behaves again. With the fixed-supply Pledge (PLDG) token this cannot happen; it only matters if HabitPledge is deployed against a different ERC-20 with fee-on-transfer, rebasing or pausable semantics. No fix is required; the test suite asserts the fail-closed behaviour and the subsequent successful settlement once the token behaves (test_MaliciousToken_MisbehaviourAtSettlementRollsBack).","line":152,"path":"src/HabitPledge.sol","reproduction":"Deploy HabitPledge against MaliciousToken (test/HabitPledge.t.sol). createPledge(\"g\", 100, 2, charity) in Normal mode, checkIn week 0, warp to start + 14 days, switch the token to Lie / ReturnFalse / FeeOnTransfer, call settle(0). Expected and actual: revert (UnexpectedTokenAmount or TokenTransferFailed), pledges(0).settled stays false, escrow balance stays 100. Switch back to Normal and settle(0) succeeds: charity receives 50, pledger 50, escrow 0.","severity":"info","title":"Settlement fails closed (funds stay escrowed) if the token starts misbehaving after the stake is escrowed"}],"hash":"469bf7b9231747a84b23ac790e1eab6c3cf99f8defcfa184b06ef8167b22ea9f","nodeId":"42f0c2cd-9eb1-407a-b0f2-a52f0e74a68d","outcome":"completed","summary":"The harness deliberately excludes the findings file from git via `.git/info/exclude`, so it is picked up out of band. The file is in place and nothing else is needed.\n\n## Recap\n\n**Delivered** two self-contained Foundry test files, `test/Pledge.t.sol` and `test/HabitPledge.t.sol`. The repo ships no `forge-std` and I may not add `lib/`, so each file declares a minimal `Vm` cheatcode interface and its own assertion helpers. Nothing was installed, so the offline verifier has no missing dependency.\n\n**Result** of `forge test --offline` with solc 0.8.30 from the local cache:\n\n| Suite | Tests | Fuzz runs each |\n|---|---|---|\n| PledgeTest | 24 | 256 |\n| HabitPledgeTest | 63 | 256 |\n| Total | 87 passed, 0 failed | |\n\nI also confirmed a deliberately wrong scratch test fails, so the inline asserts are effective.\n\n**Coverage of the failure paths**, beyond the happy path:\n- Pledge (PLDG): metadata, fixed supply minted to deployer with mint event, no mint selector or fallback, insufficient balance and allowance reverts, zero-address reverts, finite versus unlimited allowance, allowance unchanged after a reverted spend, supply-conservation fuzz.\n- HabitPledge validation: zero stake, zero and oversize week count, zero and escrow-address beneficiary, constructor with zero or codeless token, bubbled `InsufficientAllowance` and `InsufficientBalance` from the token.\n- Timing: check-in at the last second of a window versus exactly at the boundary, settle one second early versus exactly at the final window end, late check-ins after the final window and after settlement, missed weeks being unrecoverable, all 256 weeks with the top bit.\n- Duplicates and callers: double check-in in the same block and same window, check-in by beneficiary or stranger, settle twice, unknown pledge ids, settle by anyone with fixed recipients.\n- Rounding: remainder units go to the earliest weeks, stake smaller than week count yields zero-value slices, one unit over 256 weeks, and a fuzz over amount, week count and a random check-in bitmap asserting refund plus forfeiture equals the stake and the escrow is fully drained.\n- Multiple pledges: sequential ids, independent bitmaps and start times, per-pledge settlement, aggregate escrow accounting.\n- Malicious token: legacy no-return accepted, `false`, `2` and 64-byte returns rejected, custom revert bubbled, lying and fee-on-transfer rejected at creation, misbehaviour at settlement rolls back the settled flag, and reentrant `createPledge`, `checkIn` and `settle` from inside the token all revert with `Reentrancy`.\n\n**Findings.** I found no defect in the implementation that I had to test around. The `.imd-findings.json` records one info-level note: if a non-PLDG token starts misbehaving after escrow, settlement fails closed and the pledge stays open until the token behaves, which matches the contract's documented limitation and is asserted by a test.","treeHash":"c4eac98613f3b7fc5e7be926b32b064184599a2b","usage":{"cachedInputTokens":594840,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":33961,"runtime":"claude","turns":14,"wallClockMs":366176}},{"artifacts":[],"attempt":2,"bundleHash":null,"device":"35c52a5b502e847c","findings":[],"hash":"4d15c04bbdce8efa7c3c57d238e4a472e49acbde65acd4bfff0a9c1ed93c4986","nodeId":"5cc678d5-a0a7-40f0-b55f-4aa47f7494c5","outcome":"completed","summary":"No substantiated defects found. Wrote `{\"findings\":[]}` to [.imd-findings.json](/home/identitymd/.identitymd/work/59146633-2425-4a48-8310-456019e2d15e/5cc678d5-a0a7-40f0-b55f-4aa47f7494c5/.imd-findings.json).\n\nAll 87 Foundry tests passed offline, with 1,024 runs per fuzz test. Source, tests, and configuration remain unchanged.","treeHash":null,"usage":{"cachedInputTokens":178688,"inputTokens":45473,"model":"gpt-6-astra","outputTokens":2573,"runtime":"codex","turns":4,"wallClockMs":100674}},{"artifacts":[],"attempt":1,"bundleHash":"0c2b0b8db095d8ea6926af73adca3711e1851fbdf8ecb1215d89309a3396ff94","device":"90f1f5c3374333a0","findings":[],"hash":"f7c6def6a1d9ebdf14de127a19bcc4d4e65e174f781050471ed1d41091ff793d","nodeId":"21056bad-c9ec-4d28-a613-6938dc18a3e3","outcome":"completed","summary":"Implemented [Pledge.sol](/Users/surf/.identitymd/work/59146633-2425-4a48-8310-456019e2d15e/21056bad-c9ec-4d28-a613-6938dc18a3e3/src/Pledge.sol) and [HabitPledge.sol](/Users/surf/.identitymd/work/59146633-2425-4a48-8310-456019e2d15e/21056bad-c9ec-4d28-a613-6938dc18a3e3/src/HabitPledge.sol).\n\n- Fixed supply, seven-day windows, duplicate prevention, settlement, reentrancy protection, and events.\n- Rounding assigns extra units to the earliest weeks; every staked unit is paid out.\n- `forge build` passed, including an offline source-only build.\n- `forge test`: **60 passed**, including **768 fuzz cases**.\n- Independent adversarial review identified no exploitable defects for the supplied PLDG token. It verified reentrancy containment, atomic rollback, boundaries, and payout conservation.\n\nTests and the full review remain in `test/scratch/`, excluded from submission under your rules. Only the two permitted source files were added outside scratch; no dependencies or configuration changes.","treeHash":"59dd4e806914acfb215d0b458599036e346ab8d1","usage":{"cachedInputTokens":304896,"inputTokens":35232,"model":"gpt-6-astra","outputTokens":15717,"runtime":"codex","turns":5,"wallClockMs":511568}}],"verification":[{"checks":[{"durationMs":186,"exitCode":0,"name":"build","output":"Compiling 4 files with Solc 0.8.30\nSolc 0.8.30 finished in 144.80ms\nCompiler run successful!\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HabitPledge.sol:136:13\n    │\n136 │         if (block.timestamp < pledge.startTime + pledge.weekCount * WEEK_DURATION) revert TooEarlyToSettle();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:104:9\n    │\n104 │         token.transfer(deployer, SUPPLY);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:110:9\n    │\n110 │         token.transfer(alice, SUPPLY);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:118:9\n    │\n118 │         token.transfer(alice, SUPPLY + 1);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:122:9\n    │\n122 │         token.transfer(bob, 1);\n    │         ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:128:9\n    │\n128 │         token.transfer(address(0), 1);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:184:9\n    │\n184 │         token.transferFrom(deployer, bob, 300);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/HabitPledge.t.sol:176:9\n    │\n176 │         token.transfer(alice, 10_000 ether);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/HabitPledge.t.sol:177:9\n    │\n177 │         token.transfer(bob, 10_000 ether);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:189:9\n    │\n189 │         token.transferFrom(deployer, bob, 1);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:196:9\n    │\n196 │         token.transferFrom(deployer, bob, 1_000);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:206:9\n    │\n206 │         token.transferFrom(deployer, bob, 100);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:213:9\n    │\n213 │         token.transferFrom(deployer, bob, 1);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:222:9\n    │\n222 │         token.transferFrom(alice, bob, 1);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:230:9\n    │\n230 │         token.transferFrom(deployer, address(0), 1);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:237:9\n    │\n237 │         token.transferFrom(deployer, bob, 1);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/HabitPledge.t.sol:790:9\n    │\n790 │         bad.transfer(alice, 1e24);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:246:9\n    │\n246 │         token.transfer(to, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:264:13\n    │\n264 │             token.transferFrom(deployer, bob, amount);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/Pledge.t.sol:266:13\n    │\n266 │             token.transferFrom(deployer, bob, amount);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\n","passed":true},{"durationMs":166,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 24 tests for test/Pledge.t.sol:PledgeTest\n[PASS] testFuzz_TransferConservesSupply(address,uint256) (runs: 256, μ: 49506, ~: 49880)\n[PASS] testFuzz_TransferFromRespectsAllowance(uint256,uint256) (runs: 256, μ: 62067, ~: 44916)\n[PASS] test_Approve() (gas: 43975)\n[PASS] test_ApproveOverwritesNotAccumulates() (gas: 45414)\n[PASS] test_ApproveWithoutBalanceIsAllowed() (gas: 40698)\n[PASS] test_ConstructorEmitsMintTransfer() (gas: 662567)\n[PASS] test_FixedSupplyMintedToDeployer() (gas: 16628)\n[PASS] test_Metadata() (gas: 9773)\n[PASS] test_NoMintFunctionExists() (gas: 11569)\n[PASS] test_OwnerCannotSpendViaTransferFromWithoutSelfApproval() (gas: 17105)\n[PASS] test_RevertWhen_ApproveZeroSpender() (gas: 12128)\n[PASS] test_RevertWhen_TransferExceedsBalance() (gas: 24913)\n[PASS] test_RevertWhen_TransferFromExceedsAllowance() (gas: 47524)\n[PASS] test_RevertWhen_TransferFromExceedsBalance() (gas: 46288)\n[PASS] test_RevertWhen_TransferFromToZeroAddress() (gas: 44741)\n[PASS] test_RevertWhen_TransferFromWithoutAllowance() (gas: 19128)\n[PASS] test_RevertWhen_TransferToZeroAddress() (gas: 12281)\n[PASS] test_Transfer() (gas: 52342)\n[PASS] test_TransferFromDecrementsAllowance() (gas: 93202)\n[PASS] test_TransferFromExactAllowance() (gas: 62913)\n[PASS] test_TransferFullBalance() (gas: 42787)\n[PASS] test_TransferToSelf() (gas: 19083)\n[PASS] test_TransferZeroAmount() (gas: 23283)\n[PASS] test_UnlimitedAllowanceIsNotDecremented() (gas: 77977)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 54.80ms (89.56ms CPU time)\n\nRan 63 tests for test/HabitPledge.t.sol:HabitPledgeTest\n[PASS] testFuzz_AllWeeksCheckedInRefundsExactStake(uint256,uint256) (runs: 256, μ: 1234853, ~: 1200711)\n[PASS] testFuzz_CheckInWeekIndexFollowsTimestamp(uint256,uint256) (runs: 256, μ: 277358, ~: 279613)\n[PASS] testFuzz_SlicesSumToStakeAndNothingStranded(uint256,uint256,uint256) (runs: 256, μ: 611782, ~: 436776)\n[PASS] test_CheckInAtLastSecondOfWindow() (gas: 277861)\n[PASS] test_CheckInAtWindowBoundaryCountsForNextWeek() (gas: 284374)\n[PASS] test_CheckInEveryWeekOf256() (gas: 2445464)\n[PASS] test_CheckInFirstWeekAtCreation() (gas: 286743)\n[PASS] test_ConstructorStoresToken() (gas: 13676)\n[PASS] test_CreatePledgeAllowsEmptyGoal() (gas: 198736)\n[PASS] test_CreatePledgeAllowsMaxWeeksAndBeneficiaryEqualsPledger() (gas: 228406)\n[PASS] test_CreatePledgeStoresStateAndEscrowsStake() (gas: 245822)\n[PASS] test_CreatePledgeWithFiniteAllowanceConsumesIt() (gas: 227412)\n[PASS] test_LastWeekCheckInThenImmediateSettle() (gas: 328948)\n[PASS] test_MaliciousToken_FeeOnTransferRejected() (gas: 2998134)\n[PASS] test_MaliciousToken_GarbageReturnRejected() (gas: 2995584)\n[PASS] test_MaliciousToken_LyingTransferFromRejected() (gas: 2978357)\n[PASS] test_MaliciousToken_MisbehaviourAtSettlementRollsBack() (gas: 3245857)\n[PASS] test_MaliciousToken_NoReturnDataIsAccepted() (gas: 3043322)\n[PASS] test_MaliciousToken_ReentrantCheckInDuringCreateIsBlocked() (gas: 3085102)\n[PASS] test_MaliciousToken_ReentrantCheckInDuringSettleIsBlocked() (gas: 3124908)\n[PASS] test_MaliciousToken_ReentrantCreateDuringCreateIsBlocked() (gas: 3076440)\n[PASS] test_MaliciousToken_ReentrantCreateDuringSettleIsBlocked() (gas: 3119081)\n[PASS] test_MaliciousToken_ReentrantSettleDuringSettleIsBlocked() (gas: 3121251)\n[PASS] test_MaliciousToken_ReturnFalseRejected() (gas: 2999557)\n[PASS] test_MaliciousToken_ReturnTwoRejected() (gas: 2995909)\n[PASS] test_MaliciousToken_RevertIsBubbled() (gas: 2973051)\n[PASS] test_MissedWeekCannotBeRecoveredLater() (gas: 292684)\n[PASS] test_MultiplePledgesAreIndependent() (gas: 930355)\n[PASS] test_NoEtherAccepted() (gas: 7786)\n[PASS] test_RevertWhen_BeneficiaryIsEscrow() (gas: 18138)\n[PASS] test_RevertWhen_BeneficiaryIsZero() (gas: 17979)\n[PASS] test_RevertWhen_CheckInAfterFinalWindow() (gas: 236472)\n[PASS] test_RevertWhen_CheckInAfterSettlement() (gas: 268486)\n[PASS] test_RevertWhen_CheckInByBeneficiary() (gas: 225533)\n[PASS] test_RevertWhen_CheckInByStranger() (gas: 227510)\n[PASS] test_RevertWhen_CheckInOnUnknownPledge() (gas: 234995)\n[PASS] test_RevertWhen_ConstructorTokenHasNoCode() (gas: 64830)\n[PASS] test_RevertWhen_ConstructorTokenIsZero() (gas: 60123)\n[PASS] test_RevertWhen_DuplicateCheckInSameBlock() (gas: 276588)\n[PASS] test_RevertWhen_DuplicateCheckInSameWindow() (gas: 285166)\n[PASS] test_RevertWhen_InsufficientAllowance() (gas: 207998)\n[PASS] test_RevertWhen_InsufficientBalance() (gas: 196948)\n[PASS] test_RevertWhen_NoAllowanceAtAll() (gas: 190582)\n[PASS] test_RevertWhen_SettleTooEarly() (gas: 234205)\n[PASS] test_RevertWhen_SettleTwice() (gas: 271778)\n[PASS] test_RevertWhen_SettleUnknownPledge() (gas: 16298)\n[PASS] test_RevertWhen_StakeExceedsTotalSupply() (gas: 219549)\n[PASS] test_RevertWhen_StakeIsZero() (gas: 20112)\n[PASS] test_RevertWhen_WeekCountExceedsMax() (gas: 29625)\n[PASS] test_RevertWhen_WeekCountIsZero() (gas: 20050)\n[PASS] test_RoundingMissedRemainderWeekForfeitsExtraUnit() (gas: 341887)\n[PASS] test_RoundingOneUnitOverMaxWeeks() (gas: 297411)\n[PASS] test_RoundingRemainderGoesToEarliestWeeks() (gas: 306484)\n[PASS] test_RoundingStakeSmallerThanWeekCount() (gas: 356803)\n[PASS] test_RoundingZeroSlicePledgeAllMissedForfeitsAll() (gas: 268836)\n[PASS] test_SamePledgerManyPledgesSameBlock() (gas: 1095371)\n[PASS] test_SettleAllMissedForfeitsEntireStake() (gas: 276406)\n[PASS] test_SettleByStrangerAndByBeneficiary() (gas: 467899)\n[PASS] test_SettleExactlyAtFinalWindowEnd() (gas: 280541)\n[PASS] test_SettleFullCompletionReturnsEntireStake() (gas: 333987)\n[PASS] test_SettleLongAfterDeadlineStillWorks() (gas: 295256)\n[PASS] test_SettlePartialSplitsByWeeks() (gas: 342080)\n[PASS] test_SettleWhenBeneficiaryIsPledger() (gas: 305249)\nSuite result: ok. 63 passed; 0 failed; 0 skipped; finished in 121.97ms (210.69ms CPU time)\n\nRan 2 test suites in 122.87ms (176.76ms CPU time): 87 tests passed, 0 failed, 0 skipped (87 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"469bf7b9231747a84b23ac790e1eab6c3cf99f8defcfa184b06ef8167b22ea9f","verifiedTreeHash":"c4eac98613f3b7fc5e7be926b32b064184599a2b","verifierVersion":"0.1.0+322175ca"},{"checks":[{"durationMs":67,"exitCode":0,"name":"build","output":"Compiling 2 files with Solc 0.8.30\nSolc 0.8.30 finished in 30.05ms\nCompiler run successful!\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HabitPledge.sol:136:13\n    │\n136 │         if (block.timestamp < pledge.startTime + pledge.weekCount * WEEK_DURATION) revert TooEarlyToSettle();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\n","passed":true},{"durationMs":36,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\nNo tests found in project! Forge looks for functions that start with `test`\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"f7c6def6a1d9ebdf14de127a19bcc4d4e65e174f781050471ed1d41091ff793d","verifiedTreeHash":"59dd4e806914acfb215d0b458599036e346ab8d1","verifierVersion":"0.1.0+322175ca"}]}