{"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":"9a462f85-b582-4b1d-b946-eed28887d8a9","kind":"skill:build-contract-project","nodes":[{"acceptedSubmissionHash":"2aeb36dc394f9b602bd63dae8a5847e0985cabbcdf48860ac80895e81ef366dc","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","state":"accepted"}],"objective":"A Uniswap v4 hook: Build UNLOCK (UNLK), \"The $5M Unlock Experiment\", as a compilable, tested Foundry source project and publish it to GitHub. THIS REQUEST IS CODE AND TESTS ONLY: Deploy onchain is OFF. Do not deploy to any public network, create a live token/pool, require signing keys, or require future live addresses or reward allocations. Website and public-network release are separate later tasks. Deliver repository URL and exact commit, source, ABIs, pinned dependencies, reproducible build/test commands and results. Do not replace implementation with a plan or a blocked-input note.\n\nFuture integration target, not a deployment request: IMD univ4_hook, 87% pool share, initially tested on Sepolia and later separately released on Ethereum mainnet. Inspect available official factory/router/distributor interfaces. Parameterize chain-specific dependencies through constructors or authenticated one-time setup, with no later admin changes. Hook must be attached when the official pool is initialized. Never use a plain pool or unattached hook as an equivalent. If an IMD interface is unavailable, implement and test independent core logic, isolate the integration boundary, and document the exact missing interface. Clearly label mocks and unverified adapters; do not claim production compatibility. Missing release credentials/addresses alone must not stop code development. The following rules specify the intended contract behavior and future launch economics.\n\nToken: standard ERC-20, 1 billion UNLK, 18 decimals, minted once. 10% IMD swarm, 87% official pool, 3% paying wallet. Ordinary transfers remain free of token-level taxes/quotas/blacklists/pausing. No later minting, upgrades, admin rule/oracle changes, counter resets or trader exemptions. Preserve IMD opening economics. Hook takes no additional fee; retain the mandatory 1.25% pool trading fee, split 1% to the paying wallet and 0.25% to IMD through official fee distribution.\n\nCallbacks: beforeInitialize authenticates the authorized launch factory and binds the pool once. beforeSwap authenticates the supported route and actual trader; afterSwap checks quotas and records actual executed token deltas atomically, reverting excess sales. Only canonical PoolManager invokes callbacks. Use matching hook address permission flags. Keep security-critical initialization available while allowing no later admin changes. Public users may trade, read, claim eligible rewards, synchronize proven credits and request contract-verified milestone updates.\n\nPer wallet E=cumulative eligible acquisitions, S=cumulative official-pool sales. E credits only actual official-pool buys delivered to the authenticated beneficiary, the verified 3% payer allocation, and rewards actually claimed. Verify allocations/claims on-chain from immutable launch/distributor data or authenticated callbacks; deduplicate credits. Anyone may synchronize proofs to their rightful recipient, never select amounts/recipients. User-supplied logs are not proof. Preserve IMD eligibility/proof/release rules; claiming has no added price/quota restriction. Credit-sync failure cannot block native claims. Expose pending credits; unclaimed rewards are not E.\n\nInitially p=2500. Before full unlock Q=max(0,floor(E*p/10000)-S). Sale q requires S+q<=floor(E*p/10000), then increments S by executed tokens. Use overflow-safe math and documented fee accounting; reverted swaps change nothing. Other wallets cannot consume Q. Ordinary transfers, donations and liquidity operations do not credit/move/reset E or S; the three authenticated acquisition types above do credit E. A transfer-only recipient with E=0 cannot sell here until acquiring rights or final unlock. Disclose this and prevent transfer-chain credit creation.\n\nVerified USD FDV thresholds permanently raise p: $100K:3500; $250K:4500; $500K:5500; $1M:7000; $2.5M:8500. At $5M permanently bypass quota checks for everyone, including transfer-only recipients; p=10000 alone is insufficient. Retain standard fees/settlement/authentication. Falling prices never relock.\n\nAuthenticate actual token-paying sellers and receiving buyers and enforce sourcing/delivery. Never trust tx.origin, callback sender alone or arbitrary hookData. Signed intents need domain/transaction binding, replay protection and supported smart-wallet validation. Reject direct/router paths bypassing or misattributing rights; enforce this on-chain.\n\nFDV=fixed supply times verified UNLK/USD. Use a chain-specific verified Chainlink ETH/USD feed plus an implemented on-chain UNLK/ETH time-weighted oracle; assume neither a UNLK feed nor built-in v4 TWAP. Pin/review window, warm-up, freshness, liquidity floor and sustained-threshold confirmation. Test flash-loan/same-block/sustained manipulation. Invalid data blocks new tiers only. Permanently protect initial liquidity principal using verified IMD protection or a compatible lock; preserve fee collection and reward claims. Inspect withdrawal rights, not just labels.\n\nDeliver contracts, Foundry configuration with bytecode_hash = \"none\", pinned dependencies, ABIs, local deployment scripts and integration documentation. Test launch/router/distributor interactions, callbacks, exact-input/output, currency ordering, multihop/multiple swaps, fee deltas, quota boundaries, spoofing/replay/bypass, transfers, duplicate credits, claim/sync/sale, liquidity, oracle attacks/failure and permanent unlock with unit/fuzz/invariant tests and available fork tests. Use explicitly labeled local fixtures for tokens, rewards and oracle scenarios; never substitute them for production evidence. Report executed commands/results, skipped tests and missing inputs. Provide a review checklist; only claim independent review if a separate reviewer actually performed it. Record unresolved findings and prohibit release with critical/high findings. Document future hook-address mining, deployment order, chain-specific configuration, required IMD manifest fields where verified, and post-deployment PoolKey/credit/liquidity checks. This job completes with implemented source, tests and a GitHub handoff, not mainnet addresses or transaction hashes; explicitly list unfinished integration work.\n\nToken name: UNLK","parentJobId":null,"planHash":"b3f3874af5ba2e0cf1077e4b20b07d4bdd0248008bd3b046d211c817494c1a26","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"9a462f85-b582-4b1d-b946-eed28887d8a9","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1309-unlk"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52584","feedbackHash":"76bfff1cc0b71cf47160609d7d47525d329d029543662154608784104a2c0475","nodeKey":"build_contract_project","submissionHash":"9fe6070fa36a93e21a237824f95eb21948475d55baf178f6dbbf861120cb6d3b","tag1":"verification:checks","tag2":"acceptance-v2","value":0},{"agentId":"51503","feedbackHash":"49da08f5acdd6aeb57f2da18ec2437c9e25564b50db8a7eec6185bcb583d61d4","nodeKey":"build_contract_project","submissionHash":"2aeb36dc394f9b602bd63dae8a5847e0985cabbcdf48860ac80895e81ef366dc","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"fbb9efda6a38a420e34f59a30f6094ce96a45648de563b6a6ff4f78d8857ac17","state":"completed","submissions":[{"artifacts":[],"attempt":2,"bundleHash":"f1bc543d9724fc8a27ceb3f70f4f9b7842f38bdc264f0ed7d2dfe6f3f8ee8a08","device":"c1fc321231608a52","findings":[],"hash":"2aeb36dc394f9b602bd63dae8a5847e0985cabbcdf48860ac80895e81ef366dc","nodeId":"8dcbf835-7707-409c-8c8e-1094839433cf","outcome":"completed","summary":"Implemented the [Foundry project](README.md) with contracts, pinned dependencies, 12 ABIs, local scripts and documentation.\n\n- Build, formatting and **113 tests pass**.\n- [Validation results](docs/VALIDATION.md) and [release blockers](docs/SECURITY_REVIEW.md) are recorded.\n- No onchain deployment occurred. Official IMD integration remains unverified.\n\n[GitHub publication](docs/GITHUB_HANDOFF.md) and an exact commit remain pending: no destination/access was supplied, and `.git/` changes are prohibited.","treeHash":"9286579fcd3f7864f34541f865826c4418940d1c","usage":{"cachedInputTokens":10725888,"inputTokens":230893,"model":"gpt-6-astra","outputTokens":103659,"runtime":"codex","turns":13,"wallClockMs":3943464}},{"artifacts":[],"attempt":1,"bundleHash":"1246b5590097d71a6f832d434cc7e141036f436585486af3a933dc48d8e1cd7d","device":"6f41bd9b44d3e708","findings":[],"hash":"9fe6070fa36a93e21a237824f95eb21948475d55baf178f6dbbf861120cb6d3b","nodeId":"8dcbf835-7707-409c-8c8e-1094839433cf","outcome":"completed","summary":"I built the UNLK token, the v4 hook, a swap router and a liquidity lock as a Foundry project, and all checks pass. I did not commit or push to GitHub, so I can't give you a repository URL or commit hash: the task rules forbid touching `.git/`, and I'm assuming the platform's upload step publishes it.\n\n**Checks (run locally just now):**\n- `forge build`: compiles with solc 0.8.26, `bytecode_hash = \"none\"`.\n- `forge fmt --check`: clean.\n- `forge test`: 60 passed, 0 failed, 0 skipped across 6 suites, including a 256-run fuzz test and 3 invariants (64 runs × depth 32).\n- Fork tests were not run: there is no network at verification time and the real Uniswap PoolManager isn't vendored.\n\n**What's in the repo:**\n- **Contracts** in `src/`:\n  - `UnlkToken`: plain ERC-20, 1B UNLK minted once 10/87/3, no owner or taxes.\n  - `UnlkHook`: per-wallet credits (E) and sales (S), the sale quota, and price milestones.\n  - `UnlkSwapRouter`: the only route the hook accepts, including signed swaps for normal and smart-contract wallets.\n  - `UnlkLiquidityLock`: launch liquidity can never be withdrawn; collected fees split 1% to the paying wallet and 0.25% to IMD.\n- **ABIs** in `abi/`.\n- **Local deploy script** in `script/DeployLocal.s.sol`, which the tests also use. It runs against local mocks only.\n- **`README.md`**: behaviour, fee accounting, constructor parameters and where each value comes from, deployment order with hook-address mining, post-launch checks, open integration items, a review checklist and self-review findings.\n\n**Limitations you should know about:**\n1. **No real Uniswap v4 dependency.** I couldn't fetch v4-core or forge-std, so the v4 types and math are hand-copied into `src/v4/V4Types.sol` and `src/libraries/`. Tests run only against a simplified mock PoolManager, clearly labelled as a local fixture. Production compatibility is not claimed; the code must be checked against a pinned v4-core and re-tested on the real PoolManager (including Sepolia fork tests) before release.\n2. **IMD interfaces were unavailable** for the univ4_hook factory, swarm distributor and liquidity protection. The integration boundary is isolated, and the exact interface the hook needs from the distributor (`token()` plus a cumulative `claimedAmount(address)`) is documented. The liquidity lock is a compatible stand-in, not the IMD protection contract.\n3. **Addresses are unverified.** The Chainlink ETH/USD feed and PoolManager addresses for Sepolia and mainnet were not checked on-chain. They are constructor arguments, listed in the README as unverified.\n4. **No independent review was done.** The README forbids release while that, or any critical/high finding, is open.\n5. **Oracle settings need economic review.** These are a 30-minute average, 1-hour warm-up, 1-hour sustained confirmation and the liquidity floor, all pinned as constants.\n\nBash was unavailable for part of the session because of a sandbox error, so some code was written before I could compile it; everything was compiled and tested afterwards. The sandbox also left placeholder entries in the repo root (`.bashrc`, `.gitmodules`, `.claude/` and others, all `/dev/null` device nodes). I didn't create them and haven't deleted them, but they need removing before publishing: in particular, a `.gitmodules` entry must not be shipped.","treeHash":"ebb8026be9a88273b43da7d4ed543d14af5399f5","usage":{"cachedInputTokens":5131426,"inputTokens":80,"model":"claude-opus-5-5","outputTokens":150387,"runtime":"claude","turns":67,"wallClockMs":1468961}}],"verification":[{"checks":[{"durationMs":7761,"exitCode":0,"name":"build","output":"Compiling 101 files with Solc 0.8.26\nSolc 0.8.26 finished in 7.62s\nCompiler run successful!\n","passed":true},{"durationMs":2269,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/Launch.t.sol:InitializationGuardTest\n[PASS] testFactoryCannotBindWrongFeeOrTickSpacing() (gas: 125425)\n[PASS] testForeignCallerCannotConfigureUnsetRouter() (gas: 32985)\n[PASS] testOnlyFactoryCanInitializeUnboundOfficialPool() (gas: 433107)\n[PASS] testUnboundCreditsCannotBeSynchronized() (gas: 84964)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 25.72ms (1.03ms CPU time)\n\nRan 8 tests for test/Adversarial.t.sol:AdversarialTest\n[PASS] test100PercentAloneIsNotFullUnlock() (gas: 7256770)\n[PASS] testArbitraryHookDataAndMultihopPayloadCannotSelectVictim() (gas: 87388)\n[PASS] testCallbacksAllRequireCanonicalManager() (gas: 211542)\n[PASS] testForeignPoolKeyRejectedEvenWithManagerPrank() (gas: 49892)\n[PASS] testNoMintPauseBlacklistUpgradeOrCounterResetEntrypoint() (gas: 121431)\n[PASS] testProtocolFeeChangeCannotSilentlyAlterTradingEconomics() (gas: 385924)\n[PASS] testQuotaMultiplicationDoesNotOverflowAtMaxEligible() (gas: 242062)\n[PASS] testZeroAndOverlappingAllocationRecipientsRejected() (gas: 8245)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 38.21ms (8.44ms CPU time)\n\nRan 7 tests for test/Launch.t.sol:LaunchTest\n[PASS] testLaunchAllocationAndLockedPrincipal() (gas: 119083)\n[PASS] testOneTimeSetup() (gas: 93188)\n[PASS] testOnlyCanonicalManagerCanCallHook() (gas: 66561)\n[PASS] testOnlyFactorySeedsOnce() (gas: 69027)\n[PASS] testPayerCreditExactDeduplicated() (gas: 144218)\n[PASS] testUnauthorizedFactoryAndWrongPoolRejected() (gas: 86754)\n[PASS] testUnconfiguredComponentsFailClosed() (gas: 39600)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 44.86ms (902.68µs CPU time)\n\nRan 2 tests for test/ReleaseConfig.t.sol:ReleaseConfigTest\n[PASS] testReadOnlyReleaseChecksOnLocalFixture() (gas: 1322752)\n[PASS] testReadOnlyReleaseChecksRejectWrongChainOrHash() (gas: 1246830)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 45.29ms (321.24µs CPU time)\n\nRan 10 tests for test/CreditsAndFees.t.sol:CreditsAndFeesTest\n[PASS] testClaimTransferAndPayerTransferDoNotDuplicateCredit() (gas: 464151)\n[PASS] testCreditEvidenceFailureCannotBlockNativeClaim() (gas: 789606)\n[PASS] testFeeCollectionDoesNotReducePrincipal() (gas: 650415)\n[PASS] testNativeClaimThenSyncThenSale() (gas: 1162732)\n[PASS] testNegativeLiquidityForbiddenEvenForVault() (gas: 80138)\n[PASS] testPoolFee125BpsNoHookFeeAndDistribution80_20() (gas: 799070)\n[PASS] testProofReleaseAndDedupRemainNativeRules() (gas: 380904)\n[PASS] testSaleFeesCountGrossInputAndNeverCreditFeeRecipients() (gas: 1133118)\n[PASS] testUnauthorizedLiquidityAndDonationNoCredit() (gas: 241872)\n[PASS] testUnclaimedRewardsNotEligible() (gas: 46017)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 106.42ms (5.16ms CPU time)\n\nRan 2 tests for test/LocalScript.t.sol:LocalScriptTest\n[PASS] testLocalScriptRefusesPublicChainId() (gas: 9049346)\n[PASS] testLocalSimulationFunctionDoesNotDependOnCaller() (gas: 46754758)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 109.11ms (59.35ms CPU time)\n\nRan 16 tests for test/Trading.t.sol:TradingTest\n[PASS] testAnotherWalletCannotConsumeVictimsAllowanceOrQuota() (gas: 484794)\n[PASS] testBatchBuysThenSellsAndRollbackExcess() (gas: 1653212)\n[PASS] testDirectManagerAndForeignRouterSpoofingRejected() (gas: 642450)\n[PASS] testDirectSmartWalletOwnsRightsNotItsOwner() (gas: 704424)\n[PASS] testDonatedRouterBalancesCannotCreateCreditOrBeSwept() (gas: 491430)\n[PASS] testExactInputBuyCreditsOnlyDeliveredTokens() (gas: 456000)\n[PASS] testExactOutputBuyAndRefund() (gas: 398402)\n[PASS] testExactOutputSaleAccountsActualInput() (gas: 723612)\n[PASS] testExcessSaleRollsBackPoolBalancesOracleAndNonce() (gas: 810752)\n[PASS] testFuzzQuotaBoundary(uint96) (runs: 256, μ: 1020458, ~: 1020660)\nLogs:\n  Bound result 1745325848416156399\n\n[PASS] testPartialExactOutputRejectedAtomically() (gas: 444207)\n[PASS] testPartialInputFillCreditsOnlyExecutedBuy() (gas: 393016)\n[PASS] testReplayOldCallbackHasNoLiveContext() (gas: 429634)\n[PASS] testSaleBoundaryExecutedInputIncludesPoolFee() (gas: 1049980)\n[PASS] testSlippageDeadlineAndNativeValueRejected() (gas: 522731)\n[PASS] testTransfersDoNotMoveRightsOrAllowChainCredit() (gas: 824999)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 109.17ms (94.42ms CPU time)\n\nRan 14 tests for test/Oracle.t.sol:OracleTest\n[PASS] testBadChainlinkRoundsAndAnswersFailClosed() (gas: 2341065)\n[PASS] testConfirmationGapRestartsRatherThanCountingUnobservedTime() (gas: 2831351)\n[PASS] testEveryTierAndPermanentUnlock() (gas: 16145814)\n[PASS] testFallingPricesNeverLowerReachedTier() (gas: 5024951)\n[PASS] testFlashLoanCannotCrossMilestoneInItsTransaction() (gas: 1583869)\n[PASS] testInvalidDataResetsUnfinishedConfirmation() (gas: 3129225)\n[PASS] testNegativeTickAveragesRoundConservativelyForBothOrders() (gas: 777458)\n[PASS] testOneBlockSpikeCannotConfirm() (gas: 765512)\n[PASS] testOracleCannotBeReboundOrConfiguredByAnyone() (gas: 98402)\n[PASS] testSameTimestampManipulationHasNoTimeWeight() (gas: 787582)\n[PASS] testStaleCheckpointAndFeedPreventNewTierButNotTrades() (gas: 1321033)\n[PASS] testSustainedManipulationRequiresWindowAndConfirmation() (gas: 3152696)\n[PASS] testThresholdMappingBoundaries() (gas: 104606)\n[PASS] testWarmupAndExactWindow() (gas: 382127)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 109.15ms (29.27ms CPU time)\n\nRan 16 tests for test/Trading.t.sol:Token0TradingTest\n[PASS] testAnotherWalletCannotConsumeVictimsAllowanceOrQuota() (gas: 483456)\n[PASS] testBatchBuysThenSellsAndRollbackExcess() (gas: 1648852)\n[PASS] testDirectManagerAndForeignRouterSpoofingRejected() (gas: 643277)\n[PASS] testDirectSmartWalletOwnsRightsNotItsOwner() (gas: 703525)\n[PASS] testDonatedRouterBalancesCannotCreateCreditOrBeSwept() (gas: 490303)\n[PASS] testExactInputBuyCreditsOnlyDeliveredTokens() (gas: 454873)\n[PASS] testExactOutputBuyAndRefund() (gas: 395954)\n[PASS] testExactOutputSaleAccountsActualInput() (gas: 720826)\n[PASS] testExcessSaleRollsBackPoolBalancesOracleAndNonce() (gas: 809149)\n[PASS] testFuzzQuotaBoundary(uint96) (runs: 256, μ: 1017960, ~: 1018323)\nLogs:\n  Bound result 1999999001800000001\n\n[PASS] testPartialExactOutputRejectedAtomically() (gas: 443029)\n[PASS] testPartialInputFillCreditsOnlyExecutedBuy() (gas: 392091)\n[PASS] testReplayOldCallbackHasNoLiveContext() (gas: 428926)\n[PASS] testSaleBoundaryExecutedInputIncludesPoolFee() (gas: 1047935)\n[PASS] testSlippageDeadlineAndNativeValueRejected() (gas: 521699)\n[PASS] testTransfersDoNotMoveRightsOrAllowChainCredit() (gas: 823396)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 151.13ms (96.99ms CPU time)\n\nRan 14 tests for test/Oracle.t.sol:Token0OracleTest\n[PASS] testBadChainlinkRoundsAndAnswersFailClosed() (gas: 2335951)\n[PASS] testConfirmationGapRestartsRatherThanCountingUnobservedTime() (gas: 2825107)\n[PASS] testEveryTierAndPermanentUnlock() (gas: 16111725)\n[PASS] testFallingPricesNeverLowerReachedTier() (gas: 5014109)\n[PASS] testFlashLoanCannotCrossMilestoneInItsTransaction() (gas: 1566291)\n[PASS] testInvalidDataResetsUnfinishedConfirmation() (gas: 3122147)\n[PASS] testNegativeTickAveragesRoundConservativelyForBothOrders() (gas: 775506)\n[PASS] testOneBlockSpikeCannotConfirm() (gas: 763336)\n[PASS] testOracleCannotBeReboundOrConfiguredByAnyone() (gas: 98858)\n[PASS] testSameTimestampManipulationHasNoTimeWeight() (gas: 785384)\n[PASS] testStaleCheckpointAndFeedPreventNewTierButNotTrades() (gas: 1317490)\n[PASS] testSustainedManipulationRequiresWindowAndConfirmation() (gas: 3145505)\n[PASS] testThresholdMappingBoundaries() (gas: 104606)\n[PASS] testWarmupAndExactWindow() (gas: 381293)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 151.23ms (25.34ms CPU time)\n\nRan 11 tests for test/NativeLaunch.t.sol:NativeWithdrawalTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 3316130)\n[PASS] testNativeBatchSettlement() (gas: 855315)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1093448)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 444285)\n[PASS] testNativeSettlementResetsPriorSyncCurrency() (gas: 600374)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 94883)\n[PASS] testNativeWithdrawalUsesCEIAndCannotDoubleWithdraw() (gas: 994708)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 31704)\n[PASS] testOtherWalletCannotWithdrawNativeRefund() (gas: 456489)\n[PASS] testRejectingNativeWalletCanTradeAndRetryWithdrawal() (gas: 1070160)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 4804742)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 157.29ms (9.57ms CPU time)\n\nRan 7 tests for test/NativeLaunch.t.sol:NativeLaunchTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 3316128)\n[PASS] testNativeBatchSettlement() (gas: 855315)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1093437)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 444196)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 94905)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 31726)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 4804742)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 179.18ms (6.45ms CPU time)\n\nRan 1 test for test/Invariants.t.sol:FullyUnlockedInvariantTest\n[PASS]\nFullyUnlockedInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n[PASS] invariantUnlockRemainsPermanentDespiteInvalidFeed\n FullyUnlockedInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 809   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 845   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 873   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 888   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 827   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 878   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 14333\n  Bound result 122\n  Bound result 91\n  Bound result 124\n  Bound result 190\n  Bound result 12029\n  Bound result 17141\n  Bound result 24\n  Bound result 166323839982266600\n  Bound result 295\n  Bound result 3792478066\n  Bound result 499999000000000529\n  Bound result 13970\n  Bound result 129\n  Bound result 294\n  Bound result 146339723262671417\n  Bound result 4421\n  Bound result 5039\n  Bound result 499999000000007521\n  Bound result 499999000000016109\n  Bound result 15154735922275213491976462\n  Bound result 1800009657\n  Bound result 499999000000002543\n  Bound result 7025\n  Bound result 349\n  Bound result 163617974793515397\n  Bound result 499999000016776961\n  Bound result 1261\n  Bound result 18315\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.94s (1.87s CPU time)\n\nRan 1 test for test/Invariants.t.sol:SystemInvariantTest\n[PASS]\nSystemInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n SystemInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 809   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 845   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 873   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 888   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 827   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 878   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 13275\n  Bound result 61\n  Bound result 91\n  Bound result 124\n  Bound result 190\n  Bound result 12028\n  Bound result 98\n  Bound result 166323839982266600\n  Bound result 295\n  Bound result 827\n  Bound result 499999000000000444\n  Bound result 19501\n  Bound result 129\n  Bound result 294\n  Bound result 146339723262671417\n  Bound result 418630442\n  Bound result 4749\n  Bound result 499999000000007146\n  Bound result 499999000000005806\n  Bound result 12039016488997419948171873\n  Bound result 29999999999999999999988800\n  Bound result 499999000000002398\n  Bound result 6513\n  Bound result 292\n  Bound result 163617974793515397\n  Bound result 499999000000000956\n  Bound result 1356\n  Bound result 5247\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.09s (2.04s CPU time)\n\nRan 14 test suites in 2.10s (5.26s CPU time): 113 tests passed, 0 failed, 0 skipped (113 total tests)\n","passed":true},{"durationMs":96,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"HookDeployer.deploy(bytes32,(address,address,address,address,address,address,address,address,int24))\",\"UnlkHook.afterAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"UnlkHook.afterRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"UnlkHook.beforeAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"UnlkHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"UnlkHook.syncPayer()\",\"UnlkHook.syncRewards(address)\",\"UnlkHook.updateMilestone()\",\"UnlkLiquidityLock.collectFees()\",\"UnlkLiquidityLock.configureHook(address)\",\"UnlkLiquidityLock.seed(uint128,int24,int24,uint256)\",\"UnlkLiquidityLock.unlockCallback(bytes)\",\"UnlkOracle.bind((address,address,uint24,int24,address))\",\"UnlkOracle.checkpoint()\",\"UnlkOracle.configureHook(address)\",\"UnlkOracle.setLiquidityRange(int24,int24)\",\"UnlkSwapRouter.configureHook(address)\",\"UnlkSwapRouter.receive()\",\"UnlkSwapRouter.swap((bool,int256,uint160,uint256,uint256,uint256))\",\"UnlkSwapRouter.swapBatch((bool,int256,uint160,uint256,uint256,uint256)[])\",\"UnlkSwapRouter.unlockCallback(bytes)\",\"UnlkSwapRouter.withdrawNative()\",\"UnlkToken.approve(address,uint256)\",\"UnlkToken.transfer(address,uint256)\",\"UnlkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"LICENSE\":25,\"README.md\":83,\"dependencies.files.json\":409,\"dependencies.lock.json\":29,\"docs/ARCHITECTURE.md\":64,\"docs/DEPLOYMENT.md\":67,\"docs/GITHUB_HANDOFF.md\":20,\"docs/IMD_INTEGRATION.md\":59,\"docs/SECURITY_REVIEW.md\":60,\"docs/VALIDATION.md\":71,\"docs/abi/HookDeployer.json\":182,\"docs/abi/IChainlinkEthUsd.json\":48,\"docs/abi/IClaimEvidence.json\":47,\"docs/abi/IFeeDistribution.json\":46,\"docs/abi/IHooks.json\":789,\"docs/abi/IPoolManager.json\":1286,\"docs/abi/IRouteContext.json\":20,\"docs/abi/UnlkHook.json\":1551,\"docs/abi/UnlkLiquidityLock.json\":342,\"docs/abi/UnlkOracle.json\":461,\"docs/abi/UnlkSwapRouter.json\":398,\"docs/abi/UnlkToken.json\":414,\"docs/validation/build.txt\":3,\"docs/validation/contract-sizes.json\":26,\"docs/validation/lint-high-medium.txt\":408,\"docs/validation/lint-high.txt\":0,\"docs/validation/tests.txt\":205,\"foundry.toml\":31,\"handoff/inventory-digest.txt\":1,\"handoff/inventory.sha256\":464,\"remappings.txt\":4,\"script/CheckReleaseConfig.s.sol\":61,\"script/LocalDemo.s.sol\":35,\"scripts/check.sh\":11,\"scripts/check_dependencies.py\":13,\"scripts/export_abis.py\":26,\"scripts/mine-hook.sh\":9,\"scripts/source_inventory.py\":24,\"scripts/verify_artifacts.py\":19,\"src/HookDeployer.sol\":24,\"src/UnlkHook.sol\":367,\"src/UnlkLiquidityLock.sol\":179,\"src/UnlkOracle.sol\":209,\"src/UnlkSwapRouter.sol\":240,\"src/UnlkToken.sol\":29,\"src/interfaces/IIntegration.sol\":43,\"src/libraries/OperationHash.sol\":14,\"test/Adversarial.t.sol\":114,\"test/CreditsAndFees.t.sol\":165,\"test/Invariants.t.sol\":206,\"test/Launch.t.sol\":121,\"test/LocalScript.t.sol\":28,\"test/NativeLaunch.t.sol\":232,\"test/Oracle.t.sol\":300,\"test/ReleaseConfig.t.sol\":24,\"test/Trading.t.sol\":276,\"test/fixtures/LocalFixtures.sol\":182,\"test/fixtures/SystemFixture.sol\":184},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":4145,"exitCode":0,"name":"slither","output":"[high/medium] reentrancy-balance at src/UnlkSwapRouter.sol:114: Reentrancy in UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177):\n[high/medium] reentrancy-balance at src/UnlkSwapRouter.sol:114: Reentrancy in UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177):\n[medium/medium] divide-before-multiply at src/UnlkOracle.sol:141: UnlkOracle.twapTick() (src/UnlkOracle.sol#141-166) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/UnlkOracle.sol:105: UnlkOracle.checkpoint() (src/UnlkOracle.sol#105-134) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/UnlkOracle.sol:141: UnlkOracle.twapTick() (src/UnlkOracle.sol#141-166) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/UnlkOracle.sol:105: UnlkOracle.checkpoint() (src/UnlkOracle.sol#105-134) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/UnlkHook.sol:174: Reentrancy in UnlkHook.afterSwap(address,PoolKey,IPoolManager.SwapParams,BalanceDelta,bytes) (src/UnlkHook.sol#174-204):\n[medium/medium] uninitialized-local at src/UnlkSwapRouter.sol:125: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256).state (src/UnlkSwapRouter.sol#125) is a local variable never initialized\n[medium/medium] unused-return at src/UnlkHook.sol:152: UnlkHook.beforeSwap(address,PoolKey,IPoolManager.SwapParams,bytes) (src/UnlkHook.sol#152-172) ignores return value by (None,None,protocolFee,lpFee) = poolManager.getSlot0(poolId) (src/UnlkHook.sol#166)\n[low/medium] events-maths at src/UnlkOracle.sol:96: UnlkOracle.setLiquidityRange(int24,int24) (src/UnlkOracle.sol#96-101) should emit an event for: \n[low/medium] calls-loop at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177) has external calls inside a loop: state.baseInput = state.inputToken.balanceOf(address(this)) (src/UnlkSwapRouter.sol#131-133)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177) has external calls inside a loop: address(hook) == address(0) || ! hook.bound() || block.timestamp > request.deadline || request.amountSpecified == 0 || request.amountSpecified == type()(int256).min || request.maxInput == 0 || request.maxInput > uint256(uint128(type()(int128).max)) || request.minOutput == 0 (src/UnlkSwapRouter.sol#119-122)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177) has external calls inside a loop: result = poolManager.unlock(abi.encode(key,params,operationNonce,request.maxInput)) (src/UnlkSwapRouter.sol#150)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:183: UnlkSwapRouter._balance(IERC20) (src/UnlkSwapRouter.sol#183-185) has external calls inside a loop: currency.balanceOf(address(this)) (src/UnlkSwapRouter.sol#184)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177) has external calls inside a loop: key = hook.poolKey() (src/UnlkSwapRouter.sol#124)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177) has external calls inside a loop: outputBefore = state.outputToken.balanceOf(msg.sender) (src/UnlkSwapRouter.sol#166)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177) has external calls inside a loop: state.outputToken.balanceOf(msg.sender) != outputBefore + output (src/UnlkSwapRouter.sol#168)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177) has external calls inside a loop: state.baseOutput = state.outputToken.balanceOf(address(this)) (src/UnlkSwapRouter.sol#134-135)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177) has external calls inside a loop: state.inputToken.balanceOf(address(this)) != state.baseInput + request.maxInput (src/UnlkSwapRouter.sol#140)\n[low/medium] reentrancy-benign at src/UnlkSwapRouter.sol:114: Reentrancy in UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177):\n[low/medium] reentrancy-benign at src/UnlkHook.sol:312: Reentrancy in UnlkHook.updateMilestone() (src/UnlkHook.sol#312-316):\n[low/medium] reentrancy-benign at src/UnlkLiquidityLock.sol:74: Reentrancy in UnlkLiquidityLock.seed(uint128,int24,int24,uint256) (src/UnlkLiquidityLock.sol#74-115):\n[low/medium] reentrancy-benign at src/UnlkHook.sol:174: Reentrancy in UnlkHook.afterSwap(address,PoolKey,IPoolManager.SwapParams,BalanceDelta,bytes) (src/UnlkHook.sol#174-204):\n[low/medium] reentrancy-events at src/UnlkHook.sol:116: Reentrancy in UnlkHook.beforeInitialize(address,PoolKey,uint160) (src/UnlkHook.sol#116-140):\n[low/medium] reentrancy-events at src/UnlkHook.sol:312: Reentrancy in UnlkHook.updateMilestone() (src/UnlkHook.sol#312-316):\n[low/medium] reentrancy-events at src/UnlkHook.sol:174: Reentrancy in UnlkHook.afterSwap(address,PoolKey,IPoolManager.SwapParams,BalanceDelta,bytes) (src/UnlkHook.sol#174-204):\n[low/medium] timestamp at src/UnlkOracle.sol:141: UnlkOracle.twapTick() (src/UnlkOracle.sol#141-166) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:185: UnlkOracle._ethUsd() (src/UnlkOracle.sol#185-198) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:105: UnlkOracle.checkpoint() (src/UnlkOracle.sol#105-134) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:169: UnlkOracle.fdvUsd() (src/UnlkOracle.sol#169-183) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkHook.sol:328: UnlkHook._updateMilestone() (src/UnlkHook.sol#328-357) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#114-177) uses timestamp for comparisons","passed":true},{"durationMs":734,"exitCode":0,"name":"aderyn","output":"[high] contract-locks-ether at src/UnlkLiquidityLock.sol:17: Contract locks Ether without a withdraw function\n[high] eth-send-unchecked-address at src/UnlkSwapRouter.sol:195: ETH transferred without address checks\n[high] reentrancy-state-change at src/UnlkHook.sol:129: Reentrancy: State change after external call (13 places)\n[high] unprotected-initializer at src/HookDeployer.sol:9: Unprotected initializer\n[low] costly-loop at src/UnlkHook.sol:341: Costly operations inside loop (2 places)\n[low] large-numeric-literal at src/UnlkHook.sol:194: Large Numeric Literal (16 places)\n[low] literal-instead-of-constant at src/UnlkHook.sol:159: Literal Instead of Constant (12 places)\n[low] local-variable-shadowing at src/UnlkHook.sol:55: Local Variable Shadows State Variable (8 places)\n[low] require-revert-in-loop at src/UnlkSwapRouter.sol:105: Loop Contains `require`/`revert`\n[low] state-change-without-event at src/UnlkHook.sol:152: State Change Without Event (5 places)\n[low] unchecked-return at src/UnlkHook.sol:202: Unchecked Return\n[low] unused-public-function at src/HookDeployer.sol:13: Public Function Not Used Internally","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"2aeb36dc394f9b602bd63dae8a5847e0985cabbcdf48860ac80895e81ef366dc","verifiedTreeHash":"9286579fcd3f7864f34541f865826c4418940d1c","verifierVersion":"0.1.0+0e08a464"},{"checks":[{"durationMs":38621,"exitCode":0,"name":"build","output":"Compiling 21 files with Solc 0.8.26\nSolc 0.8.26 finished in 38.57s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> src/UnlkHook.sol:251:5:\n    |\n251 |     function beforeRemoveLiquidity(\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":431,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 21 tests for test/UnlkLaunch.t.sol:UnlkLaunchTest\n[PASS] test_FeesCollectedAndSplit80To20() (gas: 932576)\n[PASS] test_LockedPrincipalCannotBeRemoved() (gas: 99533)\n[PASS] test_PoolBoundWithHookFlags() (gas: 70922)\n[PASS] test_RevertWhen_CallbackFromManagerButUnsupportedSender() (gas: 53888)\n[PASS] test_RevertWhen_CallbackNotFromPoolManager() (gas: 269065)\n[PASS] test_RevertWhen_FactoryInitializesSecondPool() (gas: 52607)\n[PASS] test_RevertWhen_HookDeployedAtAddressWithoutFlags() (gas: 14622)\n[PASS] test_RevertWhen_InitializeLaunchNotFactory() (gas: 30676)\n[PASS] test_RevertWhen_InitializeLaunchTwice() (gas: 35305)\n[PASS] test_RevertWhen_LockDepositedTwice() (gas: 59398)\n[PASS] test_RevertWhen_RogueRouterBuys() (gas: 503926)\n[PASS] test_RevertWhen_RogueRouterSpoofsTrader() (gas: 801344)\n[PASS] test_RevertWhen_RouterCallbackNotFromManager() (gas: 35745)\n[PASS] test_RevertWhen_SlippageExceeded() (gas: 224831)\n[PASS] test_RevertWhen_SwapDeadlinePassed() (gas: 44342)\n[PASS] test_RevertWhen_TokenConstructedWithZeroPayer() (gas: 4344)\n[PASS] test_RevertWhen_TokenTransferExceedsBalance() (gas: 37468)\n[PASS] test_RevertWhen_UnauthorizedPoolInitialization() (gas: 48492)\n[PASS] test_RevertWhen_UnusedCallbackInvoked() (gas: 16395)\n[PASS] test_TokenSupplyAndAllocations() (gas: 40308)\n[PASS] test_TransfersAreUntaxedAndDoNotTouchCounters() (gas: 458336)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 33.93ms (3.51ms CPU time)\n\nRan 13 tests for test/UnlkOracle.t.sol:UnlkOracleTest\n[PASS] test_FallingPriceNeverRelocks() (gas: 875087)\n[PASS] test_FdvAtLaunchPriceIsAbout50k() (gas: 197008)\n[PASS] test_FullUnlockBypassesQuotaForEveryone() (gas: 1060823)\n[PASS] test_InitialStateAndWarmup() (gas: 160783)\n[PASS] test_InvalidFeedAnswersBlockTiers() (gas: 648127)\n[PASS] test_LowLiquidityBlocksTiers() (gas: 21292867)\n[PASS] test_OneBlockManipulationBarelyMovesTwap() (gas: 459130)\n[PASS] test_SameBlockManipulationIgnored() (gas: 361250)\n[PASS] test_StaleFeedBlocksNewTiersOnly() (gas: 895383)\n[PASS] test_SustainedThresholdRaisesP() (gas: 768728)\n[PASS] test_TickMathKnownValues() (gas: 873)\n[PASS] test_TierTable() (gas: 56988)\n[PASS] test_UnconfirmedSpikeDoesNotRaiseTier() (gas: 607288)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 38.86ms (10.53ms CPU time)\n\nRan 2 tests for test/UnlkOrdering.t.sol:UnlkOrderingTest\n[PASS] test_UnlkAsCurrency0() (gas: 112338499)\n[PASS] test_UnlkAsCurrency1() (gas: 41004781)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 40.95ms (60.22ms CPU time)\n\nRan 9 tests for test/UnlkSignedSwap.t.sol:UnlkSignedSwapTest\n[PASS] test_RevertWhen_Expired() (gas: 55232)\n[PASS] test_RevertWhen_OtherRelayer() (gas: 58095)\n[PASS] test_RevertWhen_SignatureReplayed() (gas: 303212)\n[PASS] test_RevertWhen_SignedForOtherChain() (gas: 65815)\n[PASS] test_RevertWhen_SignedSaleExceedsSignerQuota() (gas: 281344)\n[PASS] test_RevertWhen_TamperedSteps() (gas: 65539)\n[PASS] test_RevertWhen_WrongSigner() (gas: 65255)\n[PASS] test_SignedBuyCreditsSigner() (gas: 294346)\n[PASS] test_SmartWalletErc1271() (gas: 617973)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 50.96ms (5.92ms CPU time)\n\nRan 14 tests for test/UnlkQuota.t.sol:UnlkQuotaTest\n[PASS] testFuzz_QuotaRule(uint256,uint256) (runs: 256, μ: 490147, ~: 520994)\n[PASS] test_BuyExactInputCreditsActualDelta() (gas: 255538)\n[PASS] test_BuyExactOutputCreditsExactAmount() (gas: 272455)\n[PASS] test_ClaimNotBlockedWhenCreditSyncFails() (gas: 341407)\n[PASS] test_ClaimedRewardsCreditedOnceAndOnlyAfterClaim() (gas: 780675)\n[PASS] test_ExactOutputSaleRecordsFeeInclusiveTokensIn() (gas: 559604)\n[PASS] test_MultipleSwapsInOneUnlock() (gas: 547110)\n[PASS] test_PayerAllocationCreditedOnceToPayerOnly() (gas: 421687)\n[PASS] test_RevertWhen_BatchSellPrecedesBuy() (gas: 249355)\n[PASS] test_RevertWhen_OtherWalletTriesToUseQuota() (gas: 485906)\n[PASS] test_RevertWhen_SaleExceedsQuotaByOneWei() (gas: 435105)\n[PASS] test_RevertWhen_TransferOnlyRecipientSells() (gas: 234316)\n[PASS] test_SellAtExactQuotaBoundary() (gas: 567296)\n[PASS] test_SellsAccumulateAgainstQuota() (gas: 892362)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 50.97ms (27.41ms CPU time)\n\nRan 1 test for test/UnlkInvariant.t.sol:UnlkInvariantTest\n[PASS]\nUnlkInvariantTest invariants:\n[PASS] invariant_FixedSupply\n[PASS] invariant_NoCreditWithoutAcquisition\n[PASS] invariant_SoldNeverExceedsCapacity\n UnlkInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭-------------+----------+-------+---------+----------╮\n| Contract    | Selector | Calls | Reverts | Discards |\n+=====================================================+\n| UnlkHandler | buy      | 678   | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| UnlkHandler | sell     | 672   | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| UnlkHandler | transfer | 698   | 0       | 0        |\n╰-------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 371.60ms (335.82ms CPU time)\n\nRan 6 test suites in 372.80ms (587.27ms CPU time): 60 tests passed, 0 failed, 0 skipped (60 total tests)\n","passed":true},{"durationMs":39,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"UnlkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"UnlkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"UnlkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"UnlkHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"UnlkHook.initializeLaunch(address,address,address)\",\"UnlkHook.syncPayerAllocation()\",\"UnlkHook.syncRewardCredits(address)\",\"UnlkHook.updateMilestones()\",\"UnlkLiquidityLock.collectFees()\",\"UnlkLiquidityLock.lockLiquidity(int24,int24,uint128)\",\"UnlkLiquidityLock.receive()\",\"UnlkLiquidityLock.unlockCallback(bytes)\",\"UnlkSwapRouter.swap((bool,int256,uint160,uint256)[],uint256)\",\"UnlkSwapRouter.swapWithSignature((address,address,(bool,int256,uint160,uint256)[],uint256,uint256),bytes)\",\"UnlkSwapRouter.unlockCallback(bytes)\",\"UnlkToken.approve(address,uint256)\",\"UnlkToken.transfer(address,uint256)\",\"UnlkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":181,\"abi/UnlkHook.json\":1977,\"abi/UnlkLiquidityLock.json\":353,\"abi/UnlkSwapRouter.json\":423,\"abi/UnlkToken.json\":356,\"foundry.toml\":30,\"script/DeployLocal.s.sol\":182,\"src/UnlkHook.sol\":593,\"src/UnlkLiquidityLock.sol\":159,\"src/UnlkSwapRouter.sol\":198,\"src/UnlkToken.sol\":95,\"src/interfaces/IUnlkExternal.sol\":30,\"src/libraries/FullMath.sol\":62,\"src/libraries/HookMiner.sol\":27,\"src/libraries/OracleMath.sol\":29,\"src/libraries/TickMath.sol\":45,\"src/v4/V4Types.sol\":240,\"test/UnlkInvariant.t.sol\":96,\"test/UnlkLaunch.t.sol\":229,\"test/UnlkOracle.t.sol\":176,\"test/UnlkOrdering.t.sol\":50,\"test/UnlkQuota.t.sol\":182,\"test/UnlkSignedSwap.t.sol\":114,\"test/mocks/Fixtures.sol\":212,\"test/mocks/MockPoolManager.sol\":315,\"test/utils/UnlkTestBase.sol\":193,\"test/utils/Vm.sol\":23},\"excluded\":[\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":2946,"exitCode":0,"name":"slither","output":"[high/high] arbitrary-send-erc20 at src/UnlkLiquidityLock.sol:125: UnlkLiquidityLock._pay(Currency,int128) (src/UnlkLiquidityLock.sol#125-138) uses arbitrary from in transferFrom: SafeTransferLib.safeTransferFrom(Currency.unwrap(currency),depositor,address(poolManager),owed) (src/UnlkLiquidityLock.sol#135)\n[high/high] arbitrary-send-erc20 at src/UnlkSwapRouter.sol:167: UnlkSwapRouter._settle(Currency,int128,address) (src/UnlkSwapRouter.sol#167-180) uses arbitrary from in transferFrom: SafeTransferLib.safeTransferFrom(Currency.unwrap(currency),trader,address(poolManager),owed) (src/UnlkSwapRouter.sol#174)\n[high/medium] arbitrary-send-eth at src/UnlkSwapRouter.sol:140: UnlkSwapRouter._execute(address,UnlkSwapRouter.SwapStep[]) (src/UnlkSwapRouter.sol#140-153) sends eth to arbitrary user\n[high/medium] arbitrary-send-eth at src/UnlkLiquidityLock.sol:155: UnlkLiquidityLock._sendNative(address,uint256) (src/UnlkLiquidityLock.sol#155-158) sends eth to arbitrary user\n[high/medium] weak-prng at src/UnlkHook.sol:486: UnlkHook.twapTick() (src/UnlkHook.sol#486-509) uses a weak PRNG: \"diff < 0 && diff % elapsed != 0 (src/UnlkHook.sol#504)\"\n[high/medium] incorrect-exp at src/libraries/FullMath.sol:8: FullMath.mulDiv(uint256,uint256,uint256) (src/libraries/FullMath.sol#8-53) has bitwise-xor operator ^ instead of the exponentiation operator **: \n[medium/medium] divide-before-multiply at src/libraries/FullMath.sol:8: FullMath.mulDiv(uint256,uint256,uint256) (src/libraries/FullMath.sol#8-53) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/libraries/FullMath.sol:8: FullMath.mulDiv(uint256,uint256,uint256) (src/libraries/FullMath.sol#8-53) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/libraries/FullMath.sol:8: FullMath.mulDiv(uint256,uint256,uint256) (src/libraries/FullMath.sol#8-53) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/libraries/FullMath.sol:8: FullMath.mulDiv(uint256,uint256,uint256) (src/libraries/FullMath.sol#8-53) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/libraries/FullMath.sol:8: FullMath.mulDiv(uint256,uint256,uint256) (src/libraries/FullMath.sol#8-53) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/libraries/TickMath.sol:13: TickMath.getSqrtPriceAtTick(int24) (src/libraries/TickMath.sol#13-44) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/libraries/FullMath.sol:8: FullMath.mulDiv(uint256,uint256,uint256) (src/libraries/FullMath.sol#8-53) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/libraries/FullMath.sol:8: FullMath.mulDiv(uint256,uint256,uint256) (src/libraries/FullMath.sol#8-53) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/libraries/FullMath.sol:8: FullMath.mulDiv(uint256,uint256,uint256) (src/libraries/FullMath.sol#8-53) performs a multiplication on the result of a division:\n[medium/medium] uninitialized-local at src/UnlkHook.sol:218: UnlkHook.beforeInitialize(address,PoolKey,uint160).isZero (src/UnlkHook.sol#218) is a local variable never initialized\n[medium/medium] unused-return at src/UnlkHook.sol:486: UnlkHook.twapTick() (src/UnlkHook.sol#486-509) ignores return value by (None,spot) = StateReader.getSlot0(poolManager,poolId) (src/UnlkHook.sol#492)\n[medium/medium] unused-return at src/UnlkSwapRouter.sol:167: UnlkSwapRouter._settle(Currency,int128,address) (src/UnlkSwapRouter.sol#167-180) ignores return value by poolManager.settle{value: owed}() (src/UnlkSwapRouter.sol#171)\n[medium/medium] unused-return at src/UnlkHook.sol:557: UnlkHook._updateOracle() (src/UnlkHook.sol#557-572) ignores return value by (None,tick) = StateReader.getSlot0(poolManager,poolId) (src/UnlkHook.sol#561)\n[medium/medium] unused-return at src/UnlkHook.sol:574: UnlkHook._ethUsd() (src/UnlkHook.sol#574-592) ignores return value by (roundId,answer,updatedAt,answeredInRound) = ethUsdFeed.latestRoundData() (src/UnlkHook.sol#581-591)\n[medium/medium] unused-return at src/UnlkSwapRouter.sol:167: UnlkSwapRouter._settle(Currency,int128,address) (src/UnlkSwapRouter.sol#167-180) ignores return value by poolManager.settle() (src/UnlkSwapRouter.sol#175)\n[medium/medium] unused-return at src/UnlkLiquidityLock.sol:125: UnlkLiquidityLock._pay(Currency,int128) (src/UnlkLiquidityLock.sol#125-138) ignores return value by poolManager.settle{value: owed}() (src/UnlkLiquidityLock.sol#132)\n[medium/medium] unused-return at src/UnlkLiquidityLock.sol:100: UnlkLiquidityLock.unlockCallback(bytes) (src/UnlkLiquidityLock.sol#100-123) ignores return value by (delta,None) = poolManager.modifyLiquidity(key,params,) (src/UnlkLiquidityLock.sol#111)\n[medium/medium] unused-return at src/UnlkLiquidityLock.sol:125: UnlkLiquidityLock._pay(Currency,int128) (src/UnlkLiquidityLock.sol#125-138) ignores return value by poolManager.settle() (src/UnlkLiquidityLock.sol#136)\n[medium/medium] unused-return at src/UnlkLiquidityLock.sol:76: UnlkLiquidityLock.lockLiquidity(int24,int24,uint128) (src/UnlkLiquidityLock.sol#76-88) ignores return value by poolManager.unlock(abi.encode(ACTION_ADD)) (src/UnlkLiquidityLock.sol#84)\n[medium/medium] unused-return at src/UnlkLiquidityLock.sol:100: UnlkLiquidityLock.unlockCallback(bytes) (src/UnlkLiquidityLock.sol#100-123) ignores return value by (feeDelta,None) = poolManager.modifyLiquidity(key,poke,) (src/UnlkLiquidityLock.sol#119)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:167: UnlkSwapRouter._settle(Currency,int128,address) (src/UnlkSwapRouter.sol#167-180) has external calls inside a loop: poolManager.take(currency,trader,uint256(uint128(amount))) (src/UnlkSwapRouter.sol#178)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:167: UnlkSwapRouter._settle(Currency,int128,address) (src/UnlkSwapRouter.sol#167-180) has external calls inside a loop: poolManager.settle{value: owed}() (src/UnlkSwapRouter.sol#171)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:167: UnlkSwapRouter._settle(Currency,int128,address) (src/UnlkSwapRouter.sol#167-180) has external calls inside a loop: poolManager.sync(currency) (src/UnlkSwapRouter.sol#173)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:167: UnlkSwapRouter._settle(Currency,int128,address) (src/UnlkSwapRouter.sol#167-180) has external calls inside a loop: poolManager.settle() (src/UnlkSwapRouter.sol#175)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:113: UnlkSwapRouter.unlockCallback(bytes) (src/UnlkSwapRouter.sol#113-138) has external calls inside a loop: delta = poolManager.swap(key,SwapParams({zeroForOne:step.zeroForOne,amountSpecified:step.amountSpecified,sqrtPriceLimitX96:limit}),hookData) (src/UnlkSwapRouter.sol#124-130)\n[low/medium] reentrancy-events at src/UnlkLiquidityLock.sol:146: Reentrancy in UnlkLiquidityLock._distribute(Currency,uint256) (src/UnlkLiquidityLock.sol#146-153):\n[low/medium] reentrancy-events at src/UnlkLiquidityLock.sol:91: Reentrancy in UnlkLiquidityLock.collectFees() (src/UnlkLiquidityLock.sol#91-98):\n[low/medium] reentrancy-events at src/UnlkLiquidityLock.sol:91: Reentrancy in UnlkLiquidityLock.collectFees() (src/UnlkLiquidityLock.sol#91-98):\n[low/medium] reentrancy-events at src/UnlkLiquidityLock.sol:76: Reentrancy in UnlkLiquidityLock.lockLiquidity(int24,int24,uint128) (src/UnlkLiquidityLock.sol#76-88):\n[low/medium] reentrancy-events at src/UnlkSwapRouter.sol:113: Reentrancy in UnlkSwapRouter.unlockCallback(bytes) (src/UnlkSwapRouter.sol#113-138):\n[low/medium] timestamp at src/UnlkHook.sol:486: UnlkHook.twapTick() (src/UnlkHook.sol#486-509) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkHook.sol:409: UnlkHook.tierForFdv(uint256) (src/UnlkHook.sol#409-414) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkHook.sol:574: UnlkHook._ethUsd() (src/UnlkHook.sol#574-592) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkHook.sol:420: UnlkHook.updateMilestones() (src/UnlkHook.sol#420-466) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkSwapRouter.sol:80: UnlkSwapRouter.swapWithSignature(UnlkSwapRouter.SignedSwap,bytes) (src/UnlkSwapRouter.sol#80-93) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkSwapRouter.sol:74: UnlkSwapRouter.swap(UnlkSwapRouter.SwapStep[],uint256) (src/UnlkSwapRouter.sol#74-77) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkHook.sol:557: UnlkHook._updateOracle() (src/UnlkHook.sol#557-572) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkHook.sol:469: UnlkHook.oracleFdvUsd() (src/UnlkHook.sol#469-482) uses timestamp for comparisons","passed":false}],"detail":"static analysis found arbitrary-send-erc20 at src/UnlkLiquidityLock.sol:125; arbitrary-send-erc20 at src/UnlkSwapRouter.sol:167: UnlkLiquidityLock._pay(Currency,int128) (src/UnlkLiquidityLock.sol#125-138) uses arbitrary from in transferFrom: SafeTransferLib.safeTransferFrom(Currency.unwrap(currency),depositor,address(poolManager),owed) (src/UnlkLiquidityLock.sol#135)","evaluation":"checks","profile":"foundry","status":"rejected","submissionHash":"9fe6070fa36a93e21a237824f95eb21948475d55baf178f6dbbf861120cb6d3b","verifiedTreeHash":"ebb8026be9a88273b43da7d4ed543d14af5399f5","verifierVersion":"0.1.0+0e08a464"}]}