Uniswap V3 Expert
ccashwell/evm-cortex
A skill your agent uses when building on, integrating with, or analyzing Uniswap V3.
Generate, simulate, audit, and deploy a Uniswap v4 hook + test pool from a brief, on any Uniswap v4 chain (every testnet and mainnet) - pre-audited templates or a from-scratch freeform hook (flags…
$ npx skills add aeonfun/aeon --skill deploy-uni-hook -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install aeonfun/aeon deploy-uni-hook --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/aeonfun/aeon.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/deploy-uni-hook .claude/skills/deploy-uni-hook && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "deploy-uni-hook" agent skill from https://github.com/aeonfun/aeon/tree/main/skills/deploy-uni-hook into .claude/skills/deploy-uni-hook/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "deploy-uni-hook", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/aeonfun/aeon/tree/main/skills/deploy-uni-hookType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add aeonfun/aeon --skill deploy-uni-hook -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install aeonfun/aeon deploy-uni-hook --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/aeonfun/aeon.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/deploy-uni-hook .agents/skills/deploy-uni-hook && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "deploy-uni-hook" agent skill from https://github.com/aeonfun/aeon/tree/main/skills/deploy-uni-hook into .agents/skills/deploy-uni-hook/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "deploy-uni-hook", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add aeonfun/aeon --skill deploy-uni-hook -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install aeonfun/aeon deploy-uni-hook --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/aeonfun/aeon.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/deploy-uni-hook .cursor/skills/deploy-uni-hook && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "deploy-uni-hook" agent skill from https://github.com/aeonfun/aeon/tree/main/skills/deploy-uni-hook into .cursor/skills/deploy-uni-hook/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "deploy-uni-hook", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/aeonfun/aeon.git --path skills/deploy-uni-hook--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add aeonfun/aeon --skill deploy-uni-hook -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install aeonfun/aeon deploy-uni-hook --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/aeonfun/aeon.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/deploy-uni-hook .gemini/skills/deploy-uni-hook && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "deploy-uni-hook" agent skill from https://github.com/aeonfun/aeon/tree/main/skills/deploy-uni-hook into .gemini/skills/deploy-uni-hook/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "deploy-uni-hook", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install aeonfun/aeon deploy-uni-hookInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add aeonfun/aeon --skill deploy-uni-hook -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/aeonfun/aeon.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/deploy-uni-hook .github/skills/deploy-uni-hook && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "deploy-uni-hook" agent skill from https://github.com/aeonfun/aeon/tree/main/skills/deploy-uni-hook into .github/skills/deploy-uni-hook/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "deploy-uni-hook", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add aeonfun/aeon --skill deploy-uni-hook -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install aeonfun/aeon deploy-uni-hook --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/aeonfun/aeon.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/deploy-uni-hook .opencode/skills/deploy-uni-hook && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "deploy-uni-hook" agent skill from https://github.com/aeonfun/aeon/tree/main/skills/deploy-uni-hook into .opencode/skills/deploy-uni-hook/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "deploy-uni-hook", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
deploy-uni-hookGenerate, simulate, audit, and deploy a Uniswap v4 hook + test pool from a brief, on any Uniswap v4 chain (every testnet and mainnet) - pre-audited templates or a from-scratch freeform hook (flags…
Deploy Uni Hook is an agent skill from aeonfun/aeon. Generate, simulate, audit, and deploy a Uniswap v4 hook + test pool from a brief, on any Uniswap v4 chain (every testnet and mainnet) - pre-audited templates or a from-scratch freeform hook (flags auto-derived; static audit + dangerous-pattern scan + a behavioral forge test + fork sim gate the deploy). Dry-run by default; explicit arm: to broadcast; testnet default, mainnet behind a double opt-in; records the deploy to main. Every deployed hook inherits a mandatory 10 bps AeonFee protocol fee.
Its SKILL.md is about 6.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 13 other files (for example `hook-deploy.sh`).
It sits in DevOps & Cloud. It works with Uniswap. The repository describes itself as: The most autonomous AI agent framework: runs unattended on GitHub Actions, self-healing skills, drives Claude Code, Grok, Codex & more. No approval loops. Configure once, forget… The licence is MIT.
5 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit f252074. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships script files (Shell), which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
notion.soFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
ALCHEMY_API_KEYDEPLOY_HOOK_NO_KEYETHERSCAN_API_KEYHOOK_DEPLOYER_PRIVATE_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Deploy Uni Hook loads about 6.6k tokens when it runs. Until then it costs about 129 tokens; SKILL.md has 3,448 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from aeonfun/aeon at commit f252074, republished under its MIT licence (© aeonfun). 3,448 words, ~6,611 tokens.
.claude/skills/deploy-uni-hook/SKILL.md (or your agent's skills folder). This skill also uses 12 other files; get the full folder from GitHub.${var} — the hook brief. Grammar:
[arm:][template:<name>] [chain:<name>] <brief>
- `` (empty) → print help and exit
DEPLOY_HOOK_EMPTY.<brief>→ dry-run: generate, compile, mine, and simulate. Never broadcasts. [default — no prefix]arm:<brief>→ broadcast: do the full dry-run first, then deploy for real if the simulation passes.template:<name>→ force a mode:dynamic|noop|skim(pre-audited templates) orfreeform(build a whole hook from the prompt). Omit to auto-pick: a brief that matches a template uses it; anything else →freeform.chain:<name>→ any Uniswap v4 chain inchains.tsv(run./hook-deploy.sh chainsto list). Defaultbase-sepolia. Testnets:base-sepolia,unichain-sepolia,arbitrum-sepolia. Mainnets (testnet: false, e.g.base,ethereum,unichain,arbitrum,optimism,polygon,bnb,avalanche, ...) require BOTHarm:and an explicitchain:— the skill never targets mainnet by default.base-mainnetis accepted as an alias forbase.
Today is ${today}. This skill turns a one-line brief into a live Uniswap v4 hook. It is built to be safe: it simulates every deploy before it broadcasts, it defaults to a dry-run on testnet, and it needs an explicit arm: to move on-chain.
A hook binding is immutable and a bad hook can brick a pool or steal funds. So the gates sit BEFORE the deploy: two of them (dry-run then arm:), a mandatory simulation, and idempotent state. Everything after the broadcast is just recording what already happened — appended to memory/state/hook-deploys.json on main, no PR (there is nothing left to review). The Foundry flow is the proven one — mine a CREATE2 salt so the address carries the right hook-flag bits, deploy, initialize the pool, add liquidity, run one swap.
testnet: false chain unless ${var} has BOTH arm: AND an explicit chain:<mainnet-name> — AND the instance has HOOK_MAINNET_OK=1 set as a repo variable (a third, operator-level lock enforced inside hook-deploy.sh, exit 7; store it as a variable, not a secret - a secret value of 1 masks every 1 in the run log, so tx hashes and links print as ***). An instance that never authorized mainnet cannot broadcast there even if an armed message asks it to. This skill must only run on an instance whose inbound path is owner-gated (TELEGRAM_ALLOWED_USER_ID / the multi-channel allowlist) — a mainnet deploy spends real gas, so an untrusted sender must never be able to dispatch it. On a mainnet chain, first read the deployer balance with cast balance and abort (DEPLOY_HOOK_UNDERFUNDED) if it cannot cover the simulation's Estimated amount required; hook-deploy.sh independently enforces a funding floor (exit 8), an optional MAX_GAS_GWEI gas-price ceiling (exit 9), and warns if the deployer holds more than HOOK_MAX_FLOAT_ETH (default 0.25) — a deploy key must hold gas float only, never LP or treasury capital. Log a clear MAINNET warning in the output.DEPLOY_HOOK_SIM_FAILED.${var} starts with arm:../hook-deploy.sh, which reads it from the env inside the script.memory/state/hook-deploys.json. If an identical brief already deployed within the last hour, do not re-deploy. The deploy script is also idempotent at the address level: it deploys to the canonical address (the first flag-matching CREATE2 salt for this exact (creationCode, flags, PoolManager)). If that address already holds code, an identical hook is already live, so the script logs ALREADY_DEPLOYED <addr> and does nothing — the runner reports the existing address instead of deploying a duplicate. (HookMiner itself skips occupied addresses, so without this check a re-run would silently deploy another copy at a new address.)skills/deploy-uni-hook/templates/ - AeonFee.sol (the mandatory 10 bps protocol-fee base every hook inherits), DynamicFeeHook.sol, NoOpHook.sol, HookFeeHook.sol (pre-audited), Hook.sol + Hook.t.sol + hook.env.example (freeform scaffold, behavioral-test gate, manifest), plus DeployHook.s.sol, MockERC20.sol, foundry.toml, chains.tsv.skills/deploy-uni-hook/templates/chains.tsv is the single source of truth — TAB-separated name chainId testnet poolManager stateView rpc explorer alchemy, one row per Uniswap v4 chain (staged next to hook-deploy.sh, which reads it). memory/uni-deployments.md mirrors it for humans. To add a chain, append a row to chains.tsv.rpc column is a public endpoint. When ALCHEMY_API_KEY is set and the row has an alchemy slug, hook-deploy.sh uses https://<slug>.g.alchemy.com/v2/$ALCHEMY_API_KEY instead — a trusted RPC matters for the mainnet sim + broadcast (a lying public RPC can fake a clean sim). Precedence: RPC_URL (override, for testing) > Alchemy key + slug > public rpc. The RPC path (where the key lives) is never printed — logs show host only.skills/deploy-uni-hook/hook-deploy.sh — the only sanctioned broadcast path (hides the key).memory/state/hook-deploys.json — idempotency + the deploy ledger.template: is not given)| Brief mentions | Mode |
|---|---|
| fee, volatility, dynamic, surge | dynamic |
| skim, hook fee, take a cut, revenue | skim |
| "minimal" / "starter" / "empty" | noop |
| game, leaderboard, points, crown, loyalty | freeform (game rules in Labs routing) |
| anything else (novel logic the templates don't cover) | freeform |
Every hook this skill deploys inherits AeonFee (templates/AeonFee.sol): a MANDATORY 10 bps (0.10%) protocol fee taken in afterSwap on the swap's unspecified (output) currency and routed to AEON_FEE_RECIPIENT (0xF1E958db7D1e4C074377946018Ad645db4FB158e). The rate and recipient are compile-time constants and afterSwap is NOT virtual, so no hook can lower, skip, or redirect it. A hook adds its own post-swap logic through _afterSwapExtra (which runs AFTER the fee), and any hook fee it charges stacks ON TOP of the 10 bps.
Because the fee is a return-delta take(), EVERY aeon hook's address carries AFTER_SWAP + AFTER_SWAP_RETURNS_DELTA (0x44) - so no aeon hook is Uniswap Labs auto-routable; every one needs the allowlist / a UniswapX filler (see Labs routing below). This is the deliberate trade for a fee that can never be bypassed.
Uniswap Labs auto-routes a hooked pool unless the address starts with 0x91, or the hook uses beforeSwapReturnsDelta, afterSwapReturnsDelta, or dynamicFees. Anything in that set needs the allowlist form or a UniswapX filler. Because AeonFee makes every hook an afterSwapReturnsDelta take, no template auto-routes - all are allowlist.
| Template | Flags | Labs classic router |
|---|---|---|
noop | 0xC4 (beforeSwap + AeonFee 0x44) | allowlist (afterSwapReturnsDelta) |
freeform default (_afterSwapExtra) | 0x44 (AeonFee) | allowlist (afterSwapReturnsDelta) |
dynamic | 0x10C4 (0x10C0 + AeonFee 0x04) + DYNAMIC_FEE_FLAG | allowlist (dynamicFees + afterSwapReturnsDelta) |
skim | 0x44 (AeonFee + own skim, same bits) | allowlist (afterSwapReturnsDelta) |
Game on a hook (freeform): the 10 bps fee already runs in the base afterSwap via take() - a freeform body must NOT implement afterSwap (put extra logic in _afterSwapExtra).
_afterSwapExtra and stacks on top.hookData names a player. Empty hookData (Labs Universal Router) = paid swap, no game, no revert.amountSpecified, block number, or a required swap direction. Those revert the router and collect nothing.sender is the router, not the user. Do not key game state off sender.Do not generate amount-suffix / block-echo / exact-out-only / direction-gate hooks unless the brief explicitly asks for a revert-gate. The miner skips 0x91... addresses.
These are standing defects measured on the live fleet. Freeform MUST NOT recreate them. The skim template is already patched.
Fee / take():
if (unspecifiedAmount <= 0) return silently skips the fee on every exact-output swap (shared-base F1).int256 before negating. -type(int128).min panics and bricks that swap.poolManager.take(..., feeRecipient, ...) to an immutable recipient. NEVER address(this). No withdraw(). Custody was the CrownClash/LegacyLedger HIGH.<= 0 early return (second copy of the sign guard).Gates (only if the brief demands a revert-gate):
block.number): a view helper answered at head N is wrong at execution N+1. Target the execution block.unlock frame can satisfy the predicate; a signed tx cannot. That binds the wrong party.amountSpecified to a token-denominated constant. The caller picks the specified currency via exact-in vs exact-out. Use a dimensionless bound (tick move / liquidity fraction).StateLibrary gives amount0 = L*2^96/sqrtP and amount1 = L*sqrtP/2^96, so amount0/amount1 = 1/price and the liquidity L cancels exactly. Any test on the two reserves (b0 >= b1, a skew band, "which side is heavier") therefore reduces to comparing the pool's RAW price to an implicit 1.0, and raw price is token1/token0 in smallest units, so it is ~1.0 only for a same-decimals pair near parity. A USDC(6d)/WETH(18d) pool sits ~8 orders of magnitude off; two 18-dec tokens at price 2.0 are already outside a 10% band. Such a gate is permanently one-directional on every real pair: one whole leg reverts forever, and "every trade rebalances toward 50/50" is false (a full-range position is already 50/50 by value at any price). Fix: snapshot the pool's OWN reference (its sqrtPriceX96 at afterInitialize, or an explicit target ratio from the brief) and gate the current price against THAT, never a hard-coded 1.0. This needs the afterInitialize callback (adds flag bit 0x1000), so a price/balance/skew hook must include it in the callback set or it cannot know its own starting price.balanceOf(poolManager): that is the v4 singleton's global inventory, not this pool. Use StateLibrary.sender is the router. Do not treat it as the trader.Tests:
hooks = address(0)).block.number across vm.roll (via-ir folds it). Use vm.getBlockNumber().setUp() pool starts at 1:1 (sqrtPriceX96 = 2^96), the single price where a raw-price-vs-1.0 gate looks correct no matter how it is written. Call _freshPoolAt(<non-1:1 sqrtPriceX96>) (helper in Hook.t.sol) and assert BOTH legs there: the leg that must stay open is not rejected, the leg that must close reverts. A gate proven only at 1:1 is a false pass.Parse ${var}. Extract the arm: flag, the optional template:, the optional chain:, and the free-text brief. Empty brief → exit DEPLOY_HOOK_EMPTY with the grammar.
Resolve the chain. The chain name resolves in chains.tsv (default base-sepolia); hook-deploy.sh maps it to the official PoolManager + RPC, so you pass the NAME, not the address. Run ./hook-deploy.sh chains to see the list, or read chains.tsv. If the name is not in the registry, exit DEPLOY_HOOK_BAD_CHAIN. Look up the row's testnet column: if it is false (mainnet), enforce the double opt-in — require BOTH arm: and an explicit chain: in ${var}, else exit DEPLOY_HOOK_BAD_CHAIN. Every Uniswap v4 chain is supported (Base, Ethereum, Unichain, Arbitrum, Optimism, Polygon, BNB, Avalanche, Robinhood, Worldchain, Ink, Soneium, Celo, X Layer + their testnets).
Confirm the staged toolchain + project. The workflow pre-stages everything before this run (scripts/stage-deploy-uni-hook.sh): Foundry on $PATH, a pre-built v4 project at $HOOKBUILD_DIR (default $HOME/hookbuild) holding all three templates + MockERC20.sol + DeployHook.s.sol + the v4 libraries, and ./hook-deploy.sh copied to the repo root. Do not install Foundry or clone the libs in-run — the sandbox blocks that. Check command -v forge and that $HOOKBUILD_DIR exists; if either is missing, degrade to DEPLOY_HOOK_NO_TOOLCHAIN (emit the generated source + plan).
Build the hook (brief-driven).
dynamic / noop / skim): in $HOOKBUILD_DIR/src/<Hook>.sol, edit ONLY the region between // --- AEON:LOGIC START --- and // --- AEON:LOGIC END ---. Keep the callback signatures and flag set unchanged. If the default already fits the brief, leave it.$HOOKBUILD_DIR/src/Hook.sol, replacing the // --- AEON:BODY ... --- region. Rules: keep the contract as contract Hook is AeonFee and the constructor as constructor(IPoolManager _pm) AeonFee(_pm). Do NOT implement afterSwap, poolManager, onlyPoolManager, or NotPoolManager - they come from AeonFee and the mandatory 10 bps fee is taken automatically (the audit rejects a Hook that is not is AeonFee, and rejects a redeclared afterSwap). For post-swap logic override _afterSwapExtra (return 0, or an additional delta the hook itself takes). Implement any OTHER v4 callbacks the prompt needs, each with the EXACT IHooks signature, onlyPoolManager, and the right selector return. Do NOT hand-set flags - they are auto-derived from your callbacks (plus the always-on AeonFee afterSwap/afterSwapReturnsDelta bits). If another callback returns a non-zero delta, set HOOK_RETURNS_DELTA in $HOOKBUILD_DIR/hook.env; for a fee-override hook set HOOK_POOL_FEE=dynamic there. Follow Labs routing and Fleet audit rules: empty hookData must succeed; a game must not revert a vanilla exact-in swap; an extra take() (in _afterSwapExtra) must charge magnitude (exact-in and exact-out) and never custody; a price/balance/skew gate must add the afterInitialize callback and anchor to the pool's own start price (Gates rule 6), never an implicit 1.0.$HOOKBUILD_DIR/test/Hook.t.sol, replace the // --- AEON:ASSERT ... --- region with test_* functions that assert the hook's SPECIFIC intended behavior — not just "does not revert". For every rule in the brief write at least one positive and one negative case: a swap the hook must REJECT as _expectSwapRevert(zeroForOne, amount, Hook.SomeError.selector) (this helper unwraps v4's WrappedError for you — do NOT use bare vm.expectRevert, it won't match the wrapper); a swap it must ALLOW as a plain _swap(...); any getter/accounting as assertEq(hook.someGetter(...), expected). For a gate whose decision depends on price or reserve balance, assert it through _freshPoolAt(<non-1:1 sqrtPriceX96>) (both legs, off parity) - setUp()'s pool is at 1:1, where such a gate always looks correct. Do NOT edit setUp() or the helpers - only the AEON:ASSERT region. If the brief has no rejectable behavior, still assert the observable state the hook changes.Simulate + audit (always). Pass mode, kind, and chain (chain omitted = base-sepolia):
./hook-deploy.sh simulate <kind> <chain>For freeform this runs, in order, three gates before any deploy:
Hook, is is AeonFee (mandatory fee) and does not redeclare afterSwap, has ≥1 callback or _afterSwapExtra, every callback carries onlyPoolManager, test/Hook.t.sol has ≥1 test_ function, and scans for dangerous patterns (selfdestruct/delegatecall are hard fails; tx.origin/raw value-call/inline assembly print a warning to review). A failure exits DEPLOY_HOOK_AUDIT_FAILED (never deploy).forge test --fork-url <chain> --match-contract HookBehaviorTest runs the agent-written assertions on a fork. A failing OR non-compiling test exits DEPLOY_HOOK_TEST_FAILED (never deploy). This proves the hook does what the prompt asked.forge script compiles, mines the salt, deploys in-memory, initializes the pool, adds liquidity, and runs one swap against a fork of the target chain.
On a compile error, fix and retry (max 3). On a sim revert, exit DEPLOY_HOOK_SIM_FAILED. Capture the mined hook address, the derived flags, and the Estimated amount required. On mainnet, compare that estimate to the deployer balance (cast balance <addr> --rpc-url <rpc>) and exit DEPLOY_HOOK_UNDERFUNDED if it will not cover it.
For a freeform hook, also read the generated Hook.sol and reason about safety before arming: does any callback let a caller steal funds, brick the pool (unconditional revert), or reenter? If unsure, stop at the dry-run and report the concern.Dry-run stop. If ${var} did NOT start with arm:, STOP here. Report: template, mined address (with its flag bits), the receipt routing line (auto-route vs allowlist + reason), the pool key, and the simulation result. Exit DEPLOY_HOOK_DRY_RUN.
Arm checks (only if arm:).
HOOK_DEPLOYER_PRIVATE_KEY is set (it is injected via requires:). If not, degrade to the dry-run report and exit DEPLOY_HOOK_NO_KEY.memory/state/hook-deploys.json. If the same (chain, template, brief) deployed in the last hour, exit DEPLOY_HOOK_IDEMPOTENT with the prior address.Broadcast.
./hook-deploy.sh broadcast <kind> <chain>The runner prints a deploy receipt (hook address, decoded flag names, explorer deep-link, tx hashes) and, when ETHERSCAN_API_KEY is set on an Etherscan-family chain, auto-verifies the hook source on the explorer (best-effort — a failed verify never fails a completed deploy). If it printed ALREADY_DEPLOYED, treat the reported address as the result (no new deploy). Read the hook address and the transaction hashes from the receipt or $HOOKBUILD_DIR/broadcast/DeployHook.s.sol/<chainId>/run-latest.json.
Verify. With cast, read the pool back through StateView.getSlot0(poolId) on the RPC. Confirm the pool exists and the hook address low bits equal the template's flags. Confirm the swap emitted the hook event.
Record the deploy. The deploy already happened on-chain — this is append-only history, not a change to review, so DO NOT open a PR or a branch. Just write the record into the working tree on main; the workflow's post-run commit lands it. Write:
memory/state/hook-deploys.json — append this deploy (chain, template, brief, hook address, flags, tx hashes, timestamp, poolId, poolKey).output/hooks/<hook-address>.sol — copy the deployed source from $HOOKBUILD_DIR/src/<Hook>.sol.output/hooks/<hook-address>.t.sol — copy $HOOKBUILD_DIR/test/Hook.t.sol (the behavioral test that gated the deploy).Do NOT stage the root ./hook-deploy.sh or ./chains.tsv (runtime copies; both gitignored).
Publish to the public hook list (live mainnet deploys only). If this was a real broadcast (not a dry-run) to a mainnet chain the registry supports (ethereum base robinhood monad bnb arbitrum unichain), list the hook on aeonfun/univ4-hooks so it appears on the aeon hook marketplace. Reuse the submit-hook skill's helper - it decodes the flags from the address, formats the entry, regenerates the registry, and opens a PR (issue fallback when there is no push access):
python3 skills/submit-hook/submit-univ4.py \
--address "$HOOK_ADDR" --chain "$CHAIN" \
--name "$NAME" --category "$CATEGORY" --klass "$KLASS" \
--template "$TEMPLATE" --stage deployed --source aeon --verified \
--date "$(date -u +%F)" \
--mechanic "$MECHANIC" --plain "$PLAIN" --rule "$RULE1" --rule "$RULE2"Derive name/category/klass/mechanic/plain/rules from the brief exactly as skills/submit-hook/SKILL.md describes. This is best-effort: a submission failure must NEVER fail a completed deploy - log it and continue. Skip entirely on a dry-run, a testnet, or an unsupported chain.
Notify + exit. Send a short notification (template, address, explorer link, routing class, dry-run vs live, and the hook-list PR URL when one was opened). Exit DEPLOY_HOOK_OK (or DEPLOY_HOOK_DRY_RUN).
DEPLOY_HOOK_NO_KEY. Never fail hard.command -v forge fails or $HOOKBUILD_DIR absent) → emit the generated source + plan, DEPLOY_HOOK_NO_TOOLCHAIN. Do not try to install in-run (the sandbox blocks it).DEPLOY_HOOK_BAD_CHAIN.HOOK_MAINNET_OK=1 (hook-deploy.sh exit 7) → DEPLOY_HOOK_MAINNET_NOT_AUTHORIZED (never broadcast).hook-deploy.sh exit 8) → DEPLOY_HOOK_UNDERFUNDED (never broadcast).MAX_GAS_GWEI (hook-deploy.sh exit 9) → DEPLOY_HOOK_GAS_TOO_HIGH (never broadcast; retry when fees drop).onlyPoolManager / no test_ / selfdestruct / delegatecall) → DEPLOY_HOOK_AUDIT_FAILED (never deploy).DEPLOY_HOOK_TEST_FAILED (never deploy).DEPLOY_HOOK_SIM_FAILED (never broadcast after a failed sim).AeonFee, so all carry the return-delta bits and are allowlist (dynamic = 0x10C4; noop = 0xC4; skim = 0x44).src/Hook.sol and its behavioral test into test/Hook.t.sol. Flags are auto-derived from the callbacks (never hand-set). Three gates run before any deploy: a static audit (name/callbacks/onlyPoolManager/test-present/dangerous-pattern scan), the agent-written forge test behavioral assertions on a fork, then the fork simulation. The agent also reads the generated source for steal/brick/reentrancy risk before arming. Prefer a matching template when one fits (they are audited); use freeform for novel logic.chains.tsv carries every official v4 deployment (Base, Ethereum, Unichain, Arbitrum, Optimism, Polygon, BNB, Avalanche, Robinhood, Worldchain, Ink, Soneium, Celo, X Layer + the Sepolia testnets), each verified to hold the PoolManager. The same flow runs on all of them — only the PoolManager/RPC differ, resolved by name. The CREATE2 deployer (0x4e59…4956C) is required for the mined address; if a chain lacks it the fork simulation fails closed before any broadcast.MockERC20 tokens to itself (free) and seeds the demo pool with those mock tokens — a mainnet broadcast risks GAS ONLY, never real capital. The deployed pool is a MockA/MockB demo; the reusable hook contract is the real deliverable. The deployer key must be a funded burner holding gas float only (the runner warns above HOOK_MAX_FLOAT_ETH); mainnet also needs the HOOK_MAINNET_OK=1 operator lock. A future version can add the keyless Base MCP send_calls rail so no key sits in the runner.ALCHEMY_API_KEY + the chain's alchemy slug) over the public RPC, so a lying public node can't fake a clean sim. After a broadcast it prints a receipt (address, decoded flags, explorer link, tx hashes) and, with ETHERSCAN_API_KEY on an Etherscan-family chain, auto-verifies the source (best-effort). All of this is opt-in: with no keys set the skill still runs on public RPCs, unverified.© aeonfun, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 12 other files in skills/deploy-uni-hook of aeonfun/aeon.
Open the folder on GitHubat commit f252074
Deploy Uni Hook next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Deploy Uni Hook this skillaeonfun/aeon | 767 | — | ~6.6k | Automated safety check: Pass | MIT | |
| Uniswap V3 Expertccashwell/evm-cortex | 131 | — | ~9.6k | Automated safety check: Pass | MIT | |
| Monitor CInrwl/nx | 29k | 5 repos | ~4.7k | Automated safety check: Pass | MIT | |
| Terraform and OpenTofu Guideagentscope-ai/QwenPaw | 35k | 6 repos | ~4.2k | Automated safety check: Pass | Apache-2.0 | |
| Vercel Optimize Auditvercel-labs/agent-skills | 32k | 8 repos | ~4.3k | Automated safety check: Pass | None | |
| Analyze GitHub Action Logswithastro/astro | 63k | 1 repos | ~1.3k | Automated safety check: Pass | Custom licence |
ccashwell/evm-cortex
A skill your agent uses when building on, integrating with, or analyzing Uniswap V3.
nrwl/nx
Monitor Nx Cloud CI pipeline and handle self-healing fixes. An agent skill from nrwl/nx.
agentscope-ai/QwenPaw
Guidance for writing and testing Terraform and OpenTofu code: module structure, naming, test approaches, CI/CD workflows, state handling and security scanning.
vercel-labs/agent-skills
Runs a metrics-first audit of a deployed Vercel project, gating investigations on real signals to produce ranked, citation-backed cost and performance recommendations.
withastro/astro
Analyze recent GitHub Actions workflow runs to identify patterns, mistakes, and improvements.
netdata/netdata
Use only when the user explicitly asks to build, run, preview, inspect, or validate learn.netdata.cloud locally using the contents of a PR or documentation branch before merge.
aeonfun/aeon
Browses open tasks on the TaskMarket agent-worker market and, with explicit operator approval, creates tasks, tracks submissions and submits finished work.
aeonfun/aeon
Sets up and manages an Aeon agent instance that runs skills on a schedule through GitHub Actions: starting, rescheduling, debugging, editing skills and mining chat history.
aeonfun/aeon
Reads a Base Account's address, portfolio and transaction history through the Base MCP server, and stays strictly read-only in unattended Aeon runs, reporting only changes.
aeonfun/aeon
Audits every page of a site each day from its sitemap, scores on-page and technical SEO, checks duplicates across pages and reports what changed since the last run.
aeonfun/aeon
5 concrete real-life actions, leverage-scored against open loops with specificity and anti-fluff gates
aeonfun/aeon
Static linter for an Aeon instance's configuration that catches silent failures such as unquoted schedules, duplicate keys, unconfigured skills and broken MCP references.
Works with
Categories
Generate, simulate, audit, and deploy a Uniswap v4 hook + test pool from a brief, on any Uniswap v4 chain (every testnet and mainnet) - pre-audited templates or a from-scratch freeform hook (flags…. Deploy Uni Hook is an agent skill from aeonfun/aeon. Generate, simulate, audit, and deploy a Uniswap v4 hook + test pool from a brief, on any Uniswap v4 chain (every testnet and mainnet) - pre-audited templates or a from-scratch freeform hook (flags auto-derived; static audit + dangerous-pattern scan + a behavioral forge test + fork sim gate the deploy).
Deploy Uni Hook fits situations like: devOps & Cloud work in your project.
Run `npx skills add aeonfun/aeon --skill deploy-uni-hook -a claude-code`. Or copy the skill folder (skills/deploy-uni-hook in aeonfun/aeon) into .claude/skills/deploy-uni-hook in your project. Claude Code loads it when a task matches its description.
Run `npx skills add aeonfun/aeon --skill deploy-uni-hook -a codex`. Or copy the skill folder (skills/deploy-uni-hook in aeonfun/aeon) into .agents/skills/deploy-uni-hook in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add aeonfun/aeon --skill deploy-uni-hook -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/deploy-uni-hook, .gemini/skills/deploy-uni-hook, .github/skills/deploy-uni-hook and .opencode/skills/deploy-uni-hook in your project.
Going by SKILL.md and its folder, Deploy Uni Hook needs a shell for the scripts in its folder and credentials named ALCHEMY_API_KEY, DEPLOY_HOOK_NO_KEY, ETHERSCAN_API_KEY and HOOK_DEPLOYER_PRIVATE_KEY. Our summary lists: A Bash shell; A credential in HOOK_DEPLOYER_PRIVATE_KEY; A credential in ALCHEMY_API_KEY.
SKILL.md names 1 domain. As links in the text: notion.so. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Deploy Uni Hook is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.6k tokens (SKILL.md is roughly 26k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Deploy Uni Hook: Uniswap V3 Expert (ccashwell/evm-cortex, 131 stars), Monitor CI (nrwl/nx, 29k stars), Terraform and OpenTofu Guide (agentscope-ai/QwenPaw, 35k stars) and Vercel Optimize Audit (vercel-labs/agent-skills, 32k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
aeonfun (a GitHub organization) maintains it in aeonfun/aeon, which has 767 GitHub stars. The repository holds 82 skills in this directory. The repository was last updated on October 6, 2026.
Source: aeonfun/aeon on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.