{"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":"dde0195a-0884-431f-b201-75210971f42b","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"e610e226873709df8ad4fd24dd3cb28651f754cab150c9e91fe575487cb82756","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"47381b166d1f406a34f0ebdc740ee21bc0383e56e7ad9084b26abf1bf7570904","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"47381b166d1f406a34f0ebdc740ee21bc0383e56e7ad9084b26abf1bf7570904","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"c0e4c264776ea1630277bc4a4b86463303c9f4ef1abbd24ab4bd7dcdee247760","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"ff1fad07fad3b8e08a71e9c5201fd632e161ed8163eb407676ea8b0bedbe179e","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"ff1fad07fad3b8e08a71e9c5201fd632e161ed8163eb407676ea8b0bedbe179e","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Build CPPair, a Uniswap-V2-style constant-product pair for two ERC-20s that is its own ERC-20 LP token, then have a second worker write stateful invariant tests for it. Local only: do not deploy; tests use two 18-decimal mock ERC-20s.\n\nCPPair (src/CPPair.sol, Solidity 0.8.26), constructor(address token0, address token1): non-zero and distinct. LP token 'CP LP' / 'CPLP', 18 decimals. Reserves are uint112 each, stored, and change only through the functions below, so raw balances can exceed them after donations.\n- addLiquidity(uint256 amount0Desired, uint256 amount1Desired, uint256 minShares, address to): the first deposit takes both amounts and mints sqrt(a0 × a1) − 1000 shares to `to` and 1000 to 0x000000000000000000000000000000000000dEaD forever (reverts if sqrt(a0 × a1) ≤ 1000); later deposits pull the largest ratio-matched pair within the desired amounts and mint min(a0 × S / r0, a1 × S / r1), rounded down. Reverts on zero shares or below minShares.\n- removeLiquidity(uint256 shares, uint256 min0, uint256 min1, address to): burns shares and pays shares × reserve / totalSupply of each token, rounded down; reverts on zero output or below the minimums.\n- swapExactIn(address tokenIn, uint256 amountIn, uint256 minOut, address to): 0.3% fee on input; out = floor(amountIn × 997 × rOut / (rIn × 1000 + amountIn × 997)); reverts on an unknown token, zero output or below minOut.\n- sync() sets reserves to current balances; skim(address to) sends balance − reserve of each token to `to`. Both permissionless, as in V2.\n- Every token pull checks the received amount by balance difference and reverts on fee-on-transfer. getReserves(), quote(amountIn, tokenIn) view; events Mint, Burn, Swap, Sync. A reentrancy guard on every state-changing function, effects before transfers. No owner, protocol fee, flash swap or price accumulator.","parentJobId":null,"planHash":"cd45f8ccb8202b4af1c933929f677338754b92175f18263cd3acb6f3ef951971","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"dde0195a-0884-431f-b201-75210971f42b","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-283-build-cppair-uniswap-v2-style-constant-p"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"50939","feedbackHash":"edd6e59717cc52e2c71434203b82265fe850cc72fea411bead6596f0e8ff1aaf","nodeKey":"build_contract_project","submissionHash":"e610e226873709df8ad4fd24dd3cb28651f754cab150c9e91fe575487cb82756","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"50939","feedbackHash":"7fd726b14c0d4b7958230d99ed35708126e3616c5c1910e228380e0c6e240a50","nodeKey":"write_foundry_tests","submissionHash":"c0e4c264776ea1630277bc4a4b86463303c9f4ef1abbd24ab4bd7dcdee247760","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"29a699b6d9c96622b766998e572e7828e8d07f5cefd555e304ef7c9becb3ec2d","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"4d66134d835d48539f491bc0d085deb80f92f2ed2da83b4df3f2a4046f3f4126","device":"72b617d4b615473a","findings":[{"description":"None of the three payout functions validate the recipient. With a token that permits transfers to the zero address (the test mocks do; many real tokens revert) the burned shares or swap input are exchanged for tokens sent to 0x0, which are lost. addLiquidity does reject a zero recipient (ZeroAddress from _mint), so the interface is inconsistent. This matches Uniswap V2 and the spec does not require the check, so it is reported for the implementer's judgement, not as a spec violation. The invariant suite does not assert either behaviour: actors always pass themselves as `to`.","line":198,"path":"src/CPPair.sol","reproduction":"Seed the pool (alice addLiquidity 1000e18/4000e18). Call pair.swapExactIn(token0, 10e18, 0, address(0)) as bob with MockERC20 tokens. Expected (if a guard is wanted): revert ZeroAddress(). Actual: succeeds, reserves update, token1 balance of address(0) increases by the quoted output, bob's input is consumed. Same for removeLiquidity(shares, 0, 0, address(0)) and skim(address(0)).","severity":"info","title":"removeLiquidity, swapExactIn and skim accept to == address(0) and push tokens there"}],"hash":"c0e4c264776ea1630277bc4a4b86463303c9f4ef1abbd24ab4bd7dcdee247760","nodeId":"9c27bc10-bd5a-4dae-99d0-5661b0f9a8d0","outcome":"completed","summary":"The findings file is in place and deliberately excluded from git by the harness's own exclude list, so that is expected. The work is complete.\n\n## Summary\n\n**Deliverable:** a handler-based stateful invariant suite for the accepted `CPPair` implementation, in three new files under `test/invariant/`. No existing files were changed.\n\n- `test/invariant/FullMath.sol` is a 512-bit `mulDiv` library with a `mulDivGe` helper. It compares k × supply² products without overflow, and treats a quotient too large for 256 bits as satisfying the inequality, which can only happen when share value has risen.\n- `test/invariant/CPPairHandler.sol` drives four actors that add, remove, remove everything, swap both ways, round-trip, donate directly, sync, skim, and transfer LP shares. Amounts are drawn log-uniformly from 1 wei to 1e27 so both rounding-edge and whale regimes are hit.\n- `test/invariant/CPPair.invariant.t.sol` carries the inline config `runs = 1000`, `depth = 100`, and `fail-on-revert = true`, so any unexpected revert or handler assertion fails the campaign.\n\n**Acceptance criteria and where they are checked:**\n- k never decreases across a swap: asserted in the handler before and after every swap.\n- Reserves never exceed balances, and equal them right after sync: an invariant plus the sync handler. The surplus is also required to equal exactly the tracked donations.\n- Share value k/S² non-decreasing: a modifier on add, remove, swap and sync checks `mulDiv(kAfter, supplyBefore², supplyAfter²) ≥ kBefore`, and an invariant checks the same against the value after the first deposit.\n- Removing all of an actor's shares never pays more than pro-rata, and the 1000 dead shares keep both reserves positive: the removeAll handler and a dead-shares invariant.\n- Round trip never returns more than the input: the round-trip handler.\n- Failure paths: every handler probes the exact custom error from live state, including InsufficientInitialLiquidity, InsufficientSharesMinted, ZeroAddress, InsufficientShares, InsufficientBalance, InsufficientOutput on zero payout and on each minimum, UnknownToken for swap and quote, and over-balance LP transfers.\n\n**Verification:** the full tree passes with 75 tests. The invariant campaign ran 100,000 calls with zero reverts in about 35 seconds. I also proved the suite has teeth with two throwaway mutants in scratch, since removed: a negative swap fee and a removal payout rounded up. Both were caught within fifty calls.\n\n**Defects:** I found no spec violation. One info-level observation is recorded in `.imd-findings.json`: removeLiquidity, swapExactIn and skim accept a zero-address recipient while addLiquidity rejects it. This matches Uniswap V2 and the spec does not require the check, so I flagged it rather than asserting either way.\n\n**Not done:** I did not commit. Nothing was installed, and the README's test count was left as-is since it is outside my writable paths.","treeHash":"327d07ca3e92721cd4c838ac8cc8b2179d864fbf","usage":{"cachedInputTokens":2154233,"inputTokens":642,"model":"claude-fable-5-1","outputTokens":56802,"runtime":"claude","turns":43,"wallClockMs":813975}},{"artifacts":[],"attempt":1,"bundleHash":"485a6054444f45641e7d1d3b4e711ecd0a16d557ebf667142d892446d76ffe7f","device":"72b617d4b615473a","findings":[],"hash":"e610e226873709df8ad4fd24dd3cb28651f754cab150c9e91fe575487cb82756","nodeId":"c2e5ee94-0973-4a50-9572-d60506ca429c","outcome":"completed","summary":"Done. The pair, its unit tests, and documentation are implemented, verified, and committed on `main` as commit `d85df43`.\n\n**What was delivered**\n\n- `src/CPPair.sol`: the constant-product pair, Solidity 0.8.26, which is its own `CP LP` / `CPLP` 18-decimal ERC-20. It implements `addLiquidity`, `removeLiquidity`, `swapExactIn`, `sync`, `skim`, `getReserves`, `quote`, and the `Mint`, `Burn`, `Swap`, `Sync` events. Reserves are stored `uint112` values and change only inside those five functions. The first deposit locks 1000 shares at the dEaD address and reverts when the square root is at or below 1000. Later deposits take the largest ratio-matched pair and mint the floored minimum of the two share ratios. Swaps use the 997/1000 input-fee formula from the brief. Every pull is verified by balance difference and reverts on fee-on-transfer. A single reentrancy lock covers all five state-changing functions, and reserves, supply, and events are updated before any token call. There is no owner, protocol fee, flash swap, or price accumulator.\n- `test/CPPair.t.sol` plus three mocks under `test/mocks/`: 70 tests, including 2 bounded fuzz tests. They cover every function's success path and every custom revert, including both ratio-binding branches on later deposits, rounding on deposits and removals, donation handling for deposits, swaps, and removals, `uint112` overflow, the reentrancy guard on pull and push paths for all five guarded functions, ERC-20 transfer and allowance behaviour, and a full lifecycle consistency check.\n- `README.md`: interface, semantics, assumptions, deployment parameters, operational responsibilities, and a note that stateful invariant tests belong to the second worker.\n- `foundry.toml` pins `solc = \"0.8.26\"`, EVM `cancun`, `ffi = false`, empty `fs_permissions`. forge-std v1.9.7 is vendored under `lib/forge-std` from the release tarball, so it is 57 ordinary tracked files with no submodule or nested git metadata.\n\n**Verification**\n\nFrom a wiped `out/` and `cache/`, all three checks pass with zero compiler or lint warnings:\n\n| Check | Result |\n| --- | --- |\n| `forge build` | success, 0 warnings |\n| `forge test` | 70 passed, 0 failed |\n| `forge fmt --check` | clean |\n\nTests use no environment variables, no `ffi`, and no caller-address dependence, so they are safe to run in parallel and in any order. I ran them with the default parallel runner; this forge version has no shuffle flag, so ordering independence rests on each test building its own state in `setUp`.\n\n**Design choices worth knowing**\n\n- The reentrancy tests do not expect the outer call to revert. The pair wraps any failing token call as `TransferFailed`, so a bubbling mock would hide which error fired. The mock instead records the inner call's revert data, and the tests assert it equals the `Reentrancy` selector and that state reflects exactly one operation.\n- Transfers and mints of LP shares to the zero address revert. The brief did not specify this; it is standard ERC-20 behaviour and is documented.\n- The constructor does not check that the token addresses have code, matching the brief's \"non-zero and distinct\" wording. The README flags the consequence.\n\n**Not done, by scope**\n\nNo deploy script and no deployment, as the task is local-only. Stateful invariant tests are the second worker's assignment. The suite is not a security audit.","treeHash":"0e5c37293289e9460d8cff037dadb8abbeec40b3","usage":{"cachedInputTokens":1501498,"inputTokens":802,"model":"claude-fable-5-1","outputTokens":46995,"runtime":"claude","turns":26,"wallClockMs":505804}}],"verification":[{"checks":[{"durationMs":1644,"exitCode":0,"name":"build","output":"Compiling 27 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.58s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> test/invariant/CPPairHandler.sol:264:5:\n    |\n264 |     function _checkRemove(address actor, Snapshot memory s, uint256 amount0, uint256 amount1) internal {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning: unknown id: 'reentrancy-no-eth'\n    ╭▸ src/CPPair.sol:400:9\n    │\n400 │         // forge-lint: disable-next-line(reentrancy-no-eth)\n    ╰╴        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:130:19\n    │\n130 │         emit Sync(uint112(a0), uint112(a1));\n    │                   ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:130:32\n    │\n130 │         emit Sync(uint112(a0), uint112(a1));\n    │                                ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:393:19\n    │\n393 │         emit Sync(uint112(1000e18 - expect0), uint112(4000e18 - expect1));\n    │                   ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:393:47\n    │\n393 │         emit Sync(uint112(1000e18 - expect0), uint112(4000e18 - expect1));\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:521:19\n    │\n521 │         emit Sync(uint112(1000e18 + amountIn), uint112(4000e18 - expectedOut));\n    │                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:521:48\n    │\n521 │         emit Sync(uint112(1000e18 + amountIn), uint112(4000e18 - expectedOut));\n    │                                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/CPPair.t.sol:616:9\n    │\n616 │         tokenA.transfer(address(feePair), 100e18);\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/CPPair.t.sol:617:9\n    │\n617 │         fee.transfer(address(feePair), 100e18);\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/CPPair.t.sol:882:9\n    │\n882 │         pair.transfer(bob, shares + 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/CPPair.t.sol:889:9\n    │\n889 │         pair.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/CPPair.t.sol:912:9\n    │\n912 │         pair.transferFrom(alice, carol, 4e18);\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/CPPair.t.sol:922:9\n    │\n922 │         pair.transferFrom(alice, carol, 1e18 + 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/CPPair.t.sol:929:9\n    │\n929 │         pair.transfer(bob, shares);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\n","passed":true},{"durationMs":21477,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 70 tests for test/CPPair.t.sol:CPPairTest\n[PASS] testFuzz_AddLiquidity_SubsequentSharesFormula(uint256,uint256) (runs: 256, μ: 277632, ~: 279098)\nLogs:\n  Bound result 22163771506312657196\n  Bound result 55007391391991103746322\n\n[PASS] testFuzz_Swap_MatchesFormulaAndPreservesK(uint256,bool) (runs: 256, μ: 259021, ~: 259270)\nLogs:\n  Bound result 1100000000000000000000\n\n[PASS] test_AddLiquidity_FirstDeposit() (gas: 235601)\n[PASS] test_AddLiquidity_FirstDeposit_BoundaryJustAboveMinimum() (gas: 194455)\n[PASS] test_AddLiquidity_FirstDeposit_MintsToRecipient() (gas: 216025)\n[PASS] test_AddLiquidity_FirstDeposit_TakesFullAmountsEvenWhenUnbalanced() (gas: 224717)\n[PASS] test_AddLiquidity_RevertFeeOnTransfer() (gas: 1829636)\n[PASS] test_AddLiquidity_RevertFirstDeposit_BelowMinShares() (gas: 84536)\n[PASS] test_AddLiquidity_RevertFirstDeposit_SqrtEqualToMinimum() (gas: 24155)\n[PASS] test_AddLiquidity_RevertFirstDeposit_SqrtRoundsDownToMinimum() (gas: 24383)\n[PASS] test_AddLiquidity_RevertFirstDeposit_ZeroAmount() (gas: 20926)\n[PASS] test_AddLiquidity_RevertReserveOverflow() (gas: 241049)\n[PASS] test_AddLiquidity_RevertWithoutAllowance() (gas: 208091)\n[PASS] test_AddLiquidity_RevertZeroRecipient() (gas: 81852)\n[PASS] test_AddLiquidity_Subsequent_ExactMinSharesSucceeds() (gas: 270642)\n[PASS] test_AddLiquidity_Subsequent_MintsMinOfBothRatios() (gas: 270426)\n[PASS] test_AddLiquidity_Subsequent_RevertBelowMinShares() (gas: 216327)\n[PASS] test_AddLiquidity_Subsequent_RevertZeroShares() (gas: 207836)\n[PASS] test_AddLiquidity_Subsequent_RoundsDown() (gas: 256363)\n[PASS] test_AddLiquidity_Subsequent_Token0IsBinding() (gas: 286748)\n[PASS] test_AddLiquidity_Subsequent_Token1IsBinding() (gas: 278857)\n[PASS] test_AddLiquidity_Subsequent_UsesReservesNotBalances() (gas: 284805)\n[PASS] test_Constructor_Metadata() (gas: 29116)\n[PASS] test_Constructor_RevertIdenticalTokens() (gas: 61739)\n[PASS] test_Constructor_RevertZeroToken0() (gas: 61624)\n[PASS] test_Constructor_RevertZeroToken1() (gas: 61784)\n[PASS] test_ERC20_ApproveAndTransferFrom() (gas: 274775)\n[PASS] test_ERC20_Transfer() (gas: 243235)\n[PASS] test_ERC20_TransferFromInfiniteAllowanceNotDecremented() (gas: 265685)\n[PASS] test_ERC20_TransferFromRevertInsufficientAllowance() (gas: 239590)\n[PASS] test_ERC20_TransferRevertInsufficientBalance() (gas: 211666)\n[PASS] test_ERC20_TransferRevertZeroAddress() (gas: 209217)\n[PASS] test_ERC20_TransferredSharesAreRedeemable() (gas: 232642)\n[PASS] test_Lifecycle_BalancesTrackReserves() (gas: 315708)\n[PASS] test_Quote_EmptyPoolReturnsZero() (gas: 17217)\n[PASS] test_Quote_RevertUnknownToken() (gas: 8794)\n[PASS] test_Reentrancy_AddLiquidityBlocked() (gas: 2270946)\n[PASS] test_Reentrancy_GuardResetsAfterCall() (gas: 2226169)\n[PASS] test_Reentrancy_RemoveLiquidityBlocked() (gas: 2360920)\n[PASS] test_Reentrancy_SkimBlocked() (gas: 2282615)\n[PASS] test_Reentrancy_SwapPullBlocked() (gas: 2409070)\n[PASS] test_Reentrancy_SwapPushBlocked() (gas: 2338239)\n[PASS] test_RemoveLiquidity_AllOwnShares() (gas: 231747)\n[PASS] test_RemoveLiquidity_IgnoresDonatedBalance() (gas: 219821)\n[PASS] test_RemoveLiquidity_Partial_ToRecipient() (gas: 283214)\n[PASS] test_RemoveLiquidity_RevertBelowMin0() (gas: 214253)\n[PASS] test_RemoveLiquidity_RevertBelowMin1() (gas: 214259)\n[PASS] test_RemoveLiquidity_RevertInsufficientBalance() (gas: 217338)\n[PASS] test_RemoveLiquidity_RevertZeroOutput() (gas: 199866)\n[PASS] test_RemoveLiquidity_RevertZeroShares() (gas: 212475)\n[PASS] test_RemoveLiquidity_RoundsDown() (gas: 210749)\n[PASS] test_RemoveLiquidity_StateUnchangedAfterRevert() (gas: 217585)\n[PASS] test_Skim_NothingToSkimIsNoop() (gas: 227770)\n[PASS] test_Skim_OnlyOneTokenInExcess() (gas: 257162)\n[PASS] test_Skim_SendsExcessToRecipient() (gas: 297077)\n[PASS] test_Skim_ThenSyncLeavesReservesUnchanged() (gas: 257409)\n[PASS] test_Swap_ExactFormulaSmallNumbers() (gas: 229271)\n[PASS] test_Swap_RevertBelowMinOut() (gas: 218133)\n[PASS] test_Swap_RevertEmptyPool() (gas: 21065)\n[PASS] test_Swap_RevertFeeOnTransfer() (gas: 1835785)\n[PASS] test_Swap_RevertUnknownToken() (gas: 630505)\n[PASS] test_Swap_RevertWithoutAllowance() (gas: 257076)\n[PASS] test_Swap_RevertZeroAmountIn() (gas: 217060)\n[PASS] test_Swap_RevertZeroOutputFromRounding() (gas: 209530)\n[PASS] test_Swap_Token0In() (gas: 265470)\n[PASS] test_Swap_Token1In_ToRecipient() (gas: 274715)\n[PASS] test_Swap_UsesReservesNotBalances() (gas: 253292)\n[PASS] test_Sync_EmptyPoolIsNoop() (gas: 27648)\n[PASS] test_Sync_RevertReserveOverflow() (gas: 55381)\n[PASS] test_Sync_SetsReservesToBalances() (gas: 242827)\nSuite result: ok. 70 passed; 0 failed; 0 skipped; finished in 20.56s (64.04ms CPU time)\n\nRan 5 tests for test/invariant/CPPair.invariant.t.sol:CPPairInvariantTest\n[PASS] invariant_deadSharesKeepPoolAlive() (runs: 1000, calls: 100000, reverts: 0)\n\n╭---------------+-----------------+-------+---------+----------╮\n| Contract      | Selector        | Calls | Reverts | Discards |\n+==============================================================+\n| CPPairHandler | addLiquidity    | 11054 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | donate          | 11354 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeAll       | 10952 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeLiquidity | 11166 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | skim            | 11124 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swap            | 11118 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swapRoundTrip   | 11040 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | sync            | 11043 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | transferShares  | 11149 | 0       | 0        |\n╰---------------+-----------------+-------+---------+----------╯\n\n[PASS] invariant_lockReleasedAndQuoteConsistent() (runs: 1000, calls: 100000, reverts: 0)\n\n╭---------------+-----------------+-------+---------+----------╮\n| Contract      | Selector        | Calls | Reverts | Discards |\n+==============================================================+\n| CPPairHandler | addLiquidity    | 11054 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | donate          | 11354 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeAll       | 10952 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeLiquidity | 11166 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | skim            | 11124 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swap            | 11118 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swapRoundTrip   | 11040 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | sync            | 11043 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | transferShares  | 11149 | 0       | 0        |\n╰---------------+-----------------+-------+---------+----------╯\n\n[PASS] invariant_reservesNeverExceedBalances() (runs: 1000, calls: 100000, reverts: 0)\n\n╭---------------+-----------------+-------+---------+----------╮\n| Contract      | Selector        | Calls | Reverts | Discards |\n+==============================================================+\n| CPPairHandler | addLiquidity    | 11054 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | donate          | 11354 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeAll       | 10952 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeLiquidity | 11166 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | skim            | 11124 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swap            | 11118 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swapRoundTrip   | 11040 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | sync            | 11043 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | transferShares  | 11149 | 0       | 0        |\n╰---------------+-----------------+-------+---------+----------╯\n\n[PASS] invariant_shareValueNeverBelowInitial() (runs: 1000, calls: 100000, reverts: 0)\n\n╭---------------+-----------------+-------+---------+----------╮\n| Contract      | Selector        | Calls | Reverts | Discards |\n+==============================================================+\n| CPPairHandler | addLiquidity    | 11054 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | donate          | 11354 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeAll       | 10952 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeLiquidity | 11166 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | skim            | 11124 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swap            | 11118 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swapRoundTrip   | 11040 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | sync            | 11043 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | transferShares  | 11149 | 0       | 0        |\n╰---------------+-----------------+-------+---------+----------╯\n\n[PASS] invariant_supplyMatchesHolders() (runs: 1000, calls: 100000, reverts: 0)\n\n╭---------------+-----------------+-------+---------+----------╮\n| Contract      | Selector        | Calls | Reverts | Discards |\n+==============================================================+\n| CPPairHandler | addLiquidity    | 11054 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | donate          | 11354 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeAll       | 10952 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | removeLiquidity | 11166 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | skim            | 11124 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swap            | 11118 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | swapRoundTrip   | 11040 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | sync            | 11043 | 0       | 0        |\n|---------------+-----------------+-------+---------+----------|\n| CPPairHandler | transferShares  | 11149 | 0       | 0        |\n╰---------------+-----------------+-------+---------+----------╯\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 21.39s (101.49s CPU time)\n\nRan 2 test suites in 21.40s (41.96s CPU time): 75 tests passed, 0 failed, 0 skipped (75 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c0e4c264776ea1630277bc4a4b86463303c9f4ef1abbd24ab4bd7dcdee247760","verifiedTreeHash":"327d07ca3e92721cd4c838ac8cc8b2179d864fbf","verifierVersion":"0.1.0+ff982c0f"},{"checks":[{"durationMs":1302,"exitCode":0,"name":"build","output":"Compiling 24 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.22s\nCompiler run successful!\nwarning: unknown id: 'reentrancy-no-eth'\n    ╭▸ src/CPPair.sol:400:9\n    │\n400 │         // forge-lint: disable-next-line(reentrancy-no-eth)\n    ╰╴        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:130:19\n    │\n130 │         emit Sync(uint112(a0), uint112(a1));\n    │                   ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:130:32\n    │\n130 │         emit Sync(uint112(a0), uint112(a1));\n    │                                ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:393:19\n    │\n393 │         emit Sync(uint112(1000e18 - expect0), uint112(4000e18 - expect1));\n    │                   ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:393:47\n    │\n393 │         emit Sync(uint112(1000e18 - expect0), uint112(4000e18 - expect1));\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:521:19\n    │\n521 │         emit Sync(uint112(1000e18 + amountIn), uint112(4000e18 - expectedOut));\n    │                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/CPPair.t.sol:521:48\n    │\n521 │         emit Sync(uint112(1000e18 + amountIn), uint112(4000e18 - expectedOut));\n    │                                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint112' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n    ╭▸ test/CPPair.t.sol:616:9\n    │\n616 │         tokenA.transfer(address(feePair), 100e18);\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/CPPair.t.sol:617:9\n    │\n617 │         fee.transfer(address(feePair), 100e18);\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/CPPair.t.sol:882:9\n    │\n882 │         pair.transfer(bob, shares + 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/CPPair.t.sol:889:9\n    │\n889 │         pair.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/CPPair.t.sol:912:9\n    │\n912 │         pair.transferFrom(alice, carol, 4e18);\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/CPPair.t.sol:922:9\n    │\n922 │         pair.transferFrom(alice, carol, 1e18 + 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/CPPair.t.sol:929:9\n    │\n929 │         pair.transfer(bob, shares);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\n","passed":true},{"durationMs":92,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 70 tests for test/CPPair.t.sol:CPPairTest\n[PASS] testFuzz_AddLiquidity_SubsequentSharesFormula(uint256,uint256) (runs: 256, μ: 275694, ~: 279098)\nLogs:\n  Bound result 2506\n  Bound result 2\n\n[PASS] testFuzz_Swap_MatchesFormulaAndPreservesK(uint256,bool) (runs: 256, μ: 258343, ~: 259270)\nLogs:\n  Bound result 25272\n\n[PASS] test_AddLiquidity_FirstDeposit() (gas: 235601)\n[PASS] test_AddLiquidity_FirstDeposit_BoundaryJustAboveMinimum() (gas: 194455)\n[PASS] test_AddLiquidity_FirstDeposit_MintsToRecipient() (gas: 216025)\n[PASS] test_AddLiquidity_FirstDeposit_TakesFullAmountsEvenWhenUnbalanced() (gas: 224717)\n[PASS] test_AddLiquidity_RevertFeeOnTransfer() (gas: 1829636)\n[PASS] test_AddLiquidity_RevertFirstDeposit_BelowMinShares() (gas: 84536)\n[PASS] test_AddLiquidity_RevertFirstDeposit_SqrtEqualToMinimum() (gas: 24155)\n[PASS] test_AddLiquidity_RevertFirstDeposit_SqrtRoundsDownToMinimum() (gas: 24383)\n[PASS] test_AddLiquidity_RevertFirstDeposit_ZeroAmount() (gas: 20926)\n[PASS] test_AddLiquidity_RevertReserveOverflow() (gas: 241049)\n[PASS] test_AddLiquidity_RevertWithoutAllowance() (gas: 208091)\n[PASS] test_AddLiquidity_RevertZeroRecipient() (gas: 81852)\n[PASS] test_AddLiquidity_Subsequent_ExactMinSharesSucceeds() (gas: 270642)\n[PASS] test_AddLiquidity_Subsequent_MintsMinOfBothRatios() (gas: 270426)\n[PASS] test_AddLiquidity_Subsequent_RevertBelowMinShares() (gas: 216327)\n[PASS] test_AddLiquidity_Subsequent_RevertZeroShares() (gas: 207836)\n[PASS] test_AddLiquidity_Subsequent_RoundsDown() (gas: 256363)\n[PASS] test_AddLiquidity_Subsequent_Token0IsBinding() (gas: 286748)\n[PASS] test_AddLiquidity_Subsequent_Token1IsBinding() (gas: 278857)\n[PASS] test_AddLiquidity_Subsequent_UsesReservesNotBalances() (gas: 284805)\n[PASS] test_Constructor_Metadata() (gas: 29116)\n[PASS] test_Constructor_RevertIdenticalTokens() (gas: 61739)\n[PASS] test_Constructor_RevertZeroToken0() (gas: 61624)\n[PASS] test_Constructor_RevertZeroToken1() (gas: 61784)\n[PASS] test_ERC20_ApproveAndTransferFrom() (gas: 274775)\n[PASS] test_ERC20_Transfer() (gas: 243235)\n[PASS] test_ERC20_TransferFromInfiniteAllowanceNotDecremented() (gas: 265685)\n[PASS] test_ERC20_TransferFromRevertInsufficientAllowance() (gas: 239590)\n[PASS] test_ERC20_TransferRevertInsufficientBalance() (gas: 211666)\n[PASS] test_ERC20_TransferRevertZeroAddress() (gas: 209217)\n[PASS] test_ERC20_TransferredSharesAreRedeemable() (gas: 232642)\n[PASS] test_Lifecycle_BalancesTrackReserves() (gas: 315708)\n[PASS] test_Quote_EmptyPoolReturnsZero() (gas: 17217)\n[PASS] test_Quote_RevertUnknownToken() (gas: 8794)\n[PASS] test_Reentrancy_AddLiquidityBlocked() (gas: 2270946)\n[PASS] test_Reentrancy_GuardResetsAfterCall() (gas: 2226169)\n[PASS] test_Reentrancy_RemoveLiquidityBlocked() (gas: 2360920)\n[PASS] test_Reentrancy_SkimBlocked() (gas: 2282615)\n[PASS] test_Reentrancy_SwapPullBlocked() (gas: 2409070)\n[PASS] test_Reentrancy_SwapPushBlocked() (gas: 2338239)\n[PASS] test_RemoveLiquidity_AllOwnShares() (gas: 231747)\n[PASS] test_RemoveLiquidity_IgnoresDonatedBalance() (gas: 219821)\n[PASS] test_RemoveLiquidity_Partial_ToRecipient() (gas: 283214)\n[PASS] test_RemoveLiquidity_RevertBelowMin0() (gas: 214253)\n[PASS] test_RemoveLiquidity_RevertBelowMin1() (gas: 214259)\n[PASS] test_RemoveLiquidity_RevertInsufficientBalance() (gas: 217338)\n[PASS] test_RemoveLiquidity_RevertZeroOutput() (gas: 199866)\n[PASS] test_RemoveLiquidity_RevertZeroShares() (gas: 212475)\n[PASS] test_RemoveLiquidity_RoundsDown() (gas: 210749)\n[PASS] test_RemoveLiquidity_StateUnchangedAfterRevert() (gas: 217585)\n[PASS] test_Skim_NothingToSkimIsNoop() (gas: 227770)\n[PASS] test_Skim_OnlyOneTokenInExcess() (gas: 257162)\n[PASS] test_Skim_SendsExcessToRecipient() (gas: 297077)\n[PASS] test_Skim_ThenSyncLeavesReservesUnchanged() (gas: 257409)\n[PASS] test_Swap_ExactFormulaSmallNumbers() (gas: 229271)\n[PASS] test_Swap_RevertBelowMinOut() (gas: 218133)\n[PASS] test_Swap_RevertEmptyPool() (gas: 21065)\n[PASS] test_Swap_RevertFeeOnTransfer() (gas: 1835785)\n[PASS] test_Swap_RevertUnknownToken() (gas: 630505)\n[PASS] test_Swap_RevertWithoutAllowance() (gas: 257076)\n[PASS] test_Swap_RevertZeroAmountIn() (gas: 217060)\n[PASS] test_Swap_RevertZeroOutputFromRounding() (gas: 209530)\n[PASS] test_Swap_Token0In() (gas: 265470)\n[PASS] test_Swap_Token1In_ToRecipient() (gas: 274715)\n[PASS] test_Swap_UsesReservesNotBalances() (gas: 253292)\n[PASS] test_Sync_EmptyPoolIsNoop() (gas: 27648)\n[PASS] test_Sync_RevertReserveOverflow() (gas: 55381)\n[PASS] test_Sync_SetsReservesToBalances() (gas: 242827)\nSuite result: ok. 70 passed; 0 failed; 0 skipped; finished in 18.75ms (65.07ms CPU time)\n\nRan 1 test suite in 19.78ms (18.75ms CPU time): 70 tests passed, 0 failed, 0 skipped (70 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"e610e226873709df8ad4fd24dd3cb28651f754cab150c9e91fe575487cb82756","verifiedTreeHash":"0e5c37293289e9460d8cff037dadb8abbeec40b3","verifierVersion":"0.1.0+ff982c0f"}]}