Agent #2reviewedAgent #3reviewedAgent #355reviewedAgent #1979reviewedAgent #579builtAgent #946integratedAgent #19testednode audit_judge exhausted its attempts
The whole request
Build a token called Prism Riot (PRIO) and a Uniswap v4 hook charging 0.5% extra on swaps to a treasury; deploy; build and publish a website to swap and view the treasury.
Launch kind: univ4_hook. TreasuryFeeHook charges an immutable extra 0.5% on the ETH leg, excluding fees, of buys AND sells in its ETH/PRIO pool. Transfer the whole extra fee directly into FeeTreasury. Keep platform fees separate. Test exact-input/output swaps, rounding and factory/router compatibility. No tax on ordinary transfers; other pools are outside this hook. Display every fee in quotes. Reject incompatible deployment instead of dropping the fee.
The website design uses neon pink, cyan, yellow and violet, with original dragon, frog, wolf and raven illustrations.
The project title on the website is PRISM RIOT.
Add an Arena contract with commitMove(bytes32), revealMove(uint256,bytes32), finalizeRound() and claimReward(). Each entry escrows 100 PRIO plus a 2 PRIO fee. Wrong moves lose 10 PRIO, missed reveals 20. Hold escrow until finalization. The website provides these contract actions, a leaderboard and refund controls.
Add an OracleAdapter contract accepting signed IMD EIP-712 panel attestations, verifying signer, consumer domain, question, expiry, quorum and replay. Store the attested numeric result on-chain. The website reads that result and source references from the contract, with a manual submit-attestation form. A separate operator requests the IMD panel result; the website does not call paid APIs.
Add stake(), withdraw(), claim() for PRIO staking. Distribute already funded rewards by stake amount/time. Principal remains withdrawable, separate from game escrow and agent budgets. No fixed APY, minting or unfunded accrual.
Reserve gas/operating costs from earned ETH fees, then allocate remaining ETH 30% to purchasing IMD for agent work, 30% to buying PRIO rewards, 40% to owner. Split reward PRIO equally between staking and games. Bound spending/slippage. No owner operating top-ups; insufficient revenue disables paid work.
Provide a budget-limited operator script using IMD oracle.request and job.open to propose challenge content and artwork. Include payment, polling and setup instructions, server-side keys and spending caps. Paid work starts only after configuration and fee funding; outputs cannot alter active rules or spend player deposits.
The paying wallet is owner. Only owner configures future rounds and operator budgets; active rules, reserved payouts and the 0.5% fee cannot change. Use Vault Raid, faction duels and cooperative boss game modes with fixed published scoring and prizes. Wallets can stake, withdraw and claim as well as play. Oracle timeouts cancel rounds and refund entry fees and escrow. Back up reveal secrets. Separate principal, escrow, refunds and rewards; use bounded settlement and duplicate-claim/reentrancy protection. Show game lobby, staking, treasury and agent activity from real contract data; label demos. No guaranteed profit. Deliver GitHub source, ABIs and Foundry tests.
Also approved
The requester chose this release: source code published to GitHub, website hosted on IPFS, contracts deployed on chain.
Work
Build contract projectAgent #579516 files changed
Implemented PRIO, six application contracts, ABI exports, vendored dependencies, operator tooling, and documentation.
Verified:
forge build, 39 Foundry tests,forge fmt --check, and four operator tests—all pass.Deployment requirements and remaining release gates are documented in README.md, including hook-capable factory support and
job.openavailability. No transactions were broadcast.ran oncodex · gpt-6-astra · 9 turns · 33m 47s · 132.6K in · 57.1K out · 2.7M cachedsubmission4f4926e117122bc3992c460f771c141cf94e5b8767c8b4fe8cd8735c7a70d1afdevicef5dec78d5893d9dc71819bfb5d9668cc6eaca4d79a129bfc1411622281c11397started from0243d7da4a4337ae8b16bcdf15bb4ead736fd68fbundlef4182335c90f6169613d106ec5a0bd58f02cabfb57a78785c757d6b6ca6aa3b4 · 644 KBverifiedrebuilt and matched · verifier 0.1.0 ·changed · 516 files.gitignoreLICENSEREADME.mddocs/ABI.mddocs/DEPENDENCIES.mddocs/OPERATOR.mddocs/REVIEW.mddocs/VALIDATION.mddocs/abi/Arena.jsondocs/abi/FeeTreasury.jsondocs/abi/LaunchToken.jsondocs/abi/OracleAdapter.jsondocs/abi/PrioStaking.jsondocs/abi/RevenueBuyer.jsondocs/abi/TreasuryFeeHook.jsonfoundry.tomllib/forge-std/LICENSE-APACHElib/forge-std/LICENSE-MITlib/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/StdConstants.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/IERC6909.sollib/forge-std/src/interfaces/IERC721.sollib/forge-std/src/interfaces/IERC7540.sollib/forge-std/src/interfaces/IERC7575.sollib/forge-std/src/interfaces/IMulticall3.sollib/forge-std/src/safeconsole.sollib/openzeppelin-contracts/LICENSElib/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/account/Account.sollib/openzeppelin-contracts/contracts/account/README.adoclib/openzeppelin-contracts/contracts/account/extensions/draft-AccountERC7579.sollib/openzeppelin-contracts/contracts/account/extensions/draft-AccountERC7579Hooked.sollib/openzeppelin-contracts/contracts/account/extensions/draft-ERC7821.sollib/openzeppelin-contracts/contracts/account/utils/EIP7702Utils.sollib/openzeppelin-contracts/contracts/account/utils/draft-ERC4337Utils.sollib/openzeppelin-contracts/contracts/account/utils/draft-ERC7579Utils.sollib/openzeppelin-contracts/contracts/crosschain/ERC7786Recipient.sollib/openzeppelin-contracts/contracts/crosschain/README.adoclib/openzeppelin-contracts/contracts/finance/README.adoclib/openzeppelin-contracts/contracts/finance/VestingWallet.sollib/openzeppelin-contracts/contracts/finance/VestingWalletCliff.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/GovernorCountingFractional.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingOverridable.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorCountingSimple.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorNoncesKeyed.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorPreventLateQuorum.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorProposalGuardian.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorSequentialProposalId.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorSettings.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorStorage.sollib/openzeppelin-contracts/contracts/governance/extensions/GovernorSuperQuorum.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/extensions/GovernorVotesSuperQuorumFraction.sollib/openzeppelin-contracts/contracts/governance/utils/IVotes.sollib/openzeppelin-contracts/contracts/governance/utils/Votes.sollib/openzeppelin-contracts/contracts/governance/utils/VotesExtended.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/IERC6909.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/IERC7751.sollib/openzeppelin-contracts/contracts/interfaces/IERC777.sollib/openzeppelin-contracts/contracts/interfaces/IERC777Recipient.sollib/openzeppelin-contracts/contracts/interfaces/IERC777Sender.sollib/openzeppelin-contracts/contracts/interfaces/IERC7913.sollib/openzeppelin-contracts/contracts/interfaces/README.adoclib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sollib/openzeppelin-contracts/contracts/interfaces/draft-IERC4337.sollib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sollib/openzeppelin-contracts/contracts/interfaces/draft-IERC7579.sollib/openzeppelin-contracts/contracts/interfaces/draft-IERC7674.sollib/openzeppelin-contracts/contracts/interfaces/draft-IERC7786.sollib/openzeppelin-contracts/contracts/interfaces/draft-IERC7802.sollib/openzeppelin-contracts/contracts/interfaces/draft-IERC7821.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/AccessManagerMock.sollib/openzeppelin-contracts/contracts/mocks/ArraysMock.sollib/openzeppelin-contracts/contracts/mocks/AuthorityMock.sollib/openzeppelin-contracts/contracts/mocks/Base64Dirty.sollib/openzeppelin-contracts/contracts/mocks/BatchCaller.sollib/openzeppelin-contracts/contracts/mocks/CallReceiverMock.sollib/openzeppelin-contracts/contracts/mocks/ConstructorMock.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/ERC165Mock.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/MerkleProofCustomHashMock.sollib/openzeppelin-contracts/contracts/mocks/MerkleTreeMock.sollib/openzeppelin-contracts/contracts/mocks/MulticallHelper.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/ReentrancyTransientMock.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/TransientSlotMock.sollib/openzeppelin-contracts/contracts/mocks/UpgradeableBeaconMock.sollib/openzeppelin-contracts/contracts/mocks/VotesExtendedMock.sollib/openzeppelin-contracts/contracts/mocks/VotesMock.sollib/openzeppelin-contracts/contracts/mocks/account/AccountMock.sollib/openzeppelin-contracts/contracts/mocks/account/modules/ERC7579Mock.sollib/openzeppelin-contracts/contracts/mocks/account/utils/ERC7579UtilsMock.sollib/openzeppelin-contracts/contracts/mocks/compound/CompTimelock.sollib/openzeppelin-contracts/contracts/mocks/crosschain/ERC7786GatewayMock.sollib/openzeppelin-contracts/contracts/mocks/crosschain/ERC7786RecipientMock.sollib/openzeppelin-contracts/contracts/mocks/docs/ERC20WithAutoMinerReward.sollib/openzeppelin-contracts/contracts/mocks/docs/ERC4626Fees.sollib/openzeppelin-contracts/contracts/mocks/docs/MyNFT.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/AccessControlModified.sollib/openzeppelin-contracts/contracts/mocks/docs/access-control/AccessManagedERC20MintBase.sollib/openzeppelin-contracts/contracts/mocks/docs/access-control/MyContractOwnable.sollib/openzeppelin-contracts/contracts/mocks/docs/account/MyAccountERC7702.sollib/openzeppelin-contracts/contracts/mocks/docs/account/MyFactoryAccount.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/docs/token/ERC1155/GameItems.sollib/openzeppelin-contracts/contracts/mocks/docs/token/ERC1155/MyERC115HolderContract.sollib/openzeppelin-contracts/contracts/mocks/docs/token/ERC20/GLDToken.sollib/openzeppelin-contracts/contracts/mocks/docs/token/ERC6909/ERC6909GameItems.sollib/openzeppelin-contracts/contracts/mocks/docs/token/ERC721/GameItem.sollib/openzeppelin-contracts/contracts/mocks/docs/utilities/Base64NFT.sollib/openzeppelin-contracts/contracts/mocks/docs/utilities/Multicall.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorCountingOverridableMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorFractionalMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorNoncesKeyedMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorPreventLateQuorumMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorProposalGuardianMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorSequentialProposalIdMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorStorageMock.sollib/openzeppelin-contracts/contracts/mocks/governance/GovernorSuperQuorumMock.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/GovernorVotesSuperQuorumFractionMock.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/ERC1363ForceApproveMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC1363NoReturnMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReceiverMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC1363ReturnFalseMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC1363SpenderMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20ApprovalMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20BridgeableMock.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/ERC20GetterHelper.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/ERC20VotesAdditionalCheckpointsMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesLegacyMock.sollib/openzeppelin-contracts/contracts/mocks/token/ERC20VotesTimestampMock.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/utils/cryptography/ERC7739Mock.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/ERC1155/utils/ERC1155Utils.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/ERC1363.sollib/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/extensions/draft-ERC20Bridgeable.sollib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-ERC20TemporaryApproval.sollib/openzeppelin-contracts/contracts/token/ERC20/utils/ERC1363Utils.sollib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sollib/openzeppelin-contracts/contracts/token/ERC6909/ERC6909.sollib/openzeppelin-contracts/contracts/token/ERC6909/README.adoclib/openzeppelin-contracts/contracts/token/ERC6909/extensions/ERC6909ContentURI.sollib/openzeppelin-contracts/contracts/token/ERC6909/extensions/ERC6909Metadata.sollib/openzeppelin-contracts/contracts/token/ERC6909/extensions/ERC6909TokenSupply.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/ERC721/utils/ERC721Utils.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/Base58.sollib/openzeppelin-contracts/contracts/utils/Base64.sollib/openzeppelin-contracts/contracts/utils/Blockhash.sollib/openzeppelin-contracts/contracts/utils/Bytes.sollib/openzeppelin-contracts/contracts/utils/CAIP10.sollib/openzeppelin-contracts/contracts/utils/CAIP2.sollib/openzeppelin-contracts/contracts/utils/Calldata.sollib/openzeppelin-contracts/contracts/utils/Comparators.sollib/openzeppelin-contracts/contracts/utils/Context.sollib/openzeppelin-contracts/contracts/utils/Create2.sollib/openzeppelin-contracts/contracts/utils/Errors.sollib/openzeppelin-contracts/contracts/utils/LowLevelCall.sollib/openzeppelin-contracts/contracts/utils/Memory.sollib/openzeppelin-contracts/contracts/utils/Multicall.sollib/openzeppelin-contracts/contracts/utils/Nonces.sollib/openzeppelin-contracts/contracts/utils/NoncesKeyed.sollib/openzeppelin-contracts/contracts/utils/Packing.sollib/openzeppelin-contracts/contracts/utils/Panic.sollib/openzeppelin-contracts/contracts/utils/Pausable.sollib/openzeppelin-contracts/contracts/utils/README.adoclib/openzeppelin-contracts/contracts/utils/RLP.sollib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sollib/openzeppelin-contracts/contracts/utils/ReentrancyGuardTransient.sollib/openzeppelin-contracts/contracts/utils/RelayedCall.sollib/openzeppelin-contracts/contracts/utils/ShortStrings.sollib/openzeppelin-contracts/contracts/utils/SlotDerivation.sollib/openzeppelin-contracts/contracts/utils/StorageSlot.sollib/openzeppelin-contracts/contracts/utils/Strings.sollib/openzeppelin-contracts/contracts/utils/TransientSlot.sollib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sollib/openzeppelin-contracts/contracts/utils/cryptography/EIP712.sollib/openzeppelin-contracts/contracts/utils/cryptography/Hashes.sollib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sollib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sollib/openzeppelin-contracts/contracts/utils/cryptography/P256.sollib/openzeppelin-contracts/contracts/utils/cryptography/README.adoclib/openzeppelin-contracts/contracts/utils/cryptography/RSA.sollib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sollib/openzeppelin-contracts/contracts/utils/cryptography/WebAuthn.sollib/openzeppelin-contracts/contracts/utils/cryptography/draft-ERC7739Utils.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/AbstractSigner.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/MultiSignerERC7913.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/SignerECDSA.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/SignerEIP7702.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/SignerERC7913.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/SignerP256.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/SignerRSA.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/SignerWebAuthn.sollib/openzeppelin-contracts/contracts/utils/cryptography/signers/draft-ERC7739.sollib/openzeppelin-contracts/contracts/utils/cryptography/verifiers/ERC7913P256Verifier.sollib/openzeppelin-contracts/contracts/utils/cryptography/verifiers/ERC7913RSAVerifier.sollib/openzeppelin-contracts/contracts/utils/cryptography/verifiers/ERC7913WebAuthnVerifier.sollib/openzeppelin-contracts/contracts/utils/draft-InteroperableAddress.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/Accumulators.sollib/openzeppelin-contracts/contracts/utils/structs/BitMaps.sollib/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sollib/openzeppelin-contracts/contracts/utils/structs/CircularBuffer.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/structs/Heap.sollib/openzeppelin-contracts/contracts/utils/structs/MerkleTree.sollib/openzeppelin-contracts/contracts/utils/types/Time.sollib/openzeppelin-contracts/contracts/vendor/compound/ICompoundTimelock.sollib/openzeppelin-contracts/contracts/vendor/compound/LICENSElib/solmate/LICENSElib/solmate/src/auth/Owned.sollib/solmate/src/tokens/ERC20.sollib/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/Slot0.sollib/v4-core/test/utils/AmountHelpers.sollib/v4-core/test/utils/Constants.sollib/v4-core/test/utils/CurrencySettler.sollib/v4-core/test/utils/Deployers.sollib/v4-core/test/utils/JavascriptFfi.sollib/v4-core/test/utils/LiquidityAmounts.sollib/v4-core/test/utils/Logger.sollib/v4-core/test/utils/NestedActions.t.sollib/v4-core/test/utils/SortTokens.sollib/v4-core/test/utils/SwapHelper.t.sollib/v4-core/test/utils/V3Helper.solremappings.txtscript/MineHook.s.solscript/export_abis.pyscript/run_operator.pysrc/Arena.solsrc/FeeTreasury.solsrc/LaunchToken.solsrc/OracleAdapter.solsrc/OracleAttestation.solsrc/PrioStaking.solsrc/RevenueBuyer.solsrc/TreasuryFeeHook.solsrc/libraries/SwapPreview.soltest/Arena.t.soltest/Deployment.t.soltest/Hook.t.soltest/Invariants.t.soltest/Oracle.t.soltest/OracleConsumerConformance.t.soltest/TokenStaking.t.soltest/Treasury.t.soltest/helpers/System.soltest/operator/test_operator.pyManifestAgent #9461 file changed
Created launch.json with PRIO and six application contracts in dependency order.
Schema and ABI checks passed.
forge buildpassed with existing lint warnings; all 39 tests passed.Only
launch.jsonchanged. Its notes preserve the unresolved hook/factory compatibility finding.ran oncodex · gpt-6-astra · 5 turns · 6m 21s · 95.3K in · 9.3K out · 1M cachedsubmissione0807c103e81a2441ed779206d631878fdbac5793b48edaa569b20410e675de8device269d07167a05c2058ee08777dab51e85a0ca01bad82bf8d5e4974754a3cd4b1cstarted from02a8edede8d0221eee430e733986caf4cd8a3778bundle69a5daa5087fbe5739330c1eba3489c5a0a01d4b9235fccb95da9f8fa1011b8e · 645 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied onf4182335c90f6169613d106ec5a0bd58f02cabfb57a78785c757d6b6ca6aa3b4changed · 1 filelaunch.jsonmay writelaunch.jsonAudit flowAgent #3found 1 medium, 2 low, 1 info
The review is complete.
.imd-findings.jsonat the repository root holds four findings and a coverage row for all 51 listed entry points. No source, test, config or doc file was changed; the one scratch test I used was deleted after it confirmed a finding.What I covered. The Execution Trace, Periphery and First Principles guides, applied to all seven contracts and the SwapPreview library. I rebuilt the project and ran the existing suite (39 tests pass), compared the hook's delta sign conventions line by line against the pinned v4-core Hooks and Pool libraries, and confirmed every file in docs/abi is byte-identical to the compiled ABI. Arena, PrioStaking, RevenueBuyer and the hook's swap-fee math held under every failure mode in my guides. The Arena oracle timing is sound: an answer cannot land before revealEnd or after the shared deadline, so the cancel and settle paths are mutually exclusive.
Findings, most severe first.
- Medium, TreasuryFeeHook.sol:67. The hook needs a salt-mined address with permission bits 0x20cc, an owner-only configure call before pool initialization, and a pool key naming it as the hook. A one-transaction generic factory that initializes with PoolInitializationGuard satisfies none of these, so the launch either reverts or opens an unhooked pool. The author already flags this in docs/REVIEW.md. It is the fact that decides whether this launch can deploy, and the manifest reviewer needs the univ4_hook factory's actual lifecycle as evidence.
- Low, OracleAdapter.sol:89. The adapter rejects any attestation whose issuedAt is ahead of block.timestamp, though the protocol base contract allows five minutes of clock drift. Verified with a scratch test: one second ahead reverts, the same signed attestation is accepted a second later. On the paid callback path there is no retry, so the 0.5 IMD is spent and the question stays pending until someone resubmits manually.
- Low, FeeTreasury.sol:191. Buying PRIO rewards requires the IMD and Intake services to be configured although it uses neither. On a chain without an Intake contract, the owner cannot call setServices honestly, and the 30% reward bucket is unreachable.
- Info, SwapPreview.sol:63. The 128-step quote cap means a swap crossing more than 128 initialized ticks reverts. Dust positions can raise that count, but it only bounds swap size, not the pool, and the author documents it.
Static-analysis leads. The reentrancy-balance lead on buyTokens is the hook paying a fee back to the treasury during its own purchase. I traced it and the balance-versus-accounted invariant holds, so I did not report it. The strict-equality and divide-before-multiply leads in PrioStaking are benign by construction.
Not reached. No live factory, router or chain fork was available, so the deployment finding rests on the task's description of the factory and the author's own notes rather than an executed launch.
ran onclaude · claude-fable-5-1 · 31 turns · 12m 49s · 354 in · 51K out · 1.3M cachedsubmissione91d4c5ba41762aa6c2943502bf05a03f7fdf80a1b6566cdcba1fc8fe4af7199device077d2937780a81bc63aca73b54616f949b3566a81a7a59abda7b8245765661d9started from02a8edede8d0221eee430e733986caf4cd8a3778bundlenoneapplied onf4182335c90f6169613d106ec5a0bd58f02cabfb57a78785c757d6b6ca6aa3b4mediumLaunch lifecycle: TreasuryFeeHook cannot be deployed and the hooked pool cannot be initialized by a one-transaction generic factory flowsrc/TreasuryFeeHook.sol:67
OracleAdapter rejects attestations whose issuedAt is ahead of block.timestamp, stricter than the protocol's 5-minute tolerance; a paid callback hit by honest clock drift is lostsrc/OracleAdapter.sol:89
FeeTreasury.buyTokens for PRIO rewards is gated on IMD/Intake configuration it does not use; on a chain without a live Intake the 30% reward bucket is unreachable without a bogus intake addresssrc/FeeTreasury.sol:191
imdcan only be set through setServices, which requires all of buyer_, imd_ and intake_ to have code (line 117). The reward purchase (agents=false) needs onlybuyerandtoken, yet line 191 also requiresimd. On a launch chain where no Intake contract exists (the supplied oracle-consumer reference lists Base and Sepolia as having none), the owner cannot call setServices honestly, so rewardETH accrues forever and staking/Arena never receive purchased PRIO.The only workaround is passing an unrelated contract as intake_, after which requestWork calls priceOf on it.
Fix: in buyTokens require
imdonly whenagentsis true, or let setServices accept a zero intake_ and have requestWork check it.State: fresh deployment, owner set budgets and rates, revenue allocated so rewardETH > 0, chain has no Intake.
Call setServices(buyer, imdToken, anyEOA) -> InvalidSetting (intake_.code.length == 0).
Call buyTokens(false, amount, minOut, deadline) -> NotConfigured (address(imd) == 0).
Expected: reward purchases depend only on the buyer route.
Actual: blocked until a contract address is supplied as intake.
SwapPreview caps a swap at 128 steps; a swap crossing more than 128 initialized ticks reverts the whole swap (per-swap size cap, griefable with dust positions)src/libraries/SwapPreview.sol:63
Each loop iteration is one computeSwapStep, i.e. one initialized tick or word boundary. Anyone can mint dust positions at many distinct ticks (tickSpacing 60) around the spot price; a swap whose quoted path would cross more than 128 of them reverts in beforeSwap, so the swap cannot execute at all through this pool. It is not a permanent lock: a smaller swap crosses fewer ticks, moves the price, and the next swap continues.
It is documented in docs/REVIEW.md as an accepted limit, so this is recorded for the judge, not as a defect to fix.
State: hooked pool at tick 0 with a full-range position plus 129 positions of minimal liquidity each spanning [60k, 60(k+1)] for k=1..129 (all on the sell side).
Input: exact-input buy large enough that the fixed-point quote would push the price past tick 60*130.
Actual: TreasuryFeeHook.beforeSwap -> quote -> SwapPreview.quote reverts UnsupportedSwap, PoolManager.swap reverts.
Expected by a router: a filled swap (or a partial fill).
Splitting into two swaps succeeds.
Audit mathAgent #355found 1 medium, 2 low
The review is complete. The findings file is written, every snippet matches its source line, the scratch directory is removed, and the working tree is otherwise untouched (only the untracked
.imd-findings.jsonremains, which git ignores).Outcome. The math in this project is sound. I traced the hook's 0.5% fee in all four swap modes, the Synthetix-style staking accumulator, the treasury's reserve-then-30/30/40 split and PRIO halving, the arena's 102-PRIO escrow settlement, and the oracle adapter's windows against the Math Precision, Boundary and Numerical Gap checklists. No loss-of-funds or wrong-recipient defect exists. The three findings in
.imd-findings.jsonare:- Medium, deployment path.
TreasuryFeeHook.beforeInitializerevertsNotConfigureduntil the owner has calledconfigure, so a factory that deploys and initializes the pool in one transaction cannot launch this hook. The code fails closed as the brief asks, but no accepted launch path currently satisfies it. The builder already flags this in the README and review handoff. - Low, fee rounding. The exact-input ETH buy path iterates to an integer fee fixed point and reverts
FeeRoundingConflictwhen none exists. Measured on the test pool, 14 of 3,000 consecutive amounts starting at 1 ETH revert, including 1000000000000000176 wei, while the 1-wei neighbour succeeds. The quote reverts too, so the website cannot display a fee for those amounts. Accepting the larger of the two oscillating values would fix it within 1 wei. - Low, timestamp boundary.
OracleAdapter._submitrejects an attestation whoseissuedAtis one second ahead of the block timestamp, stricter than the protocol's five-minute tolerance. On the paid callback path that single delivery attempt is lost and must be re-submitted manually later. Verified: the same signed attestation is accepted one second later.
Coverage. All 52 listed entry points have a row, plus four invariant rows. Three are marked
finding, the restholds. I also confirmed that every exported ABI indocs/abiis identical to the compiled artifact, and the full existing suite of 39 tests passes. Static-analysis leads I checked and dismissed with evidence: the reentrancy onbuyTokensis the hook'srecordFeere-entering during the purchase, and the accounting stays consistent; the divide-before-multiply instartRewardsis deliberate, with the remainder kept queued.ran onclaude · claude-fable-5-1 · 37 turns · 14m 20s · 610 in · 57.5K out · 2M cachedsubmission865564bb83a6c9600dd35e0200bd021919fa6f2a27667c05c310f20ee59855afdevice61b40507100263702b1d5f5439a8f6e8262c575173890bc72ccafb1eb3092ee9started from02a8edede8d0221eee430e733986caf4cd8a3778bundlenoneapplied onf4182335c90f6169613d106ec5a0bd58f02cabfb57a78785c757d6b6ca6aa3b4mediumHook refuses pool initialization until owner has called configure(); a factory that deploys and initializes the pool in one transaction cannot launch this hooksrc/TreasuryFeeHook.sol:67
About 0.5% of exact-input ETH buy amounts have no integer fee fixed point and revert with FeeRoundingConflict; the swap and the website quote both fail for that amountsrc/TreasuryFeeHook.sol:114
OracleAdapter rejects any attestation whose issuedAt is ahead of block.timestamp by even one second, stricter than the protocol's five-minute tolerance, so a paid callback can be lost to clock skewsrc/OracleAdapter.sol:89
- Medium, deployment path.
Audit permissionsAgent #1979found 1 medium, 2 low, 2 info
The review is complete. The findings file is at the repository root, and the harness's own exclude list hides it and the scratch tests from git, so no tracked file changed.
Outcome. The permission model is sound: every privileged write is owner-gated, every callback checks its caller, all constructors take
$ownerrather thanmsg.sender, and no admin path reaches player escrow, staking principal or reserved prizes. The ABI exports match the compiled artifacts for all seven contracts. The one blocking item is a launch-path conflict, not a permission bypass.Findings written to
.imd-findings.json(five, each with a confirmed reproduction undertest/scratch/):- Medium, launch-path conflict. The hook can only be activated after an owner-only
configurecall and only by the configured initializer. Under the supplied one-transaction ProjectFactory flow that call cannot happen before the factory initializes the pool, so a factory initialize reverts, an unmined CREATE2 salt aborts the launch at the hook constructor, and a guard-hooked pool charges no 0.5% fee at all. The scratch test shows all three outcomes. The manifest step cannot be accepted until a hook-capable path or a constructor-configured hook exists. - Low, trust gap. The treasury pays for an oracle callback request without checking that the adapter's delivery address is the Intake. With delivery unset, the paid callback reverts, is never retried, the IMD is spent, and delivery cannot be fixed while the question is pending.
- Low, asymmetry. The adapter rejects attestations whose issue time is one second ahead of the block, while the inherited base allows five minutes of clock drift. A drifted paid callback is dropped.
- Info, trust assumption. The owner can route all new revenue to the operator wallet through an unbounded reserve target, bypassing the 30/30/40 split. The README's claim that ownership transfer cannot redirect the paying wallet's share holds only for ETH already allocated.
- Info. All five privileged contracts use single-step ownership with renounce enabled, so one wrong call permanently disables rounds, questions and configuration.
Coverage. All 52 listed entry points have a row, plus three invariant rows and one honest
unreachedrow for things I could not exercise locally: the live factory lifecycle, the chain's actual LaunchFees fee, and callback gas when the signer is an ERC-1271 registry.Leads checked and dropped. The Slither reentrancy lead on
buyTokensis benign by construction: the only reentrant write is the hook crediting fresh unallocated revenue. PermissionlessstartRewardscan delay later funding by at most one period and cannot exclude it. The v4 self-sender hook skip is unreachable because the hook never swaps.ran onclaude · claude-fable-5-1 · 48 turns · 21m 4s · 578 in · 77.8K out · 2.9M cachedsubmissiond97d9e627c065eaeb4a4eae1215ef573b3d41f0e1aae54a3089c8671eb9d93a1device0476c44a80aa9574a3121027b06e9d96aa0536075373ba287ec42f00e433320estarted from02a8edede8d0221eee430e733986caf4cd8a3778bundlenoneapplied onf4182335c90f6169613d106ec5a0bd58f02cabfb57a78785c757d6b6ca6aa3b4mediumTreasuryFeeHook cannot be activated by the supplied one-transaction ProjectFactory launch path: owner-only configure() must precede pool initialization, so the factory's own initialize reverts NotConfsrc/TreasuryFeeHook.sol:67
FeeTreasury.requestWork pays for an oracle callback without checking that OracleAdapter.delivery is set to the Intake; the callback is rejected (NotConfigured/WrongDelivery) and the IMD is spent with src/FeeTreasury.sol:242
OracleAdapter rejects any attestation whose issuedAt is ahead of block.timestamp by even one second, stricter than the protocol base's 5-minute tolerance; a drifted paid callback is dropped and not resrc/OracleAdapter.sol:89
Trust assumption: the owner can direct 100% of newly earned ETH to the operator wallet through reserveTarget/dailyETH, bypassing the 30/30/40 split; README's 'ownership transfer cannot redirect the pasrc/FeeTreasury.sol:158
All five privileged contracts use single-step Ownable with renounceOwnership enabled; a mistyped transferOwnership or a renounce permanently disables round creation, question opening and treasury/hooksrc/Arena.sol:10
State: any deployment.
Owner calls Arena.transferOwnership(0x000...0001) (a typo address with no key) or Arena.renounceOwnership().
Then Arena.createRound(...) from the former owner reverts OwnableUnauthorizedAccount and no address can ever call it; same for OracleAdapter.openQuestion, TreasuryFeeHook.configure and FeeTreasury.setBudgets/bindHook.
Expected: a privileged-role transfer requires acceptance by the new owner; actual: one wrong call is irreversible.
- Medium, launch-path conflict. The hook can only be activated after an owner-only
Write foundry testsAgent #196 files changed
Added failure-path tests and Arena/treasury invariants; strengthened staking invariants. All changes are under
test/.forge buildpassed.- Offline
forge test: 68 passed, 0 failed, 0 skipped. - Invariants exercised 65,536 randomized calls.
No confirmed implementation defects found. Live-chain integration remains unverified.
ran oncodex · gpt-6-astra · 7 turns · 20m 47s · 148.5K in · 30K out · 2.8M cachedsubmission328663f0b158db155e1a95afab4841e64edb027b9e746f2e850fb903c8f92576device2d9304cc28cc499d0490af6f35b359d89648bc4f791281af03f0975f1a5f56e0started from02a8edede8d0221eee430e733986caf4cd8a3778bundleed84c21bd15a88f2e6e5e7a0c96d28c8ea36bcba4348db51f16deb141abd4889 · 659 KBverifiedrebuilt and matched · verifier 0.1.0 ·applied onf4182335c90f6169613d106ec5a0bd58f02cabfb57a78785c757d6b6ca6aa3b4changed · 6 filestest/ArenaProperties.t.soltest/CONTRIBUTOR_TESTS.mdtest/FailureBoundaries.t.soltest/Invariants.t.soltest/RevenueProperties.t.soltest/TreasuryPaymentFailures.t.solmay writetesttest/**Audit economicsAgent #2found 1 low, 3 info
The review is complete.
.imd-findings.jsonis written at the repository root with 4 findings and 57 coverage rows, all four snippets verified against the tree, the scratch probes deleted, and the untouched suite still passing (39 tests).Outcome. The economics of this project are sound. I found no critical, high or medium defect in the Economic Security, Invariant or Flow Gap areas. The four recorded items are one low-severity liveness defect and three informational notes.
What I verified in depth
- Arena conservation. I fuzzed 400 seeds of four consecutive rounds across all three modes with partial reveals, ties, boss-threshold misses and oracle-timeout cancels. The token balance always equalled free rewards plus reserved prizes plus escrow liability, and after all claims both escrow and reserved balances were exactly zero. Fees and penalties flow to future prizes as the brief requires.
- Treasury ETH accounting. Every writer of the five buckets keeps
accountedETHequal to their sum, including the self-fee re-entry when the treasury buys PRIO through its own hooked pool. - Staking backing. The stateful invariant suite holds. Empty-stake time is recycled, dust stays in reserve, principal is never a reward source.
- Hook fee. All four swap directions charge floor(nativeBase/200) and deliver the whole fee to the treasury. I checked the exact-output gross-up algebra by hand.
- Static-analysis leads. The reentrancy-balance, divide-before-multiply, locks-ether and unused-return lines all trace to safe or intended behaviour. None reproduced as a defect.
- Killed lead. The paid oracle callback fits the 200k stipend with headroom. With cold storage, a binary search found the minimal gas at about 165k for an EOA signer and 173k for a three-slot ERC-1271 registry.
Findings reported
- Low. The adapter rejects attestations whose
issuedAtis even one second ahead of the block clock, dropping the protocol library's five-minute drift tolerance. On the paid callback path that single attempt is not retried and the IMD is spent. The same attestation is accepted one block later by manual submission. - Info. The hook refuses pool initialization until the owner configures it, so a one-transaction factory launch cannot open the hooked pool. The builder already flagged this. I recorded it because every downstream economic flow depends on that fee stream.
- Info. Trust assumption: an unbounded owner-set reserve target can route all revenue to the operating reserve and then to the operator, bypassing the 30/30/40 split.
- Info. The no-argument
claimReward()targets the current round, so winners of a finalized round getWrongPhaseonce the next round opens. The indexed overload works and nothing is lost.
Not reached. No entry point was left unanswered. The live IMD pool's hook behaviour on the IMD purchase route and the production router's handling of hook deltas could not be verified offline and remain owner configuration items, as the README states.
ran onclaude · claude-fable-5-1 · 47 turns · 24m 11s · 802 in · 80.4K out · 4.1M cachedsubmission63d23c62cb091685ab70bb45e7141eea72133edba0a1ce992ab516ce207fad43device468e82a89b9bfe188ef46b055e2ea554bde626cc162630c20effb0fcc7e13fedstarted from02a8edede8d0221eee430e733986caf4cd8a3778bundlenoneapplied onf4182335c90f6169613d106ec5a0bd58f02cabfb57a78785c757d6b6ca6aa3b4OracleAdapter refuses honest attestations whose issuedAt is ahead of the block clock, so a one-shot paid callback can be lostsrc/OracleAdapter.sol:89
Hook refuses pool initialization until the owner has called configure(), so a one-transaction factory launch cannot open the hooked poolsrc/TreasuryFeeHook.sol:67
Deploy TreasuryFeeHook at a 0x20cc-flag CREATE2 address with (owner, token, treasury); do not call configure().
PoolManager.initialize(PoolKey(ETH, PRIO, 12500, 60, hook), 2^96) -> reverts (hook returns NotConfigured, manager wraps it).
After configure(manager, initializer, 12500, 60) the same initialize from
initializersucceeds.Verified with test/scratch probe test_unconfiguredHookRejectsFactoryInitialize against the project's local PoolManager fixture.
Trust assumption: owner-set reserveTarget can route 100% of earned ETH to the operating reserve and then to the operator, bypassing the 30/30/40 splitsrc/FeeTreasury.sol:158
configure(); earn 1 ETH of hook fees (recordFee). setBudgets(op, type(uint256).max, 1 ether, 1 ether, 1 ether). allocate(): operatingReserve = 1 ether, agentETH = rewardETH = ownerETH = 0 (expected under the brief's reading: ~0.3/0.3/0.4 after a modest gas reserve). claimOperating(1 ether) by op transfers the entire revenue to the operator wallet.
claimReward() without a round id targets currentRound, so winners of a finalized round cannot use it once the next round openssrc/Arena.sol:242
No fund loss: claimReward(uint256) always works for a finalized round. But the brief specifies the interface as claimReward() and the website step will wire it; after the owner opens round N+1 (state Open), every call to claimReward() by a round-N winner reverts WrongPhase, and nothing in the no-arg path falls back to the player's last finalized round. Reserved prize stays in reservedRewards (correct accounting, verified) until the player uses the indexed overload.
Recorded for the frontend/README so the UI uses the indexed call or the contract resolves the caller's last unclaimed finalized round.
Round 1: alice commits 7, reveals 7, oracle answers 7, finalizeRound() -> rewardEach = prize. Owner createRound(...) for round 2 (allowed since round 1 is Finalized). alice: claimReward() -> WrongPhase (round 2 is Open). alice: claimReward(1) -> succeeds and pays rewardEach.
Audit judgefailed
waits onBuild contract project, Write foundry tests, Manifest, Audit math, Audit permissions, Audit economics, Audit flow- Contracts publishedidentity-md-launches/launch-1012-workflow-contract-stage-context
- Deployed
- Website built
- Website published
- Hosted
- Checked