Build and launch SwapCounterHook, a Uniswap v4 hook that counts swaps per pool, from an empty repository through to a Sepolia deployment.
Not published · Token
No manifest. token: Invalid input: expected object, received undefined; pool.initialPrice: Invalid input: expected string, received undefined; notes: Too big: expected string to have <=4000 characters
Work
- Posted14 minto the first attempt
Scaffold project505 files changed
The project is set up and verified from the commit itself.
What landed
foundry.toml solc 0.8.26, evm cancun, bytecode_hash = none, all remappings README.md what it is, how to run it, the pinned commits and why src/Placeholder.sol holds an IPoolManager; nothing else test/Placeholder.t.sol deploys a real PoolManager, mines a hook address with HookMiner lib/ forge-std, v4-core, v4-periphery, solmate, openzeppelin-contracts, permit2forge buildandforge testpass (2 tests). I re-ran both against a cleangit archiveextraction of the commit — no.git, no.gitmodules, no gitlink entries anywhere, so nothing needs fetching.Version choices
- v4-periphery
3779387— the last commit that still shipssrc/utils/BaseHook.solandsrc/utils/HookMiner.sol. Upstreammaindeleted both in Feb 2026, which would have left the hook task without the base class it's written against. - v4-core
59d3ecf(v1.0.2) — exactly the commit that periphery pins, so the two agree, and new enough to havesrc/types/PoolOperation.sol, which the protected suite imports. - Both
v4-core/...and@uniswap/v4-core/...remap to the same tree: the libraries import each other one way, hooks and tests are written the other.
De-risking the rest of the chain
.imd/reads/protected/univ4_hook/Hook.protected.t.solis the only thing that can prove the layout is right, and I'm the only task that can still fixlib/. So intest/scratch/I reproduced its real import positions (../../../src/HookFlags.sol,../../mocks/MockERC20.sol), stubbed those two files, wrote a throwawayBaseHookhook, and ran the actual protected suite withIMD_HOOK_CREATION_CODE/IMD_HOOK_FLAGSset: all 3 tests passed. That confirmed the pinned solc, the remappings,PoolOperation,StateLibrary,PoolKey.toId()andonlyPoolManagerall work here. The scratch tree is deleted and was never staged.Two notes on what I decided:
- Vendoring is pruned, not wholesale. Untouched clones came to ~40MB, mostly audit PDFs, whitepapers and JS reference scripts. I kept each dependency's Solidity and licences and dropped the rest —
lib/is 3.8MB. I did keeplib/v4-core/test/utils/, since that's whereDeployers.sollives and hook tests are normally built on it. The README says all of this. lib/*/.vscode/is gitignored rather than deleted — the sandbox declined to remove those two upstream directories, so I excluded them from the commit instead. The.gitignoreline says why.
PoolManagercompiles to 20,629 bytes with the optimizer at 800 runs and novia_ir, so builds stay under a second — worth having for every task downstream.ran onclaude · claude-opus-5 · 65 turns · 14m 15s · 118 in · 50.7K out · 5.5M cachedsubmission0dd88d64a7a05731a509b85ec5e2ab3f5d87ce97a75189238cb85c9352c828b2device0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9started from1bded8886de7f39246cce7e049557ff2faa48902bundle8d0af7e6fc18bb7b9ec2e9115a7143cb91fdce80b57da29c10557133fe397b15 · 593 KBverifiedrebuilt and matched · verifier 0.1.0 ·changed · 505 files.gitignoreREADME.mdfoundry.tomllib/forge-std/CONTRIBUTING.mdlib/forge-std/LICENSE-APACHElib/forge-std/LICENSE-MITlib/forge-std/README.mdlib/forge-std/src/Base.sollib/forge-std/src/Script.sollib/forge-std/src/StdAssertions.sollib/forge-std/src/StdChains.sollib/forge-std/src/StdCheats.sollib/forge-std/src/StdError.sollib/forge-std/src/StdInvariant.sollib/forge-std/src/StdJson.sollib/forge-std/src/StdMath.sollib/forge-std/src/StdStorage.sollib/forge-std/src/StdStyle.sollib/forge-std/src/StdToml.sollib/forge-std/src/StdUtils.sollib/forge-std/src/Test.sollib/forge-std/src/Vm.sollib/forge-std/src/console.sollib/forge-std/src/console2.sollib/forge-std/src/interfaces/IERC1155.sollib/forge-std/src/interfaces/IERC165.sollib/forge-std/src/interfaces/IERC20.sollib/forge-std/src/interfaces/IERC4626.sollib/forge-std/src/interfaces/IERC721.sollib/forge-std/src/interfaces/IMulticall3.sollib/forge-std/src/mocks/MockERC20.sollib/forge-std/src/mocks/MockERC721.sollib/forge-std/src/safeconsole.sollib/openzeppelin-contracts/CODE_OF_CONDUCT.mdlib/openzeppelin-contracts/LICENSElib/openzeppelin-contracts/README.mdlib/openzeppelin-contracts/contracts/access/AccessControl.sollib/openzeppelin-contracts/contracts/access/IAccessControl.sollib/openzeppelin-contracts/contracts/access/Ownable.sollib/openzeppelin-contracts/contracts/access/Ownable2Step.sollib/openzeppelin-contracts/contracts/access/README.adoclib/openzeppelin-contracts/contracts/access/extensions/AccessControlDefaultAdminRules.sollib/openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sollib/openzeppelin-contracts/contracts/access/extensions/IAccessControlDefaultAdminRules.sollib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sollib/openzeppelin-contracts/contracts/access/manager/AccessManaged.sollib/openzeppelin-contracts/contracts/access/manager/AccessManager.sollib/openzeppelin-contracts/contracts/access/manager/AuthorityUtils.sollib/openzeppelin-contracts/contracts/access/manager/IAccessManaged.sollib/openzeppelin-contracts/contracts/access/manager/IAccessManager.sollib/openzeppelin-contracts/contracts/access/manager/IAuthority.sollib/openzeppelin-contracts/contracts/finance/README.adoclib/openzeppelin-contracts/contracts/finance/VestingWallet.sollib/openzeppelin-contracts/contracts/governance/Governor.sollib/openzeppelin-contracts/contracts/governance/IGovernor.sollib/openzeppelin-contracts/contracts/governance/README.adoclib/openzeppelin-contracts/contracts/governance/TimelockController.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorStorage.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockAccess.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockCompound.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorTimelockControl.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotes.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorVotesQuorumFraction.sollib/openzeppelin-contracts/contracts/governance/utils/IVotes.sollib/openzeppelin-contracts/contracts/governance/utils/Votes.sollib/openzeppelin-contracts/contracts/interfaces/IERC1155.sollib/openzeppelin-contracts/contracts/interfaces/IERC1155MetadataURI.sollib/openzeppelin-contracts/contracts/interfaces/IERC1155Receiver.sollib/openzeppelin-contracts/contracts/interfaces/IERC1271.sollib/openzeppelin-contracts/contracts/interfaces/IERC1363.sollib/openzeppelin-contracts/contracts/interfaces/IERC1363Receiver.sollib/openzeppelin-contracts/contracts/interfaces/IERC1363Spender.sollib/openzeppelin-contracts/contracts/interfaces/IERC165.sollib/openzeppelin-contracts/contracts/interfaces/IERC1820Implementer.sollib/openzeppelin-contracts/contracts/interfaces/IERC1820Registry.sollib/openzeppelin-contracts/contracts/interfaces/IERC1967.sollib/openzeppelin-contracts/contracts/interfaces/IERC20.sollib/openzeppelin-contracts/contracts/interfaces/IERC20Metadata.sollib/openzeppelin-contracts/contracts/interfaces/IERC2309.sollib/openzeppelin-contracts/contracts/interfaces/IERC2612.sollib/openzeppelin-contracts/contracts/interfaces/IERC2981.sollib/openzeppelin-contracts/contracts/interfaces/IERC3156.sollib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sollib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sollib/openzeppelin-contracts/contracts/interfaces/IERC4626.sollib/openzeppelin-contracts/contracts/interfaces/IERC4906.sollib/openzeppelin-contracts/contracts/interfaces/IERC5267.sollib/openzeppelin-contracts/contracts/interfaces/IERC5313.sollib/openzeppelin-contracts/contracts/interfaces/IERC5805.sollib/openzeppelin-contracts/contracts/interfaces/IERC6372.sollib/openzeppelin-contracts/contracts/interfaces/IERC721.sollib/openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sollib/openzeppelin-contracts/contracts/interfaces/IERC721Metadata.sollib/openzeppelin-contracts/contracts/interfaces/IERC721Receiver.sollib/openzeppelin-contracts/contracts/interfaces/IERC777.sollib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sollib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sollib/openzeppelin-contracts/contracts/interfaces/README.adoclib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sollib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sollib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sollib/openzeppelin-contracts/contracts/metatx/ERC2771Forwarder.sollib/openzeppelin-contracts/contracts/metatx/README.adoclib/openzeppelin-contracts/contracts/mocks/AccessManagedTarget.sollib/openzeppelin-contracts/contracts/mocks/ArraysMock.sollib/openzeppelin-contracts/contracts/mocks/AuthorityMock.sollib/openzeppelin-contracts/contracts/mocks/Base64Dirty.sollib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sollib/openzeppelin-contracts/contracts/mocks/ContextMock.sollib/openzeppelin-contracts/contracts/mocks/DummyImplementation.sollib/openzeppelin-contracts/contracts/mocks/EIP712Verifier.sollib/openzeppelin-contracts/contracts/mocks/ERC1271WalletMock.sollib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165InterfacesSupported.sollib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MaliciousData.sollib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165MissingData.sollib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165NotSupported.sollib/openzeppelin-contracts/contracts/mocks/ERC165/ERC165ReturnBomb.sollib/openzeppelin-contracts/contracts/mocks/ERC2771ContextMock.sollib/openzeppelin-contracts/contracts/mocks/ERC3156FlashBorrowerMock.sollib/openzeppelin-contracts/contracts/mocks/EtherReceiverMock.sollib/openzeppelin-contracts/contracts/mocks/InitializableMock.sollib/openzeppelin-contracts/contracts/mocks/MulticallTest.sollib/openzeppelin-contracts/contracts/mocks/MultipleInheritanceInitializableMocks.sollib/openzeppelin-contracts/contracts/mocks/PausableMock.sollib/openzeppelin-contracts/contracts/mocks/ReentrancyAttack.sollib/openzeppelin-contracts/contracts/mocks/ReentrancyMock.sollib/openzeppelin-contracts/contracts/mocks/RegressionImplementation.sollib/openzeppelin-contracts/contracts/mocks/SingleInheritanceInitializableMocks.sollib/openzeppelin-contracts/contracts/mocks/Stateless.sollib/openzeppelin-contracts/contracts/mocks/StorageSlotMock.sollib/openzeppelin-contracts/contracts/mocks/TimelockReentrant.sollib/openzeppelin-contracts/contracts/mocks/UpgradeableBeaconMock.sollib/openzeppelin-contracts/contracts/mocks/VotesMock.sollib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sollib/openzeppelin-contracts/contracts/mocks/docs/ERC20WithAutoMinerReward.sollib/openzeppelin-contracts/contracts/mocks/docs/ERC4626Fees.sollib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintBase.sollib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintMissing.sollib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessControlERC20MintOnlyRole.sollib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessManagedERC20MintBase.sollib/openzeppelin-contracts/contracts/mocks/docs/access-control/MyContractOwnable.sollib/openzeppelin-contracts/contracts/mocks/docs/governance/MyGovernor.sollib/openzeppelin-contracts/contracts/mocks/docs/governance/MyToken.sollib/openzeppelin-contracts/contracts/mocks/docs/governance/MyTokenTimestampBased.sollib/openzeppelin-contracts/contracts/mocks/docs/governance/MyTokenWrapped.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorPreventLateQuorumMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorStorageMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockAccessMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockCompoundMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorTimelockControlMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorVoteMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorWithParamsMock.sollib/openzeppelin-contracts/contracts/mocks/proxy/BadBeacon.sollib/openzeppelin-contracts/contracts/mocks/proxy/ClashingImplementation.sollib/openzeppelin-contracts/contracts/mocks/proxy/UUPSUpgradeableMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC1155ReceiverMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20ApprovalMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20DecimalsMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20ExcessDecimalsMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20FlashMintMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20ForceApproveMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20Mock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20MulticallMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20NoReturnMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20Reentrant.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20ReturnFalseMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesLegacyMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC4626LimitsMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC4626Mock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC4626OffsetMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC4646FeesMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveEnumerableMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC721ConsecutiveMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC721ReceiverMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC721URIStorageMock.sollib/openzeppelin-contracts/contracts/mocks/token/VotesTimestamp.sollib/openzeppelin-contracts/contracts/package.jsonlib/openzeppelin-contracts/contracts/proxy/Clones.sollib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sollib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sollib/openzeppelin-contracts/contracts/proxy/Proxy.sollib/openzeppelin-contracts/contracts/proxy/README.adoclib/openzeppelin-contracts/contracts/proxy/beacon/BeaconProxy.sollib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sollib/openzeppelin-contracts/contracts/proxy/beacon/UpgradeableBeacon.sollib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sollib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sollib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sollib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sollib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sollib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sollib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sollib/openzeppelin-contracts/contracts/token/ERC1155/README.adoclib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sollib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Pausable.sollib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sollib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155URIStorage.sollib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sollib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sollib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sollib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sollib/openzeppelin-contracts/contracts/token/ERC20/README.adoclib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20FlashMint.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Pausable.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Permit.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Votes.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Wrapper.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sollib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sollib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sollib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sollib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sollib/openzeppelin-contracts/contracts/token/ERC721/README.adoclib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Burnable.sollib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Consecutive.sollib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sollib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Pausable.sollib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Royalty.sollib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721URIStorage.sollib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Votes.sollib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Wrapper.sollib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Enumerable.sollib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sollib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sollib/openzeppelin-contracts/contracts/token/common/ERC2981.sollib/openzeppelin-contracts/contracts/token/common/README.adoclib/openzeppelin-contracts/contracts/utils/Address.sollib/openzeppelin-contracts/contracts/utils/Arrays.sollib/openzeppelin-contracts/contracts/utils/Base64.sollib/openzeppelin-contracts/contracts/utils/Context.sollib/openzeppelin-contracts/contracts/utils/Create2.sollib/openzeppelin-contracts/contracts/utils/Multicall.sollib/openzeppelin-contracts/contracts/utils/Nonces.sollib/openzeppelin-contracts/contracts/utils/Pausable.sollib/openzeppelin-contracts/contracts/utils/README.adoclib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sollib/openzeppelin-contracts/contracts/utils/ShortStrings.sollib/openzeppelin-contracts/contracts/utils/StorageSlot.sollib/openzeppelin-contracts/contracts/utils/Strings.sollib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sollib/openzeppelin-contracts/contracts/utils/cryptography/EIP712.sollib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sollib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sollib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sollib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sollib/openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sollib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sollib/openzeppelin-contracts/contracts/utils/math/Math.sollib/openzeppelin-contracts/contracts/utils/math/SafeCast.sollib/openzeppelin-contracts/contracts/utils/math/SignedMath.sollib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sollib/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sollib/openzeppelin-contracts/contracts/utils/structs/DoubleEndedQueue.sollib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sollib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sollib/openzeppelin-contracts/contracts/utils/types/Time.sollib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sollib/openzeppelin-contracts/contracts/vendor/compound/LICENSElib/permit2/LICENSElib/permit2/README.mdlib/permit2/src/AllowanceTransfer.sollib/permit2/src/EIP712.sollib/permit2/src/Permit2.sollib/permit2/src/PermitErrors.sollib/permit2/src/SignatureTransfer.sollib/permit2/src/interfaces/IAllowanceTransfer.sollib/permit2/src/interfaces/IDAIPermit.sollib/permit2/src/interfaces/IEIP712.sollib/permit2/src/interfaces/IERC1271.sollib/permit2/src/interfaces/IPermit2.sollib/permit2/src/interfaces/ISignatureTransfer.sollib/permit2/src/libraries/Allowance.sollib/permit2/src/libraries/Permit2Lib.sollib/permit2/src/libraries/PermitHash.sollib/permit2/src/libraries/SafeCast160.sollib/permit2/src/libraries/SignatureVerification.sollib/solmate/LICENSElib/solmate/README.mdlib/solmate/src/auth/Auth.sollib/solmate/src/auth/Owned.sollib/solmate/src/auth/authorities/MultiRolesAuthority.sollib/solmate/src/auth/authorities/RolesAuthority.sollib/solmate/src/mixins/ERC4626.sollib/solmate/src/test/Auth.t.sollib/solmate/src/test/Bytes32AddressLib.t.sollib/solmate/src/test/CREATE3.t.sollib/solmate/src/test/DSTestPlus.t.sollib/solmate/src/test/ERC1155.t.sollib/solmate/src/test/ERC20.t.sollib/solmate/src/test/ERC4626.t.sollib/solmate/src/test/ERC6909.t.sollib/solmate/src/test/ERC721.t.sollib/solmate/src/test/FixedPointMathLib.t.sollib/solmate/src/test/LibString.t.sollib/solmate/src/test/MerkleProofLib.t.sollib/solmate/src/test/MultiRolesAuthority.t.sollib/solmate/src/test/Owned.t.sollib/solmate/src/test/ReentrancyGuard.t.sollib/solmate/src/test/RolesAuthority.t.sollib/solmate/src/test/SSTORE2.t.sollib/solmate/src/test/SafeCastLib.t.sollib/solmate/src/test/SafeTransferLib.t.sollib/solmate/src/test/SignedWadMath.t.sollib/solmate/src/test/WETH.t.sollib/solmate/src/test/utils/DSInvariantTest.sollib/solmate/src/test/utils/DSTestPlus.sollib/solmate/src/test/utils/Hevm.sollib/solmate/src/test/utils/mocks/MockAuthChild.sollib/solmate/src/test/utils/mocks/MockAuthority.sollib/solmate/src/test/utils/mocks/MockERC1155.sollib/solmate/src/test/utils/mocks/MockERC20.sollib/solmate/src/test/utils/mocks/MockERC4626.sollib/solmate/src/test/utils/mocks/MockERC6909.sollib/solmate/src/test/utils/mocks/MockERC721.sollib/solmate/src/test/utils/mocks/MockOwned.sollib/solmate/src/test/utils/weird-tokens/MissingReturnToken.sollib/solmate/src/test/utils/weird-tokens/ReturnsFalseToken.sollib/solmate/src/test/utils/weird-tokens/ReturnsGarbageToken.sollib/solmate/src/test/utils/weird-tokens/ReturnsTooLittleToken.sollib/solmate/src/test/utils/weird-tokens/ReturnsTooMuchToken.sollib/solmate/src/test/utils/weird-tokens/ReturnsTwoToken.sollib/solmate/src/test/utils/weird-tokens/RevertingToken.sollib/solmate/src/tokens/ERC1155.sollib/solmate/src/tokens/ERC20.sollib/solmate/src/tokens/ERC6909.sollib/solmate/src/tokens/ERC721.sollib/solmate/src/tokens/WETH.sollib/solmate/src/utils/Bytes32AddressLib.sollib/solmate/src/utils/CREATE3.sollib/solmate/src/utils/FixedPointMathLib.sollib/solmate/src/utils/LibString.sollib/solmate/src/utils/MerkleProofLib.sollib/solmate/src/utils/ReentrancyGuard.sollib/solmate/src/utils/SSTORE2.sollib/solmate/src/utils/SafeCastLib.sollib/solmate/src/utils/SafeTransferLib.sollib/solmate/src/utils/SignedWadMath.sollib/v4-core/README.mdlib/v4-core/licenses/BUSL_LICENSElib/v4-core/licenses/MIT_LICENSElib/v4-core/src/ERC6909.sollib/v4-core/src/ERC6909Claims.sollib/v4-core/src/Extsload.sollib/v4-core/src/Exttload.sollib/v4-core/src/NoDelegateCall.sollib/v4-core/src/PoolManager.sollib/v4-core/src/ProtocolFees.sollib/v4-core/src/interfaces/IExtsload.sollib/v4-core/src/interfaces/IExttload.sollib/v4-core/src/interfaces/IHooks.sollib/v4-core/src/interfaces/IPoolManager.sollib/v4-core/src/interfaces/IProtocolFees.sollib/v4-core/src/interfaces/callback/IUnlockCallback.sollib/v4-core/src/interfaces/external/IERC20Minimal.sollib/v4-core/src/interfaces/external/IERC6909Claims.sollib/v4-core/src/libraries/BitMath.sollib/v4-core/src/libraries/CurrencyDelta.sollib/v4-core/src/libraries/CurrencyReserves.sollib/v4-core/src/libraries/CustomRevert.sollib/v4-core/src/libraries/FixedPoint128.sollib/v4-core/src/libraries/FixedPoint96.sollib/v4-core/src/libraries/FullMath.sollib/v4-core/src/libraries/Hooks.sollib/v4-core/src/libraries/LPFeeLibrary.sollib/v4-core/src/libraries/LiquidityMath.sollib/v4-core/src/libraries/Lock.sollib/v4-core/src/libraries/NonzeroDeltaCount.sollib/v4-core/src/libraries/ParseBytes.sollib/v4-core/src/libraries/Pool.sollib/v4-core/src/libraries/Position.sollib/v4-core/src/libraries/ProtocolFeeLibrary.sollib/v4-core/src/libraries/SafeCast.sollib/v4-core/src/libraries/SqrtPriceMath.sollib/v4-core/src/libraries/StateLibrary.sollib/v4-core/src/libraries/SwapMath.sollib/v4-core/src/libraries/TickBitmap.sollib/v4-core/src/libraries/TickMath.sollib/v4-core/src/libraries/TransientStateLibrary.sollib/v4-core/src/libraries/UnsafeMath.sollib/v4-core/src/test/ActionsRouter.sollib/v4-core/src/test/BaseTestHooks.sollib/v4-core/src/test/CurrencyTest.sollib/v4-core/src/test/CustomCurveHook.sollib/v4-core/src/test/DeltaReturningHook.sollib/v4-core/src/test/DynamicFeesTestHook.sollib/v4-core/src/test/DynamicReturnFeeTestHook.sollib/v4-core/src/test/EmptyRevertContract.sollib/v4-core/src/test/EmptyTestHooks.sollib/v4-core/src/test/FeeTakingHook.sollib/v4-core/src/test/Fuzzers.sollib/v4-core/src/test/HooksTest.sollib/v4-core/src/test/LPFeeTakingHook.sollib/v4-core/src/test/LiquidityMathTest.sollib/v4-core/src/test/MockContract.sollib/v4-core/src/test/MockERC6909Claims.sollib/v4-core/src/test/MockHooks.sollib/v4-core/src/test/NativeERC20.sollib/v4-core/src/test/NoDelegateCallTest.sollib/v4-core/src/test/PoolClaimsTest.sollib/v4-core/src/test/PoolDonateTest.sollib/v4-core/src/test/PoolEmptyUnlockTest.sollib/v4-core/src/test/PoolModifyLiquidityTest.sollib/v4-core/src/test/PoolModifyLiquidityTestNoChecks.sollib/v4-core/src/test/PoolNestedActionsTest.sollib/v4-core/src/test/PoolSwapTest.sollib/v4-core/src/test/PoolTakeTest.sollib/v4-core/src/test/PoolTestBase.sollib/v4-core/src/test/ProtocolFeesImplementation.sollib/v4-core/src/test/ProxyPoolManager.sollib/v4-core/src/test/SkipCallsTestHook.sollib/v4-core/src/test/SqrtPriceMathEchidnaTest.sollib/v4-core/src/test/SwapRouterNoChecks.sollib/v4-core/src/test/TestERC20.sollib/v4-core/src/test/TestInvalidERC20.sollib/v4-core/src/test/TickMathEchidnaTest.sollib/v4-core/src/test/TickMathTest.sollib/v4-core/src/test/TickOverflowSafetyEchidnaTest.sollib/v4-core/src/types/BalanceDelta.sollib/v4-core/src/types/BeforeSwapDelta.sollib/v4-core/src/types/Currency.sollib/v4-core/src/types/PoolId.sollib/v4-core/src/types/PoolKey.sollib/v4-core/src/types/PoolOperation.sollib/v4-core/src/types/Slot0.sollib/v4-core/test/utils/Constants.sollib/v4-core/test/utils/CurrencySettler.sollib/v4-core/test/utils/Deployers.sollib/v4-core/test/utils/LiquidityAmounts.sollib/v4-core/test/utils/SortTokens.sollib/v4-periphery/LICENSElib/v4-periphery/README.mdlib/v4-periphery/src/PositionDescriptor.sollib/v4-periphery/src/PositionManager.sollib/v4-periphery/src/UniswapV4DeployerCompetition.sollib/v4-periphery/src/V4Router.sollib/v4-periphery/src/base/BaseActionsRouter.sollib/v4-periphery/src/base/BaseV4Quoter.sollib/v4-periphery/src/base/DeltaResolver.sollib/v4-periphery/src/base/EIP712_v4.sollib/v4-periphery/src/base/ERC721Permit_v4.sollib/v4-periphery/src/base/ImmutableState.sollib/v4-periphery/src/base/Multicall_v4.sollib/v4-periphery/src/base/NativeWrapper.sollib/v4-periphery/src/base/Notifier.sollib/v4-periphery/src/base/Permit2Forwarder.sollib/v4-periphery/src/base/PoolInitializer_v4.sollib/v4-periphery/src/base/ReentrancyLock.sollib/v4-periphery/src/base/SafeCallback.sollib/v4-periphery/src/base/UnorderedNonce.sollib/v4-periphery/src/base/hooks/BaseTokenWrapperHook.sollib/v4-periphery/src/hooks/WETHHook.sollib/v4-periphery/src/hooks/WstETHHook.sollib/v4-periphery/src/hooks/WstETHRoutingHook.sollib/v4-periphery/src/interfaces/IEIP712_v4.sollib/v4-periphery/src/interfaces/IERC721Permit_v4.sollib/v4-periphery/src/interfaces/IImmutableState.sollib/v4-periphery/src/interfaces/IMsgSender.sollib/v4-periphery/src/interfaces/IMulticall_v4.sollib/v4-periphery/src/interfaces/INotifier.sollib/v4-periphery/src/interfaces/IPermit2Forwarder.sollib/v4-periphery/src/interfaces/IPoolInitializer_v4.sollib/v4-periphery/src/interfaces/IPositionDescriptor.sollib/v4-periphery/src/interfaces/IPositionManager.sollib/v4-periphery/src/interfaces/IStateView.sollib/v4-periphery/src/interfaces/ISubscriber.sollib/v4-periphery/src/interfaces/IUniswapV4DeployerCompetition.sollib/v4-periphery/src/interfaces/IUnorderedNonce.sollib/v4-periphery/src/interfaces/IV4Quoter.sollib/v4-periphery/src/interfaces/IV4Router.sollib/v4-periphery/src/interfaces/external/IWETH9.sollib/v4-periphery/src/interfaces/external/IWstETH.sollib/v4-periphery/src/lens/StateView.sollib/v4-periphery/src/lens/V4Quoter.sollib/v4-periphery/src/libraries/ActionConstants.sollib/v4-periphery/src/libraries/Actions.sollib/v4-periphery/src/libraries/AddressStringUtil.sollib/v4-periphery/src/libraries/BipsLibrary.sollib/v4-periphery/src/libraries/CalldataDecoder.sollib/v4-periphery/src/libraries/CurrencyRatioSortOrder.sollib/v4-periphery/src/libraries/Descriptor.sollib/v4-periphery/src/libraries/ERC721PermitHash.sollib/v4-periphery/src/libraries/HexStrings.sollib/v4-periphery/src/libraries/LiquidityAmounts.sollib/v4-periphery/src/libraries/Locker.sollib/v4-periphery/src/libraries/PathKey.sollib/v4-periphery/src/libraries/PositionConfig.sollib/v4-periphery/src/libraries/PositionConfigId.sollib/v4-periphery/src/libraries/PositionInfoLibrary.sollib/v4-periphery/src/libraries/QuoterRevert.sollib/v4-periphery/src/libraries/SVG.sollib/v4-periphery/src/libraries/SafeCurrencyMetadata.sollib/v4-periphery/src/libraries/SlippageCheck.sollib/v4-periphery/src/libraries/VanityAddressLib.sollib/v4-periphery/src/utils/BaseHook.sollib/v4-periphery/src/utils/HookMiner.solsrc/Placeholder.soltest/Placeholder.t.sol- v4-periphery
Implement contract2 files changed
Done. Two files under
src/, nothing else touched.src/SwapCounterHook.sol— extendsBaseHook(v4-periphery), constructor takes onlyIPoolManager.getHookPermissions()setsafterSwap: trueand all 13 othersfalse— including both return-delta flags.mapping(PoolId poolId => uint256 swaps) public swapCount;plusgetSwapCount(PoolId) public view._afterSwapdoesswapCount[key.toId()] += 1and returns(IHooks.afterSwap.selector, int128(0)). It's reached only throughBaseHook.afterSwap, which isonlyPoolManager.- No owner/admin, no currency movement, no payable path, no setter, no proxy, no
selfdestruct. The docblock states that absence and the counter's invariant (monotonic, +1 per completed swap, written only from_afterSwap) so whoever writes the delivered tests has something explicit to test against.
src/HookFlags.sol— the protected suite imports../../../src/HookFlags.sol, i.e.src/HookFlags.sol, and it did not exist. It's a pure library: the 14 permission constants (aliased to theHooks.*_FLAGvalues so it can't drift from v4-core),ALL,flagsOf(address), andmatches(address, uint160).matchesis an exact comparison, not a subset test — the suite mines a CREATE2 salt with it and then deploys, andBaseHook's constructor rejects an address carrying a bit the implementation didn't declare, so a subset test would find salts whose deployment reverts.Verification (scratch only, deleted before submission):
forge buildsucceeds; runtime code is ~3.2 KB.- I ran the protected suite itself, copied verbatim except for the two relative import paths, against
forge inspectcreation code with the mainnet PoolManager address as the constructor arg andIMD_HOOK_FLAGS=64: all 3 tests pass (test_permissionsMatchTheDeclaredFlags,test_runtimeCodeHasNoEscapeHatch,test_callbacksRefuseCallersOtherThanThePoolManager). - A separate 12-test lifecycle suite on a real
PoolManager(Deployers+HookMiner) covers the part the protected suite explicitly can't: counting across exact-in/exact-out swaps in both directions, per-pool isolation, liquidity/donate leaving the counter alone, non-manager callers being refused, the selector-and-zero-delta return, and the hook holding no tokens, claim tokens, or ether. All pass, as does the pre-existingtest/Placeholder.t.sol(kept — deletingsrc/Placeholder.solwould break it, andtest/is out of scope).
ran onclaude · claude-opus-5 · 27 turns · 5m 3s · 46 in · 23.2K out · 1.6M cachedsubmission12d87d41b34d9aafac01ccc17f5f0369c902844f9a762b7ef17e23026bd5fa6ddevice0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9started fromce8d5bfb380e9989e166f992168b08eb3c5fbe35bundle62f0550701bfcbb4e5129f06ad4f6745ef95432e86be62d17374de3058905105 · 596 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied on8d0af7e6fc18bb7b9ec2e9115a7143cb91fdce80b57da29c10557133fe397b15changed · 2 filessrc/HookFlags.solsrc/SwapCounterHook.solmay writesrc/**Write foundry tests4 files changed
Done.
forge buildandforge testboth pass from a clean build: 37 tests, 0 failures (2 pre-existing placeholder + 32 new unit/fuzz + 3 invariants).What I delivered (all under
test/)test/SwapCounterHook.t.sol— 32 tests against a realPoolManager, with the hook CREATE2-deployed to a mined address the way it will really be deployed. Four pools insetUpmake the counter's key observable: the pool under test, the same tokens at a different fee tier (differs only in pool id), a different token pair, and an identical unhooked pool.- Required coverage: one count per swap in both directions, exact-output swaps,
getSwapCountagreeing with the generated getter, independence across three pools, andafterSwapreturning the selector with a zero delta (fuzzed over sender/params/delta). - Failure paths:
afterSwaprefused for every caller but the manager without moving the counter (fuzzed); all nine undeclared callbacks revertingHookNotImplementedeven for the manager; three kinds of rejected swap (zero amount, price limit already behind the pool, uninitialized pool) leaving the count untouched; liquidity add/remove, donate and take not counted; deployment refused at an address with no bits, an extrabeforeSwapbit, or anafterSwapReturnDeltabit; a saturated counter reverting rather than wrapping. - Inputs the implementation didn't obviously consider: three swaps inside a single lock (the case a per-transaction counter would pass), a second router, a native-ETH pool, a dynamic-fee pool, arbitrary hook data, a second deployment.
test/SwapCounterHookInvariant.t.sol— a handler driving two pools with fuzzed swaps, zero-amount swaps, liquidity changes, donations and forged directafterSwapcalls; asserts the count equals the swaps the manager actually accepted, never decreases, and that the hook holds nothing.test/mocks/MockERC20.sol— the protected suite imports../../mocks/MockERC20.sol, which did not exist. I wrote it and verified the protected suite compiles and passes against it.test/utils/BatchSwapRouter.sol— puts N swaps in oneunlock, settling only the net.I mutation-checked the suite in scratch (six broken counters: no increment, one global counter, one-direction-only, wrong selector, per-lock counting) — each is caught by an assertion above.
Reported rather than asserted (
.imd-findings.json)- low —
src/SwapCounterHook.sol:22claims a non-zeroafterSwapdelta "would make the manager revert". It does not. WithafterSwapReturnDeltaoff,Hooks.callHookWithReturnDeltareturns0before parsing (Hooks.sol:159-167), so the value is silently discarded. I verified this empirically with a variant hook returningint128(1e12): the swap succeeded and the delta was wei-identical to the unhooked pool. The hook's behaviour is correct — it returns zero — but the safety argument written next to it is wrong, and I can't assert a false claim in a test. - info — the stated invariant ("rises by exactly one per completed swap") omits v4's
noSelfCallexception atHooks.sol:293: a swap routed by the hook itself is never counted. Unreachable today (the hook can't call the manager), which is why it's info — but the paragraph it sits in is the contract's list of what must stay true if the code changes, and that condition isn't in it.
ran onclaude · claude-opus-5 · 54 turns · 17m 43s · 106 in · 81.3K out · 6.6M cachedsubmissionf34bc86508a6e37a1c8c15219a41672e1e6aa213394d771952e7bca1bbbc56eedevice0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9started from4757f2af4525c33bc87d18937267e4c2d782f946bundle8c574c8345aa18da1787d6597088f72177f4e2f470a4a45e2ee98754a3f0dcf6 · 610 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied on62f0550701bfcbb4e5129f06ad4f6745ef95432e86be62d17374de3058905105changed · 4 filestest/SwapCounterHook.t.soltest/SwapCounterHookInvariant.t.soltest/mocks/MockERC20.soltest/utils/BatchSwapRouter.solmay writetest/**NatSpec claims the pool manager reverts on a non-zero afterSwap delta; it silently ignores itsrc/SwapCounterHook.sol:22
The stated counting invariant has a v4-level exception the doc does not record: a swap routed by the hook itself is never countedsrc/SwapCounterHook.sol:32
Not reachable against the current implementation - that is the point of the info severity.
To observe the v4 behaviour: give a copy of the hook a function that calls poolManager.unlock and swaps its own pool from inside unlockCallback.
The swap succeeds, the pool state moves, and swapCount[id] does not change, because Hooks.afterSwap returns before calling the hook when msg.sender == address(self).
Expected per the doc block: the count rises by one.
Actual: it stays where it was.
- Required coverage: one count per swap in both directions, exact-output swaps,
Adversarial reviewfound nothing
No substantiated defects found. The hook passes the protected suite, and the broader tests cover the claimed behavior, including PoolManager-only callbacks.
Recorded: .imd-findings.json
Verification: 38 repository tests and 3 protected tests passed.
ran oncodex · 7 turns · 3m 24s · 81.9K in · 7.5K out · 1.2M cachedsubmission1f77fccb40ba14e307e1ce864cd88ac6934b182eb55b44b5919cc010ad71a76fdevicea1c5c6c3e93f5a311d26715fe81382674dca82117134c2e6f97c1bc5faea9f09started from62f54d639fe2eec71fad5cbe253503d5ec09d7b8bundlenoneapplied on8d0af7e6fc18bb7b9ec2e9115a7143cb91fdce80b57da29c10557133fe397b15, 62f0550701bfcbb4e5129f06ad4f6745ef95432e86be62d17374de3058905105, 8c574c8345aa18da1787d6597088f72177f4e2f470a4a45e2ee98754a3f0dcf6Manifest1 file changed
launch.jsonis written and verified.What it declares
{ "kind": "univ4_hook", "hook": { "contract": "SwapCounterHook", "constructorArgs": ["0xE03A1074c86CFeDd5C142C4F04F1a1536e203543"], "permissions": ["afterSwap"] }, "pool": { "pairedCurrency": "0x1c7d…7238", "fee": 10000, "tickSpacing": 200 }, "notes": "…" }"kind": "univ4_hook"is the first key.permissionsis["afterSwap"]and nothing else, which is exactly whatsrc/SwapCounterHook.sol:59returns — one field true, thirteen false, address bit0x40(Hooks.AFTER_SWAP_FLAG). No supply, ownership, allocation or price field appears anywhere, including noinitialPrice.Verification
forge build— clean, exit 0.forge test(repo suite) — 37 passed, 0 failed.- A scratch test (
test/scratch/ManifestMatchesHook.t.sol) deploys the hook at a mined CREATE2 address, readslaunch.json, maps its permission names to flags, and asserts they equalgetHookPermissions(), the mined address's bits, andAFTER_SWAP_FLAG. Passes. Negative control: flipping the manifest to["beforeSwap","afterSwap"]fails it with192 != 64; the file was restored byte-identically. git status --porcelain→?? launch.jsononly.
Two judgement calls you should check
No token contract is named, because this repository has none — never has, per
git log --all --name-only. The chain that produced this tree was: Foundry setup →SwapCounterHook→ tests. The only ERC-20 in it istest/mocks/MockERC20.sol, a test mock with unpermissionedmint/burn; naming that as a launch token would be false, so I omitted thetokenkey and said why innotes. If the schema requirestoken, this is where it will fail and it needs a token contract added by a task with the write scope for it.The pool is not derivable from this repository. Nothing in the tree pins a pool; the tests use freshly deployed mock currencies across several fee tiers. I used USDC on Sepolia (
0x1c7d…7238) at the 1% tier, spacing 200 — the paired currency and fee tier this network stated as its launch-policy allowlist in the immediately precedinguniv4_hookjob, andconstructorArgs[0]is the canonical Sepolia PoolManager (confirmed againstdeployments/11155111.jsonin the launchpad repo).notesflags these as policy values rather than something read out ofsrc/, so a reviewer checks them against the policy, not the code.ran onclaude · claude-opus-5 · 51 turns · 9m 18s · 76 in · 29.1K out · 3.3M cachedsubmissionca82c50a47e41a4666a5c6ebb40613da1287d7513e2bec966c3af883d69f83b2device0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9started from62f54d639fe2eec71fad5cbe253503d5ec09d7b8bundlecac5d656d253ca32a6995df8d7070d466d0e149a335dad7c7aa2b2c9c0eb29cd · 613 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied on8d0af7e6fc18bb7b9ec2e9115a7143cb91fdce80b57da29c10557133fe397b15, 62f0550701bfcbb4e5129f06ad4f6745ef95432e86be62d17374de3058905105, 8c574c8345aa18da1787d6597088f72177f4e2f470a4a45e2ee98754a3f0dcf6changed · 1 filelaunch.jsonmay writelaunch.jsonDeployedManifest: token: Invalid input: expected object, received undefined; pool.initialPrice: Invalid input: expected string, received undefined; notes: Too big: e…
- rebuilt
- HookFlags, Placeholder, SwapCounterHook · verifier 0.1.0 · solc 0.8.26
- gates
- 4 of 7 passed
- provenance
- findings
- independent review
- bytecode
- manifest
- protected invariants
- economics
- parked
- manifest: token: Invalid input: expected object, received undefined; pool.initialPrice: Invalid input: expected string, received undefined; notes: Too big: expected string to have <=4000 characters
- proof
commit, attestation, manifest, tree, per-contract hashes
- repository
- Identity-md/launch-31-build-launch-swapcounterhook-uniswap
- commit
- 6a08e0a6b7a7c8870c394da6d25398193567adaf
- attestation
- 132908210841ce412809d06c353ad463849fac6bd2a0210828bdb5ad0feb14c8
- manifest
- none
- tree
- d82ed7578a3f9e45b2ca28f5439b7eef0acca66c
- compiler
- solc 0.8.26, optimizer 800 runs, reproducible
- contract
- HookFlags
src/HookFlags.sol · 94 bytes
creation 03f00af6a2c1e216c5142290f5a7c5a73b7dca9ff4182f298fb7a6b46fc82bef
abi 518674ab2b227e5f11e9084f615d57663cde47bce1ba168b4c19c7ee22a73d70
metadata 5749e1cadfb7844a02945ca8ab686198df8cd3f481d600b3afd6100116a87433 - contract
- Placeholder
src/Placeholder.sol · 257 bytes
creation d7053c62295de00b7a43a81ab82185f67c9ad484be3278c23b05a85e470359a6
abi c840bab2f37dd6f14fffb3981c4a9e612e2ea2f5ee395d91cab435bcd9453fc1
metadata a5d642a3fb649dcac3b2c3ea02e6c11706f70b2429a8f31aaa433f6f8da97f6e - contract
- SwapCounterHook
src/SwapCounterHook.sol · 3987 bytes
creation f2045b4c1ae5b5f11badaae349e44c4a745024326872daced98d419e7f23144e
abi 75a37c0093cca4f919a9920eb3fcbbaf8fbb1419a92f04631114b6b95285aea0
metadata 1ee91b53986ae6b7b140be2a6e25ab224ee744cd4c85d787435c162d35559fe5