{"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":"4c445e45-c275-4d31-8cb5-086eadb9957a","kind":"skill:build-contract-project","nodes":[{"acceptedSubmissionHash":"10b8541dfe4884422526c4a388c10ab1798c16051bb5cae7667dbc037ca7714b","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":"X: https://x.com/imdplace\nGoblin Gold v3.2: fix every critical, high and medium finding of audit 85083c05 plus two lows. Do not change foundry.toml or src/GoblinNFT.sol. Re-pin GACHA_RUNTIME_CODE_HASH from the final build.\n\n1. CRITICAL, GoldHook.bindGacha accepts a look-alike BagGacha (src/GoldHook.sol:257). Bind only the gacha the NFT owner named through the holder-reviewed setLaunchTargets: require GoblinNFT(0xC5d5F314da6d4a433F9BF897a2cC24A537576cB1).targetsSet(), reserveTarget() == gacha, vrfTarget() == gacha, polTarget() == gacha.polManager(), the 7-day review has ended, and gacha.nft()/genesis().token() match. Also check the genesis vault's gacha() == gacha and oracle == gacha's oracle. Reorder the runbook: launch 1 (token + hook), launch 2 (gacha set), setLaunchTargets, review, then bindGacha. Add the audit's BindGachaLookalike test as permanent.\n2. HIGH, POLManager._addFullRange never settles a positive fee delta (src/POLManager.sol:197). When amount0 or amount1 is positive, take it so the callback always zeroes both deltas; recycle the taken ETH and add the taken GOLD to the next add. Permanent test from PolFeeBrick.\n3. HIGH, GoldHook charges fee and tax on unconsumed ETH (src/GoldHook.sol:207). When ETH is specified, afterSwap must revert PartialFill unless the pool's realised ETH leg equals the taxed input (buy: amount - fee - tax; exact-output sell: amount). Internal POLManager swaps must use the extreme price limit. Permanent test from PartialFillFee.\n4. HIGH, JIT liquidity inflates genesis depth and the 5% payout cap (src/TwapOracle.sol:208). Make depth unmovable within one transaction: record active liquidity in each GoldHook observation and use min(current L, L at the 30-minute observation), and bound ethSide by the ETH the active liquidity holds down to the lowest usable tick. Permanent test from JitPayoutCap.\n5. MEDIUM, genesis quote uses the lower of the 30-minute and 4-hour prices (src/TwapOracle.sol:166). Use the less favourable quote for the buyer of Genesis (Math.min of the two token amounts) and value the genesis cap at the 4-hour TWAP, so both windows must be moved. Test that a 30-minute push no longer inflates Genesis Bags.\n6. MEDIUM, POLManager.MIN_OUT_BPS uses 1250 bps for the 1.25% fee (src/POLManager.sol:41). Set MIN_OUT_BPS = 10_000 - 125 - 100 - 300 (9475); test the value.\n7. LOW, exact-output buys pay the 1% fee on net input (src/GoldHook.sol:230): compute gross = ethIn * BPS / (BPS - HOOK_FEE_BPS - taxBps), fee = 1% of gross, tax = gross - fee - ethIn.\n8. LOW, an unfulfilled VRF request locks the gacha forever (src/BagGacha.sol:435): after 24 hours anyone may cancel the pending request; refund req.paid to the spinner, release the liability and uncommit genesis tokens. Test it.\nAccepted and documented (no change): withdraw fee waived while a Bag is unpriceable (low 9); the 0.5 ETH first-hour cap is per swap, not per wallet (info 10).\n\nRerun all tests and invariants (FOUNDRY_VIA_IR=false FOUNDRY_BYTECODE_HASH=none) and the v4 mainnet fork test; update the README runbook and both launch objectives.","parentJobId":"05d83502-4b3e-44ec-8d89-14cf40e464e2","planHash":"74262594cb9e675d9e1b354e02e83204ae57c82fa22b11a246dce347c894d7c2","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"9bf411ca-2719-4cab-b2a3-badcf83ed8d4","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1545-goblin-gold"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52128","feedbackHash":"cd1beb561e810798eaeba546eba2c3c789f448d0e7ec329836fbdc64a309fe22","nodeKey":"build_contract_project","submissionHash":"10b8541dfe4884422526c4a388c10ab1798c16051bb5cae7667dbc037ca7714b","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"fe5497004d375b2b714ba8df1193325344a944ffb99f916207d260638c6877fb","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"a57ed40ed46f05640858d53c5aaddc89936ea22b562f9d46d084c5a3efa2161c","device":"9c6767b941fcfedc","findings":[],"hash":"10b8541dfe4884422526c4a388c10ab1798c16051bb5cae7667dbc037ca7714b","nodeId":"63241160-4242-44e6-8427-ebb3b8ce1b66","outcome":"completed","summary":"Done. All eight findings of audit 85083c05 are fixed in source, each with a permanent regression test, and the gacha code hash is re-pinned from the final build.\n\n**What changed**\n\n- **1 Critical, bindGacha look-alike.** `GoldHook.bindGacha` now accepts only the gacha the GoblinNFT owner named through `setLaunchTargets` (reserve and VRF target must be the candidate, POL target its `polManager()`), only after the 7-day review, and only if its NFT, vault token, `vault.gacha()` and the vault/gacha oracles all agree. Three distinct errors: `NotLaunchTarget`, `ReviewPending`, `GachaMismatch`.\n- **2 High, POL fee brick.** `_addFullRange` takes positive ETH or GOLD deltas so the callback always zeroes both. Taken ETH goes straight into the POL budget, taken GOLD waits for the next add.\n- **3 High, partial fills.** With ETH specified, `afterSwap` reverts `PartialFill` unless the pool realised exactly the ETH it was handed. For an exact-output sell that is `amount + fee`, not `amount` as the brief wrote, because the pool must produce the fee on top of what the swapper receives. POL swaps already used the extreme limit.\n- **4 High, JIT depth.** Each hook observation records active liquidity. The oracle uses the lower of current liquidity and the liquidity recorded 30 minutes ago, and bounds the ETH side by what that liquidity holds up to the last usable tick.\n- **5 Medium.** Genesis quotes take the smaller token amount of the two windows, and the genesis cap is valued at the 4-hour TWAP alone.\n- **6 Medium.** `MIN_OUT_BPS` is 9475.\n- **7 Low.** Exact-output buys pay fee and tax as shares of the gross amount.\n- **8 Low.** `cancelRequest()` after 24 hours refunds the spin price as credit, releases the earmark and uncommits genesis tokens. The VRF fee stays spent.\n\n**Checks**\n\n| Check | Result |\n|---|---|\n| Launch profile build, test, fuzz seed from the brief | 160 passed, 2 fork tests skipped |\n| Mainnet fork tests via public RPC | 3 passed |\n| `forge fmt --check` | pass |\n| Pinned hash equals the v3.2 BagGacha runtime code | pass |\n| Full tree under the protected `via_ir = true` profile | not completed here |\n\nThe via_ir run could not finish in this sandbox: solc is killed by the 1.5 GB cgroup limit, and I confirmed the untouched v3.1 tree dies the same way. Sources alone do compile under that profile. This is recorded in the README and report as an open item to repeat on a larger machine.\n\nThe README runbook is reordered to launch 1, launch 2, `setLaunchTargets`, review, `bindGacha`, `release`, with both launch objectives rewritten and the two accepted findings documented. One design consequence worth knowing: because the first observation records zero liquidity, the Genesis lane opens 30 minutes after the first post-seed swap at the earliest.","treeHash":"a957dd14bfa508e69cc11e9095e8952603c7ad9e","usage":{"cachedInputTokens":9617753,"inputTokens":1570,"model":"claude-fable-5-1","outputTokens":112176,"runtime":"claude","turns":92,"wallClockMs":2042420}}],"verification":[{"checks":[{"durationMs":147089,"exitCode":0,"name":"build","output":"Compiling 147 files with Solc 0.8.26\nSolc 0.8.26 finished in 146.96s\nCompiler run successful!\n","passed":true},{"durationMs":9771,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/MainnetV4Fork.t.sol:MainnetV4ForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 236.86µs (0.00ns CPU time)\n\nRan 2 tests for test/TickMath.t.sol:TickMathTest\n[PASS] testKnownValues() (gas: 4315)\n[PASS] testOutOfRangeReverts() (gas: 3855)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 269.60µs (195.26µs CPU time)\n\nRan 1 test for test/fork/MainnetFork.t.sol:MainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 314.33µs (0.00ns CPU time)\n\nRan 4 tests for test/OracleConsumerConformance.t.sol:OracleConsumerConformanceTest\n[PASS] test_acceptsAFreshSignatureFromTheVectorKey() (gas: 1179900)\n[PASS] test_acceptsTheProtocolSignature() (gas: 75772)\n[PASS] test_callbackSelectorIsCanonical() (gas: 3894)\n[PASS] test_digestMatchesTheProtocol() (gas: 13545)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.32ms (1.06ms CPU time)\n\nRan 8 tests for test/Audit85083c05.t.sol:Audit85083c05HookTest\n[PASS] testBindGachaLookalike() (gas: 2678734)\n[PASS] testGenesisDepthIsBoundedByTheEthTheLiquidityHolds() (gas: 35743)\n[PASS] testJitPayoutCap() (gas: 2259459)\n[PASS] testMinOutBpsMatchesTheFeeSchedule() (gas: 14976)\n[PASS] testMinOutFloorBehaviour() (gas: 532112)\n[PASS] testPartialFillFee() (gas: 1978921)\n[PASS] testPolFeeBrick() (gas: 3291717)\n[PASS] testShortWindowPushNoLongerInflatesGenesisBags() (gas: 1945315)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 14.96ms (11.84ms CPU time)\n\nRan 15 tests for test/Curator.t.sol:CuratorTest\n[PASS] testApproveStoreThenPermissionlessExecuteAndReplay() (gas: 1510606)\n[PASS] testConsumedOracleUuidCannotApproveSecondRequest() (gas: 1872215)\n[PASS] testCrossContractAndCrossChainSignaturesRejected() (gas: 4446465)\n[PASS] testDirectSettersAndOutsideBoundsRejected() (gas: 185752)\n[PASS] testFuzzDiscountBounds(uint256) (runs: 256, μ: 411264, ~: 44233)\nLogs:\n  Bound result 988\n\n[PASS] testIntakeAndPaymentTokenAreCompiledInConstantsNotConstructorWords() (gas: 76285)\n[PASS] testLiquidityRecheckedAtExecutionAndCanonicalPoolRequired() (gas: 2384041)\n[PASS] testNoAnswerFailureAndTimeoutDoNotChangeSettings() (gas: 2437562)\n[PASS] testOddsRelativeTenPercentAndRollingDay() (gas: 3141165)\n[PASS] testPoolWhitelistDelistPauseAndUnpauseOnlyByApprovedAction() (gas: 4040807)\n[PASS] testProductionPinsTheRequiredSignerAndHasNoOwner() (gas: 93570)\n[PASS] testProposeReentrancyCannotOpenNestedRequest() (gas: 1381531)\n[PASS] testStaleConcurrentApprovalAndExpiredExecutionCannotChangeSettings() (gas: 2651426)\n[PASS] testWeakPanelExpiredFutureAndStaleAnswersRejected() (gas: 1580601)\n[PASS] testWrongSenderUnknownIdWrongQuestionAndTampering() (gas: 1433652)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 74.35ms (71.63ms CPU time)\n\nRan 1 test for test/GasBench.t.sol:GasBenchTest\n[PASS] testMaximumInventorySnapshotGas() (gas: 8847352)\nLogs:\n  32 Bags / 128 distinct pools request gas (mock observe): 8189207\n  32 Bag draw gas: 415965\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 126.83ms (7.77ms CPU time)\n\nRan 2 tests for test/BagGachaV2.t.sol:EarlyGachaTest\n[PASS] testDayOneRevenueBeforeSelloutAndMintRemainsRefundable() (gas: 1245067)\n[PASS] testPreReleaseRefundCannotRecycleFreeSpinCoupons() (gas: 332820)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 244.09ms (554.55µs CPU time)\n\nRan 1 test for test/GoldHook.invariant.t.sol:GoldHookInvariantTest\n[PASS] invariant_chargesEqualClaimsPlusFlushesAndNothingSticksInTheHook() (runs: 24, calls: 960, reverts: 0)\n\n╭-------------+----------+-------+---------+----------╮\n| Contract    | Selector | Calls | Reverts | Discards |\n+=====================================================+\n| HookHandler | advance  | 167   | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| HookHandler | bind     | 201   | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| HookHandler | buy      | 184   | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| HookHandler | flush    | 219   | 0       | 0        |\n|-------------+----------+-------+---------+----------|\n| HookHandler | sell     | 189   | 0       | 0        |\n╰-------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 2\n  Bound result 900\n  Bound result 4999999999000008660\n  Bound result 499999999000002171\n  Bound result 473899959237284449\n  Bound result 4999999999000001801\n  Bound result 499999999000000153\n  Bound result 656\n  Bound result 4999999999000004325\n  Bound result 767\n  Bound result 980\n  Bound result 933\n  Bound result 800\n  Bound result 526528545429293\n  Bound result 1200\n  Bound result 499999999000087401\n  Bound result 784155072523467\n  Bound result 1739297017528563116\n  Bound result 399999999600\n  Bound result 75103477940233448\n  Bound result 663\n  Bound result 499999999188661403\n  Bound result 499999999000010970\n  Bound result 1000000000000000\n  Bound result 1101148966\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 283.52ms (278.12ms CPU time)\n\nRan 12 tests for test/BagGacha.t.sol:BagGachaTest\n[PASS] testAdmissionLimits() (gas: 155445)\n[PASS] testBuybackReturnsBagAndRematures() (gas: 1928858)\n[PASS] testFinalizeAfterWindowIsKeep() (gas: 1855192)\n[PASS] testGenesisAndFreeSpins() (gas: 1530690)\n[PASS] testGenesisPaidSpinSplit() (gas: 1194892)\n[PASS] testImmatureBagsNotDrawable() (gas: 565663)\n[PASS] testOneOutstandingDrawAndCallbackRules() (gas: 1576957)\n[PASS] testRegularSpinKeep() (gas: 2275216)\n[PASS] testRejectsUnexpectedEthAndEmptyCredit() (gas: 154595)\n[PASS] testReserveTooLowBlocksSpins() (gas: 119369)\n[PASS] testSpinRules() (gas: 492399)\n[PASS] testWithdrawExitFeeAndUnpricedExitFree() (gas: 1220851)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 287.34ms (20.68ms CPU time)\n\nRan 9 tests for test/TwapOracle.t.sol:TwapOracleTest\n[PASS] testDonationsAndInactiveLiquidityCannotSatisfyTheLiquidityBound() (gas: 288565)\n[PASS] testFuzzFiveEthBoundary(uint256) (runs: 256, μ: 164656, ~: 127655)\nLogs:\n  Bound result 2000000000000000010\n\n[PASS] testFuzzGenesisOneEthBoundary(uint128) (runs: 256, μ: 83033, ~: 74479)\nLogs:\n  Bound result 210920589985331169\n\n[PASS] testGenesisPoolOneEthBoundary() (gas: 472365)\n[PASS] testInsufficientWETHSideAndTokenSideAndMissingHistory() (gas: 443513)\n[PASS] testMinOfBothTWAPsAndReverseQuote() (gas: 323498)\n[PASS] testPayoutCapIsFivePercentOfEthSideDepth() (gas: 846688)\n[PASS] testRegularPoolFiveEthBoundary() (gas: 608853)\n[PASS] testStaleDelistedAndPausedValuesRevertWETHMayPause() (gas: 226807)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 332.82ms (270.07ms CPU time)\n\nRan 14 tests for test/Audit85083c05.t.sol:Audit85083c05GachaTest\n[PASS] testAdmissionLimits() (gas: 155467)\n[PASS] testBuybackReturnsBagAndRematures() (gas: 1929132)\n[PASS] testCancelledFreeSpinRefundsNothingButReleasesTheGenesisTokens() (gas: 988891)\n[PASS] testFinalizeAfterWindowIsKeep() (gas: 1855444)\n[PASS] testGenesisAndFreeSpins() (gas: 1530771)\n[PASS] testGenesisPaidSpinSplit() (gas: 1195188)\n[PASS] testImmatureBagsNotDrawable() (gas: 565685)\n[PASS] testOneOutstandingDrawAndCallbackRules() (gas: 1576957)\n[PASS] testRegularSpinKeep() (gas: 2275636)\n[PASS] testRejectsUnexpectedEthAndEmptyCredit() (gas: 154595)\n[PASS] testReserveTooLowBlocksSpins() (gas: 119413)\n[PASS] testSpinRules() (gas: 492443)\n[PASS] testUnfulfilledRequestCanBeCancelledAfterADay() (gas: 3213689)\n[PASS] testWithdrawExitFeeAndUnpricedExitFree() (gas: 1221058)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 382.06ms (24.60ms CPU time)\n\nRan 21 tests for test/BagGachaV2.t.sol:BagGachaV2Test\n[PASS] testAdmissionLimits() (gas: 155567)\n[PASS] testBuybackReturnsBagAndRematures() (gas: 1929084)\n[PASS] testCreditTransferFailureRollsBackAndReentryCannotPayTwice() (gas: 2170621)\n[PASS] testFeeOnTransferTokenCannotCreateUnderfundedBag() (gas: 1138446)\n[PASS] testFinalizeAfterWindowIsKeep() (gas: 1855267)\n[PASS] testFreeSpinAfterRegularSnapshotAlwaysGenesis() (gas: 2613146)\n[PASS] testFreeSpinUnfundedGenesisCannotUseRegularBags() (gas: 2147088)\n[PASS] testFuzzSolventPayoutAndNoDoublePayment(uint256,uint256,bool) (runs: 256, μ: 1873803, ~: 1794877)\nLogs:\n  Bound result 197761522632708220127\n\n[PASS] testGenesisAndFreeSpins() (gas: 1530841)\n[PASS] testGenesisPaidSpinSplit() (gas: 1195099)\n[PASS] testImmatureBagsNotDrawable() (gas: 565785)\n[PASS] testMissingVRFKeepsSnapshotLockedWithoutRefundOrReroll() (gas: 1159213)\n[PASS] testOddsAndOracleChangesDoNotRewritePendingSnapshot() (gas: 2210834)\n[PASS] testOldVRFIdCannotFulfillNewPendingRequest() (gas: 2875852)\n[PASS] testOneOutstandingDrawAndCallbackRules() (gas: 1576991)\n[PASS] testRegularSpinKeep() (gas: 2275407)\n[PASS] testRejectsUnexpectedEthAndEmptyCredit() (gas: 154607)\n[PASS] testReserveTooLowBlocksSpins() (gas: 119535)\n[PASS] testSpinRules() (gas: 492542)\n[PASS] testUnavailableGenesisDoesNotBlockRegularDrawOrWithdrawal() (gas: 1710210)\n[PASS] testWithdrawExitFeeAndUnpricedExitFree() (gas: 1221095)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 392.08ms (81.35ms CPU time)\n\nRan 14 tests for test/GoldHook.t.sol:GoldHookTest\n[PASS] testConstructorRejectsZeroAndFlagsAreTheRequiredSet() (gas: 8674)\n[PASS] testExactInputBuyPaysFeeAndLaunchTaxOnTheEthInput() (gas: 304220)\n[PASS] testExactOutputBuyCapCountsFeeAndTax() (gas: 140228)\n[PASS] testExactOutputBuyChargesFeeAndTaxOnTopOfTheEthConsumed() (gas: 333688)\n[PASS] testFlushBeforeBindPaysHoldersOnlyAndBindRequiresPinnedCode() (gas: 1246341)\n[PASS] testFuzzFeeSplitInvariantOnBuys(uint256,uint256) (runs: 256, μ: 350733, ~: 350991)\nLogs:\n  Bound result 323559004531651126\n  Bound result 3190\n\n[PASS] testGenesisOneEthDepthBoundaryAndPayoutCapOnRealPool() (gas: 4915735)\n[PASS] testGenesisPricingStaleAndThinChecks() (gas: 3699163)\n[PASS] testInitializeOnlyByFactoryOnlyPlatformPoolOnlyOnce() (gas: 2878358)\n[PASS] testObserveTracksTickCumulativeAndTwapOraclePricesGenesisFromHook() (gas: 816707)\n[PASS] testPOLManagerBuyAndBurnAndFullRangeLiquidityHeldForever() (gas: 1178111)\n[PASS] testPinnedGachaRuntimeCodeHash() (gas: 20643)\nLogs:\n  BagGacha runtime code hash (this build): 0x9796d1370679550f382780faab25b5d150ed263364ab04c5178a2c3741dd361b\n  constant differs: expected only outside the FOUNDRY_VIA_IR=false FOUNDRY_BYTECODE_HASH=none profile\n\n[PASS] testSellsPayOnePercentOfEthOutAndNoTax() (gas: 659818)\n[PASS] testTaxScheduleAndBuyCap() (gas: 944542)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 402.43ms (79.01ms CPU time)\n\nRan 7 tests for test/GoblinNFT.t.sol:GoblinNFTTest\n[PASS] testMintAndLimits() (gas: 337105)\n[PASS] testRefundBeforeSellout() (gas: 308628)\n[PASS] testRefundsReopenAfter90Days() (gas: 318717096)\n[PASS] testRevealAndTokenURI() (gas: 319704626)\n[PASS] testRevealRearmsAfter256Blocks() (gas: 318772347)\n[PASS] testRevenue() (gas: 319229369)\n[PASS] testSelloutLocksRefundsAndRelease() (gas: 319518707)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 406.77ms (1.97s CPU time)\n\nRan 5 tests for test/GenesisVault.t.sol:GenesisVaultTest\n[PASS] testDividendsAndGenesisClaimsRemainSolventAndCannotPayTwice() (gas: 583344)\n[PASS] testFuzzCurveBounds(uint256,uint256,uint256,bool) (runs: 256, μ: 248316, ~: 246332)\nLogs:\n  Bound result 890042139374123441991083931461\n  Bound result 42304936\n  Bound result 1005\n\n[PASS] testHugeQuoteCappedAtThreeDaysAndReopensWithSchedule() (gas: 237227)\n[PASS] testNotStartedUnfundedAndProtectedEntryPoints() (gas: 184742)\n[PASS] testScheduleDecayAndDiscountLimits() (gas: 445432)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 449.97ms (23.06ms CPU time)\n\nRan 12 tests for test/GoblinNFTV2.t.sol:GoblinNFTV2Test\n[PASS] testDeploymentOwnerIsExplicit() (gas: 13478470)\n[PASS] testFuzzMintWalletCap(uint256,uint256) (runs: 256, μ: 626608, ~: 652584)\nLogs:\n  Bound result 1\n  Bound result 3\n\n[PASS] testMintAndLimits() (gas: 337136)\n[PASS] testRefundBeforeSellout() (gas: 308650)\n[PASS] testRefundsReopenAfter90Days() (gas: 318717206)\n[PASS] testRepeatedReviewRestartsFullSevenDaysAndOwnersCanTransfer() (gas: 319084703)\n[PASS] testRevealAndTokenURI() (gas: 319704648)\n[PASS] testRevealRearmsAfter256Blocks() (gas: 318772413)\n[PASS] testRevenue() (gas: 319229391)\n[PASS] testSelloutLocksRefundsAndRelease() (gas: 319518725)\n[PASS] testSharedReleaseTargetAndRevenueExcludedFromSplit() (gas: 319082333)\n[PASS] testTargetsRequireCodeInEverySlotAndRenounceOnlyAfterRelease() (gas: 319075641)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 455.88ms (2.66s CPU time)\n\nRan 10 tests for test/GoblinNFTDeployed.t.sol:GoblinNFTDeployedTest\n[PASS] testFuzzDeferredRevenueConservation(uint256,uint256,uint256) (runs: 256, μ: 884172, ~: 863572)\nLogs:\n  Bound result 8\n  Bound result 20938\n  Bound result 0\n\n[PASS] testMintAndLimits() (gas: 337135)\n[PASS] testPreReleaseRevenueIsDeferredAndNotClaimable() (gas: 457033)\n[PASS] testRefundBeforeSellout() (gas: 308650)\n[PASS] testRefundsReopenAfter90Days() (gas: 318717162)\n[PASS] testReleaseSplitsDeferredPoolAcrossLiveTokensThenAccruesImmediately() (gas: 319317118)\n[PASS] testRevealAndTokenURI() (gas: 319715170)\n[PASS] testRevealRearmsAfter256Blocks() (gas: 318772413)\n[PASS] testRevenue() (gas: 319229443)\n[PASS] testSelloutLocksRefundsAndRelease() (gas: 319518732)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 455.86ms (2.22s CPU time)\n\nRan 19 tests for test/PayoutCap.t.sol:PayoutCapTest\n[PASS] testAdmissionLimits() (gas: 155533)\n[PASS] testBuybackReturnsBagAndRematures() (gas: 1929205)\n[PASS] testCapAtExactlyTheValueDoesNotSplitAndOneWeiBelowDoes() (gas: 2797376)\n[PASS] testCapBindsAndBuybackRelistsOnlyTheWonPortionWhileTheRemainderStaysDrawable() (gas: 3269937)\n[PASS] testCapBindsSplitsBagAndKeepPaysOnlyTheCappedPortion() (gas: 2519916)\n[PASS] testCapChangesAfterTheRequestDoNotRewriteTheCommittedSplit() (gas: 2737681)\n[PASS] testCapIsPerTokenAndAnUncappedTokenLeavesNothingBehind() (gas: 3302701)\n[PASS] testFinalizeAfterWindowIsKeep() (gas: 1855376)\n[PASS] testFuzzCappedPayoutNeverExceedsCapAndTokensAreConserved(uint256,uint256,bool) (runs: 256, μ: 2152261, ~: 2116741)\nLogs:\n  Bound result 196900000000255687720\n  Bound result 7283246653944996\n\n[PASS] testGenesisAndFreeSpins() (gas: 1530829)\n[PASS] testGenesisPaidSpinSplit() (gas: 1195168)\n[PASS] testGenesisQuoteIsCappedAndTheSurplusStaysInTheVault() (gas: 2646822)\n[PASS] testImmatureBagsNotDrawable() (gas: 565751)\n[PASS] testOneOutstandingDrawAndCallbackRules() (gas: 1576979)\n[PASS] testRegularSpinKeep() (gas: 2275464)\n[PASS] testRejectsUnexpectedEthAndEmptyCredit() (gas: 154595)\n[PASS] testReserveTooLowBlocksSpins() (gas: 119501)\n[PASS] testSpinRules() (gas: 492530)\n[PASS] testWithdrawExitFeeAndUnpricedExitFree() (gas: 1221066)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 520.05ms (68.76ms CPU time)\n\nRan 1 test for test/GoblinEscrow.invariant.t.sol:GoblinEscrowInvariantTest\n[PASS] invariant_reviewsRefundsRevenueReleaseAndPullsRemainSolvent() (runs: 128, calls: 8192, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| EscrowHandler | advance  | 1057  | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| EscrowHandler | claim    | 969   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| EscrowHandler | deposit  | 995   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| EscrowHandler | pull     | 1006  | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| EscrowHandler | refund   | 1050  | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| EscrowHandler | release  | 1035  | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| EscrowHandler | renounce | 1027  | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| EscrowHandler | review   | 1053  | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 8516\n  Bound result 1000000000000000000\n  Bound result 4096\n  Bound result 672059847471244204\n  Bound result 512\n  Bound result 2039\n  Bound result 455957391556137398\n  Bound result 7035312\n  Bound result 9999\n  Bound result 7224628\n  Bound result 1798\n  Bound result 1800000000\n  Bound result 8639997\n  Bound result 789\n  Bound result 1645\n  Bound result 1\n  Bound result 1618667\n  Bound result 600\n  Bound result 2204\n  Bound result 9722\n  Bound result 1\n  Bound result 13886\n  Bound result 320000\n  Bound result 10000\n  Bound result 3\n  Bound result 5826864\n  Bound result 120720753247507456\n  Bound result 7327\n  Bound result 5407\n  Bound result 709765695563885981\n  Bound result 8053\n  Bound result 2684\n  Bound result 3000\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.06s (1.00s CPU time)\n\nRan 1 test for test/Curator.invariant.t.sol:CuratorInvariantTest\n[PASS] invariant_onlyFreshApprovedBoundedChangesExecuteOnce() (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+-----------------+-------+---------+----------╮\n| Contract       | Selector        | Calls | Reverts | Discards |\n+===============================================================+\n| CuratorHandler | advance         | 1627  | 0       | 0        |\n|----------------+-----------------+-------+---------+----------|\n| CuratorHandler | bypass          | 1614  | 0       | 0        |\n|----------------+-----------------+-------+---------+----------|\n| CuratorHandler | discount        | 1631  | 0       | 0        |\n|----------------+-----------------+-------+---------+----------|\n| CuratorHandler | invalidProposal | 1621  | 0       | 0        |\n|----------------+-----------------+-------+---------+----------|\n| CuratorHandler | replay          | 1699  | 0       | 0        |\n╰----------------+-----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 51200\n  Bound result 1039\n  Bound result 1136\n  Bound result 4095\n  Bound result 20\n  Bound result 5000\n  Bound result 825\n  Bound result 664\n  Bound result 833\n  Bound result 0\n  Bound result 776\n  Bound result 36992\n  Bound result 7535\n  Bound result 16965\n  Bound result 3945\n  Bound result 68034\n  Bound result 810\n  Bound result 4\n  Bound result 35200\n  Bound result 1023\n  Bound result 198\n  Bound result 705\n  Bound result 813\n  Bound result 16506\n  Bound result 448\n  Bound result 2306\n  Bound result 80000\n  Bound result 709\n  Bound result 458\n  Bound result 40511\n  Bound result 8427\n  Bound result 1200\n  Bound result 910\n  Bound result 792\n  Bound result 950\n  Bound result 694\n  Bound result 0\n  Bound result 731\n  Bound result 644\n  Bound result 19485\n  Bound result 12488\n  Bound result 102\n  Bound result 32\n  Bound result 12\n  Bound result 9391\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.18s (1.18s CPU time)\n\nRan 1 test for test/BagGacha.invariant.t.sol:BagGachaInvariantTest\n[PASS] invariant_allReserveAndTokenLiabilitiesAreBacked() (runs: 128, calls: 8192, reverts: 0)\n\n╭--------------+--------------------+-------+---------+----------╮\n| Contract     | Selector           | Calls | Reverts | Discards |\n+================================================================+\n| GachaHandler | advance            | 689   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | cancel             | 670   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | changeAvailability | 695   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | changeCap          | 701   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | claim              | 671   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | draw               | 664   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | flush              | 694   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | fulfill            | 703   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | seal               | 673   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | settle             | 656   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | spin               | 667   | 0       | 0        |\n|--------------+--------------------+-------+---------+----------|\n| GachaHandler | withdrawBag        | 709   | 0       | 0        |\n╰--------------+--------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 199999999999999999997\n  Bound result 650\n  Bound result 199000000000048880\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 151944\n  Bound result 197000000000000002001\n  Bound result 1\n  Bound result 1122\n  Bound result 2\n  Bound result 36471\n  Bound result 132667230795206373234\n  Bound result 82958341941214771\n  Bound result 170824\n  Bound result 4953508603369625\n  Bound result 4999999999998995\n  Bound result 1\n  Bound result 2\n  Bound result 1\n  Bound result 126194006469037189768\n  Bound result 2500\n  Bound result 2\n  Bound result 1\n  Bound result 2\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.34s (1.34s CPU time)\n\nRan 1 test for test/GoblinNFT.invariant.t.sol:GoblinNFTInvariantTest\n[PASS] invariant_revenueAndRefundBackingMatchIndependentLedger() (runs: 128, calls: 8192, reverts: 0)\n\n╭------------+----------+-------+---------+----------╮\n| Contract   | Selector | Calls | Reverts | Discards |\n+====================================================+\n| NFTHandler | claim    | 1649  | 0       | 0        |\n|------------+----------+-------+---------+----------|\n| NFTHandler | deposit  | 1657  | 0       | 0        |\n|------------+----------+-------+---------+----------|\n| NFTHandler | mint     | 1557  | 0       | 0        |\n|------------+----------+-------+---------+----------|\n| NFTHandler | refund   | 1693  | 0       | 0        |\n|------------+----------+-------+---------+----------|\n| NFTHandler | transfer | 1636  | 0       | 0        |\n╰------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 43\n  Bound result 20\n  Bound result 20\n  Bound result 15\n  Bound result 6226\n  Bound result 19\n  Bound result 20\n  Bound result 593991679159461444\n  Bound result 3\n  Bound result 5\n  Bound result 760691285\n  Bound result 4295128739\n  Bound result 1\n  Bound result 20\n  Bound result 10\n  Bound result 7064\n  Bound result 25\n  Bound result 13\n  Bound result 6\n  Bound result 42\n  Bound result 9\n  Bound result 200000\n  Bound result 18376\n  Bound result 500000000000000000\n  Bound result 300\n  Bound result 12\n  Bound result 21\n  Bound result 11\n  Bound result 2952\n  Bound result 33\n  Bound result 54\n  Bound result 22\n  Bound result 14\n  Bound result 23\n  Bound result 15\n  Bound result 22\n  Bound result 3\n  Bound result 5\n  Bound result 18\n  Bound result 6610\n  Bound result 17\n  Bound result 13\n  Bound result 42\n  Bound result 7\n  Bound result 49\n  Bound result 20\n  Bound result 61\n  Bound result 56\n  Bound result 72\n  Bound result 7\n  Bound result 22\n  Bound result 13\n  Bound result 2\n  Bound result 5\n  Bound result 40\n  Bound result 3\n  Bound result 89\n  Bound result 255598759316771853\n  Bound result 1486803787\n  Bound result 43\n  Bound result 4\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 9.63s (9.63s CPU time)\n\nRan 23 test suites in 9.63s (18.05s CPU time): 160 tests passed, 0 failed, 2 skipped (162 total tests)\n","passed":true},{"durationMs":89,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"BagGacha.cancelRequest()\",\"BagGacha.choose(uint256,bool)\",\"BagGacha.claimBag(uint256)\",\"BagGacha.draw()\",\"BagGacha.finalize(uint256)\",\"BagGacha.flush()\",\"BagGacha.freeSpin(uint256)\",\"BagGacha.fundReserve()\",\"BagGacha.fundVRF()\",\"BagGacha.holderSpin(uint256)\",\"BagGacha.pullMintEscrow()\",\"BagGacha.rawFulfillRandomWords(uint256,uint256[])\",\"BagGacha.receive()\",\"BagGacha.seal(address[],uint256[])\",\"BagGacha.setTierOdds(uint256[4])\",\"BagGacha.spin()\",\"BagGacha.withdraw(uint256)\",\"BagGacha.withdrawCredit()\",\"Curator.clear(uint256)\",\"Curator.execute(uint256)\",\"Curator.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"Curator.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"Curator.propose(uint8,bytes,(uint64,uint64),bytes32,uint256)\",\"GenesisVault.claim()\",\"GenesisVault.claimDividends()\",\"GenesisVault.commit(bool)\",\"GenesisVault.deliver(address,uint256)\",\"GenesisVault.setDiscount(uint256)\",\"GenesisVault.setShares(address,uint256)\",\"GenesisVault.uncommit(uint256)\",\"GoblinNFT.approve(address,uint256)\",\"GoblinNFT.claimRelease()\",\"GoblinNFT.claimRevenue(uint256[])\",\"GoblinNFT.depositRevenue()\",\"GoblinNFT.mint(uint256)\",\"GoblinNFT.refund(uint256)\",\"GoblinNFT.release()\",\"GoblinNFT.renounceOwnership()\",\"GoblinNFT.reveal()\",\"GoblinNFT.safeTransferFrom(address,address,uint256)\",\"GoblinNFT.safeTransferFrom(address,address,uint256,bytes)\",\"GoblinNFT.setApprovalForAll(address,bool)\",\"GoblinNFT.setLaunchTargets(address,address,address)\",\"GoblinNFT.transferFrom(address,address,uint256)\",\"GoblinNFT.transferOwnership(address)\",\"GoldHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"GoldHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"GoldHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"GoldHook.bindGacha(address)\",\"GoldHook.flush()\",\"GoldHook.receive()\",\"GoldHook.unlockCallback(bytes)\",\"POLManager.addLiquidity(uint256)\",\"POLManager.buyAndBurn(uint256)\",\"POLManager.depositBurn()\",\"POLManager.depositPOL()\",\"POLManager.pullMintEscrow()\",\"POLManager.receive()\",\"POLManager.recycle()\",\"POLManager.unlockCallback(bytes)\",\"TwapOracle.setPool(address,address)\",\"TwapOracle.setTokenPaused(address,bool)\"],\"files\":{\".gitignore\":3,\"README.md\":447,\"foundry.toml\":14,\"remappings.txt\":2,\"report.md\":58,\"script/DeployGoblinNFT.s.sol\":13,\"src/BagGacha.sol\":949,\"src/Curator.sol\":405,\"src/GenesisVault.sol\":225,\"src/GoblinArt.sol\":235,\"src/GoblinNFT.sol\":334,\"src/GoldHook.sol\":464,\"src/IMDProtocol.sol\":19,\"src/OracleAttestation.sol\":221,\"src/POLManager.sol\":239,\"src/TickMath.sol\":77,\"src/TwapOracle.sol\":300,\"src/v4/V4Minimal.sol\":92,\"test/Audit85083c05.t.sol\":472,\"test/BagGacha.invariant.t.sol\":235,\"test/BagGacha.t.sol\":320,\"test/BagGachaV2.t.sol\":282,\"test/Curator.invariant.t.sol\":125,\"test/Curator.t.sol\":391,\"test/GasBench.t.sol\":92,\"test/GenesisVault.t.sol\":111,\"test/GoblinEscrow.invariant.t.sol\":184,\"test/GoblinNFT.invariant.t.sol\":131,\"test/GoblinNFT.t.sol\":205,\"test/GoblinNFTDeployed.t.sol\":78,\"test/GoblinNFTV2.t.sol\":103,\"test/GoldHook.invariant.t.sol\":114,\"test/GoldHook.t.sol\":401,\"test/OracleConsumerConformance.t.sol\":146,\"test/PayoutCap.t.sol\":279,\"test/TickMath.t.sol\":22,\"test/TwapOracle.t.sol\":211,\"test/fork/MainnetFork.t.sol\":90,\"test/fork/MainnetV4Fork.t.sol\":141,\"test/mocks/AdversarialMocks.sol\":42,\"test/mocks/CuratorMocks.sol\":139,\"test/mocks/Mocks.sol\":169,\"test/mocks/V4Fixture.sol\":116,\"test/v4-core/BUSL_LICENSE\":63,\"test/v4-core/ERC6909.sol\":90,\"test/v4-core/ERC6909Claims.sol\":23,\"test/v4-core/Extsload.sol\":64,\"test/v4-core/Exttload.sol\":40,\"test/v4-core/MIT_LICENSE\":7,\"test/v4-core/NoDelegateCall.sol\":33,\"test/v4-core/PoolManager.sol\":394,\"test/v4-core/ProtocolFees.sol\":71,\"test/v4-core/interfaces/IExtsload.sol\":21,\"test/v4-core/interfaces/IExttload.sol\":15,\"test/v4-core/interfaces/IHooks.sol\":152,\"test/v4-core/interfaces/IPoolManager.sol\":217,\"test/v4-core/interfaces/IProtocolFees.sol\":52,\"test/v4-core/interfaces/callback/IUnlockCallback.sol\":10,\"test/v4-core/interfaces/external/IERC20Minimal.sol\":48,\"test/v4-core/interfaces/external/IERC6909Claims.sol\":66,\"test/v4-core/libraries/BitMath.sol\":49,\"test/v4-core/libraries/CurrencyDelta.sol\":42,\"test/v4-core/libraries/CurrencyReserves.sol\":39,\"test/v4-core/libraries/CustomRevert.sol\":120,\"test/v4-core/libraries/FixedPoint128.sol\":8,\"test/v4-core/libraries/FixedPoint96.sol\":10,\"test/v4-core/libraries/FullMath.sol\":117,\"test/v4-core/libraries/Hooks.sol\":344,\"test/v4-core/libraries/LPFeeLibrary.sol\":79,\"test/v4-core/libraries/LiquidityMath.sol\":20,\"test/v4-core/libraries/Lock.sol\":28,\"test/v4-core/libraries/NonzeroDeltaCount.sol\":35,\"test/v4-core/libraries/ParseBytes.sol\":29,\"test/v4-core/libraries/Pool.sol\":620,\"test/v4-core/libraries/Position.sol\":103,\"test/v4-core/libraries/ProtocolFeeLibrary.sol\":47,\"test/v4-core/libraries/SafeCast.sol\":60,\"test/v4-core/libraries/SqrtPriceMath.sol\":292,\"test/v4-core/libraries/StateLibrary.sol\":345,\"test/v4-core/libraries/SwapMath.sol\":108,\"test/v4-core/libraries/TickBitmap.sol\":121,\"test/v4-core/libraries/TickMath.sol\":238,\"test/v4-core/libraries/TransientStateLibrary.sol\":48,\"test/v4-core/libraries/UnsafeMath.sol\":29,\"test/v4-core/solmate/Owned.sol\":44,\"test/v4-core/test/PoolModifyLiquidityTest.sol\":96,\"test/v4-core/test/PoolSwapTest.sol\":117,\"test/v4-core/test/PoolTestBase.sol\":31,\"test/v4-core/types/BalanceDelta.sol\":72,\"test/v4-core/types/BeforeSwapDelta.sol\":38,\"test/v4-core/types/Currency.sol\":118,\"test/v4-core/types/PoolId.sol\":17,\"test/v4-core/types/PoolKey.sol\":22,\"test/v4-core/types/PoolOperation.sol\":26,\"test/v4-core/types/Slot0.sol\":95,\"test/v4-core/utils/CurrencySettler.sol\":46},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":16615,"exitCode":0,"name":"slither","output":"[high/medium] arbitrary-send-eth at src/GoldHook.sol:309: GoldHook.flush() (src/GoldHook.sol#309-324) sends eth to arbitrary user\n[high/medium] arbitrary-send-eth at src/BagGacha.sol:913: BagGacha.flush() (src/BagGacha.sol#913-924) sends eth to arbitrary user\n[high/medium] arbitrary-send-eth at src/BagGacha.sol:515: BagGacha._request(address,uint256,uint256,bool,bool) (src/BagGacha.sol#515-560) sends eth to arbitrary user\n[high/medium] reentrancy-eth at src/BagGacha.sol:515: Reentrancy in BagGacha._request(address,uint256,uint256,bool,bool) (src/BagGacha.sol#515-560):\n[medium/medium] divide-before-multiply at src/GoldHook.sol:236: GoldHook.afterSwap(address,PoolKey,SwapParams,int256,bytes) (src/GoldHook.sol#236-278) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/TickMath.sol:10: TickMath.sqrtPriceAtTick(int24) (src/TickMath.sol#10-76) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/GoldHook.sol:385: GoldHook._observeSingle(uint32,uint32,int24) (src/GoldHook.sol#385-401) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/GoldHook.sol:350: GoldHook.liquidityAt(uint32) (src/GoldHook.sol#350-358) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/BagGacha.sol:565: BagGacha._commitGenesis(bool) (src/BagGacha.sol#565-585) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/BagGacha.sol:565: BagGacha._commitGenesis(bool) (src/BagGacha.sol#565-585) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/GoldHook.sol:385: GoldHook._observeSingle(uint32,uint32,int24) (src/GoldHook.sol#385-401) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/BagGacha.sol:515: BagGacha._request(address,uint256,uint256,bool,bool) (src/BagGacha.sol#515-560) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/GoldHook.sol:360: GoldHook._write(int24,uint128) (src/GoldHook.sol#360-373) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/POLManager.sol:199: POLManager._addFullRange(uint256,uint256) (src/POLManager.sol#199-225) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/GoldHook.sol:385: GoldHook._observeSingle(uint32,uint32,int24) (src/GoldHook.sol#385-401) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/POLManager.sol:141: Reentrancy in POLManager.addLiquidity(uint256) (src/POLManager.sol#141-160):\n[medium/medium] reentrancy-no-eth at src/Curator.sol:155: Reentrancy in Curator.propose(Curator.Kind,bytes,Curator.Window,bytes32,uint256) (src/Curator.sol#155-182):\n[medium/medium] reentrancy-no-eth at src/BagGacha.sol:515: Reentrancy in BagGacha._request(address,uint256,uint256,bool,bool) (src/BagGacha.sol#515-560):\n[medium/medium] uninitialized-local at src/GoldHook.sol:224: GoldHook.beforeSwap(address,PoolKey,SwapParams,bytes).delta (src/GoldHook.sol#224) is a local variable never initialized\n[medium/medium] uninitialized-local at src/Curator.sol:214: Curator._validate(Curator.Kind,bytes).token (src/Curator.sol#214) is a local variable never initialized\n[medium/medium] uninitialized-local at src/BagGacha.sol:293: BagGacha.setTierOdds(uint256[4]).sum (src/BagGacha.sol#293) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GoldHook.sol:243: GoldHook.afterSwap(address,PoolKey,SwapParams,int256,bytes).tax (src/GoldHook.sol#243) is a local variable never initialized\n[medium/medium] uninitialized-local at src/Curator.sol:229: Curator._validate(Curator.Kind,bytes).sum (src/Curator.sol#229) is a local variable never initialized\n[medium/medium] uninitialized-local at src/BagGacha.sol:566: BagGacha._commitGenesis(bool).quoted (src/BagGacha.sol#566) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GoldHook.sol:244: GoldHook.afterSwap(address,PoolKey,SwapParams,int256,bytes).unspecified (src/GoldHook.sol#244) is a local variable never initialized\n[medium/medium] unused-return at src/POLManager.sol:199: POLManager._addFullRange(uint256,uint256) (src/POLManager.sol#199-225) ignores return value by poolManager.settle{value: ethUsed}() (src/POLManager.sol#216)\n[medium/medium] unused-return at src/GoldHook.sol:309: GoldHook.flush() (src/GoldHook.sol#309-324) ignores return value by poolManager.unlock(abi.encode(total)) (src/GoldHook.sol#319)\n[medium/medium] unused-return at src/POLManager.sol:199: POLManager._addFullRange(uint256,uint256) (src/POLManager.sol#199-225) ignores return value by poolManager.settle() (src/POLManager.sol#220)\n[medium/medium] unused-return at src/POLManager.sol:188: POLManager._buy(uint256,uint256,address) (src/POLManager.sol#188-197) ignores return value by poolManager.settle{value: uint256(uint128(- a0))}() (src/POLManager.sol#195)\n[medium/medium] unused-return at src/POLManager.sol:199: POLManager._addFullRange(uint256,uint256) (src/POLManager.sol#199-225) ignores return value by (sqrtPrice,None) = V4Lib.slot0(poolManager,V4Lib.poolId(poolKey())) (src/POLManager.sol#200)\n[medium/medium] unused-return at src/GoldHook.sol:216: GoldHook.beforeSwap(address,PoolKey,SwapParams,bytes) (src/GoldHook.sol#216-230) ignores return value by (None,tick) = V4Lib.slot0(poolManager,poolId) (src/GoldHook.sol#222)\n[medium/medium] unused-return at src/GoldHook.sol:337: GoldHook.observe(uint32[]) (src/GoldHook.sol#337-344) ignores return value by (None,tick) = V4Lib.slot0(poolManager,poolId) (src/GoldHook.sol#339)\n[medium/medium] unused-return at src/POLManager.sol:199: POLManager._addFullRange(uint256,uint256) (src/POLManager.sol#199-225) ignores return value by (delta,None) = poolManager.modifyLiquidity(poolKey(),ModifyLiquidityParams(TICK_LOWER,TICK_UPPER,int256(uint256(liquidity)),bytes32(0)),) (src/POLManager.sol#203-205)\n[medium/medium] unused-return at src/TwapOracle.sol:225: TwapOracle._checkGenesisPool() (src/TwapOracle.sol#225-244) ignores return value by (sqrtPrice,None) = goldHook.slot0() (src/TwapOracle.sol#228)\n[low/medium] calls-loop at src/BagGacha.sol:320: BagGacha.bagValue(uint256) (src/BagGacha.sol#320-325) has external calls inside a loop: v += oracle.valueInEth(b.tokens[i],b.amounts[i]) (src/BagGacha.sol#323)\n[low/medium] calls-loop at src/BagGacha.sol:599: BagGacha._buildSnapshot() (src/BagGacha.sol#599-649) has external calls inside a loop: (got,full,amounts,capped) = this.bagPayout(id) (src/BagGacha.sol#608-613)\n[low/medium] calls-loop at src/BagGacha.sol:404: BagGacha.seal(address[],uint256[]) (src/BagGacha.sol#404-438) has external calls inside a loop: amounts[i] < 1 || ! oracle.isPriced(tokens[i]) (src/BagGacha.sol#410)\n[low/medium] calls-loop at src/BagGacha.sol:404: BagGacha.seal(address[],uint256[]) (src/BagGacha.sol#404-438) has external calls inside a loop: beforeBalance = IERC20(tokens[i_scope_0]).balanceOf(address(this)) (src/BagGacha.sol#433)\n[low/medium] calls-loop at src/BagGacha.sol:599: BagGacha._buildSnapshot() (src/BagGacha.sol#599-649) has external calls inside a loop: (got,full,amounts,capped) = this.bagPayout(id) (src/BagGacha.sol#608-613)\n[low/medium] calls-loop at src/BagGacha.sol:404: BagGacha.seal(address[],uint256[]) (src/BagGacha.sol#404-438) has external calls inside a loop: IERC20(tokens[i_scope_0]).balanceOf(address(this)) - beforeBalance != amounts[i_scope_0] (src/BagGacha.sol#435)\n[low/medium] calls-loop at src/BagGacha.sol:404: BagGacha.seal(address[],uint256[]) (src/BagGacha.sol#404-438) has external calls inside a loop: value += oracle.valueInEth(tokens[i],amounts[i]) (src/BagGacha.sol#414)\n[low/medium] calls-loop at src/BagGacha.sol:599: BagGacha._buildSnapshot() (src/BagGacha.sol#599-649) has external calls inside a loop: (got,full,amounts,capped) = this.bagPayout(id) (src/BagGacha.sol#608-613)\n[low/medium] calls-loop at src/BagGacha.sol:330: BagGacha.bagPayout(uint256) (src/BagGacha.sol#330-351) has external calls inside a loop: (v,cap) = oracle.valueAndCap(b.tokens[i],full) (src/BagGacha.sol#340)\n[low/medium] reentrancy-benign at src/POLManager.sol:141: Reentrancy in POLManager.addLiquidity(uint256) (src/POLManager.sol#141-160):\n[low/medium] reentrancy-benign at src/POLManager.sol:127: Reentrancy in POLManager.buyAndBurn(uint256) (src/POLManager.sol#127-137):\n[low/medium] reentrancy-benign at src/BagGacha.sol:515: Reentrancy in BagGacha._request(address,uint256,uint256,bool,bool) (src/BagGacha.sol#515-560):\n[low/medium] reentrancy-benign at src/GoldHook.sol:309: Reentrancy in GoldHook.flush() (src/GoldHook.sol#309-324):\n[low/medium] reentrancy-benign at src/Curator.sol:155: Reentrancy in Curator.propose(Curator.Kind,bytes,Curator.Window,bytes32,uint256) (src/Curator.sol#155-182):\n[low/medium] reentrancy-events at src/GoldHook.sol:236: Reentrancy in GoldHook.afterSwap(address,PoolKey,SwapParams,int256,bytes) (src/GoldHook.sol#236-278):\n[low/medium] timestamp at src/GoldHook.sol:169: GoldHook.buyTaxBps() (src/GoldHook.sol#169-176) uses timestamp for comparisons\n[low/medium] timestamp at src/GenesisVault.sol:178: GenesisVault._accrue() (src/GenesisVault.sol#178-187) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:665: BagGacha.cancelRequest() (src/BagGacha.sol#665-688) uses timestamp for comparisons\n[low/medium] timestamp at src/GenesisVault.sol:103: GenesisVault.target() (src/GenesisVault.sol#103-108) uses timestamp for comparisons\n[low/medium] timestamp at src/GoldHook.sol:454: GoldHook._checkBuyCap(uint256) (src/GoldHook.sol#454-458) uses timestamp for comparisons\n[low/medium] timestamp at src/GenesisVault.sol:205: GenesisVault.pendingDividends(address) (src/GenesisVault.sol#205-213) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:758: BagGacha._select(uint256) (src/BagGacha.sol#758-777) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:816: BagGacha.finalize(uint256) (src/BagGacha.sol#816-821) uses timestamp for comparisons\n[low/medium] timestamp at src/GenesisVault.sol:113: GenesisVault.quote(bool) (src/GenesisVault.sol#113-135) uses timestamp for comparisons\n[low/medium] timestamp at src/GoblinNFT.sol:129: GoblinNFT.refundsOpen() (src/GoblinNFT.sol#129-134) uses timestamp for comparisons\n[low/medium] timestamp at src/Curator.sol:329: Curator.onOracleResult(bytes32,OracleAttestation.Attestation,bytes) (src/Curator.sol#329-359) uses timestamp for comparisons\n[low/medium] timestamp at src/Curator.sol:376: Curator.clear(uint256) (src/Curator.sol#376-383) uses timestamp for comparisons\n[low/medium] timestamp at src/GoldHook.sol:287: GoldHook.bindGacha(address) (src/GoldHook.sol#287-305) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:479: BagGacha.holderSpin(uint256) (src/BagGacha.sol#479-486) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:290: BagGacha.setTierOdds(uint256[4]) (src/BagGacha.sol#290-304) uses timestamp for comparisons\n[low/medium] timestamp at src/GoblinNFT.sol:221: GoblinNFT.release() (src/GoblinNFT.sol#221-236) uses timestamp for comparisons\n[low/medium] timestamp at src/GoldHook.sol:404: GoldHook._surroundings(uint32) (src/GoldHook.sol#404-428) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:653: BagGacha.rawFulfillRandomWords(uint256,uint256[]) (src/BagGacha.sol#653-659) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:807: BagGacha.choose(uint256,bool) (src/BagGacha.sol#807-813) uses timestamp for comparisons\n[low/medium] timestamp at src/GenesisVault.sol:215: GenesisVault.claimDividends() (src/GenesisVault.sol#215-224) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:442: BagGacha.withdraw(uint256) (src/BagGacha.sol#442-467) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:489: BagGacha.freeSpin(uint256) (src/BagGacha.sol#489-501) uses timestamp for comparisons\n[low/medium] timestamp at src/GoldHook.sol:385: GoldHook._observeSingle(uint32,uint32,int24) (src/GoldHook.sol#385-401) uses timestamp for comparisons\n[low/medium] timestamp at src/GoldHook.sol:350: GoldHook.liquidityAt(uint32) (src/GoldHook.sol#350-358) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:515: BagGacha._request(address,uint256,uint256,bool,bool) (src/BagGacha.sol#515-560) uses timestamp for comparisons\n[low/medium] timestamp at src/GoldHook.sol:360: GoldHook._write(int24,uint128) (src/GoldHook.sol#360-373) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:565: BagGacha._commitGenesis(bool) (src/BagGacha.sol#565-585) uses timestamp for comparisons\n[low/medium] timestamp at src/Curator.sol:385: Curator.execute(uint256) (src/Curator.sol#385-404) uses timestamp for comparisons\n[low/medium] timestamp at src/TwapOracle.sol:202: TwapOracle._checkPool(address,address) (src/TwapOracle.sol#202-217) uses timestamp for comparisons\n[low/medium] timestamp at src/TwapOracle.sol:225: TwapOracle._checkGenesisPool() (src/TwapOracle.sol#225-244) uses timestamp for comparisons\n[low/medium] timestamp at src/OracleAttestation.sol:157: OracleAttestationConsumer._verifyAttestation(OracleAttestation.Attestation,bytes) (src/OracleAttestation.sol#157-165) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:599: BagGacha._buildSnapshot() (src/BagGacha.sol#599-649) uses timestamp for comparisons\n[low/medium] timestamp at src/BagGacha.sol:472: BagGacha.spin() (src/BagGacha.sol#472-476) uses timestamp for comparisons","passed":true},{"durationMs":863,"exitCode":0,"name":"aderyn","output":"[high] contract-locks-ether at src/GoldHook.sol:48: Contract locks Ether without a withdraw function (2 places)\n[high] eth-send-unchecked-address at src/BagGacha.sol:890: ETH transferred without address checks\n[high] incorrect-shift-order at src/v4/V4Minimal.sol:76: Incorrect Assembly Shift Parameter Order\n[high] reentrancy-state-change at src/BagGacha.sol:410: Reentrancy: State change after external call (20 places)\n[high] unsafe-casting at src/TickMath.sol:75: Unsafe Casting of integers\n[low] centralization-risk at src/GoblinNFT.sol:20: Centralization Risk (3 places)\n[low] costly-loop at src/BagGacha.sol:604: Costly operations inside loop (4 places)\n[low] internal-function-used-once at src/OracleAttestation.sol:185: Internal Function Used Only Once\n[low] large-numeric-literal at src/BagGacha.sol:85: Large Numeric Literal (12 places)\n[low] literal-instead-of-constant at src/BagGacha.sol:290: Literal Instead of Constant (297 places)\n[low] local-variable-shadowing at src/GoldHook.sol:54: Local Variable Shadows State Variable\n[low] missing-inheritance at src/TwapOracle.sol:48: Missing Inheritance\n[low] require-revert-in-loop at src/BagGacha.sol:294: Loop Contains `require`/`revert` (9 places)\n[low] state-change-without-event at src/POLManager.sol:164: State Change Without Event\n[low] state-variable-could-be-immutable at src/BagGacha.sol:93: State Variable Could Be Immutable (8 places)\n[low] storage-array-length-not-cached at src/BagGacha.sol:604: Storage Array Length not Cached (2 places)\n[low] unchecked-return at src/GoldHook.sol:319: Unchecked Return (4 places)\n[low] uninitialized-local-variable at src/BagGacha.sol:294: Uninitialized Local Variable (2 places)\n[low] unsafe-oz-erc721-mint at src/GoblinNFT.sol:124: Unsafe `ERC721::_mint()`\n[low] unused-public-function at src/BagGacha.sol:320: Public Function Not Used Internally (8 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"10b8541dfe4884422526c4a388c10ab1798c16051bb5cae7667dbc037ca7714b","verifiedTreeHash":"a957dd14bfa508e69cc11e9095e8952603c7ad9e","verifierVersion":"0.1.0+67c588fa"}]}