The model never writes calldata. Builders in this repo produce the bytes; a separate guard re-decodes them before anything reaches a wallet. Below are the only contracts and selectors a Pantessa build may emit, per venue and per chain, with the guard that fences each one and the bounds it enforces — read from the same constants the builders use, not retyped, and served as JSON at /api/venues/manifest for your own tooling to pin.
How to read this page
- 12 venues are tx-shaped (they can hand your wallet something to sign); 1 is read-only and can never produce a signable artifact. The pill on each card says which.
- 49 pinned addresses across 6 chains. Each row names the constant it was read from; the standing harness asserts the literal is in that file. A pin that lives only in the free MCP repo is named, not copied.
- Selectors are derived from the builders' own ABIs with viem, or imported from the guard that pins them (Aave, Morpho) — a build for one operation can never smuggle another operation's calldata past its guard.
- Custody is stated honestly per venue. As of 2026-11-02 no institutional custody lane has been drilled end to end; Hyperliquid perps through custody are the most friction and are marked unmeasured.
- This page is the human twin of the JSON. The integrity hash in the footer is sha256 over the canonical JSON of the chains, fees, invariants, signing and venue sections; two deploys of the same code and env agree.
Venue-neutral invariants
| invariant | what it means | where |
|---|
| The model never writes calldata | The planner classifies intent; per-venue builders in this repo produce every to / data / value / typed-data field from on-chain reads and the pinned constants above. | GUARDRAILS.md §1 |
| Fail closed, everywhere | A guard error refuses the build; a blocked report withholds the artifact; a fallback never fires on a guard failure. | GUARDRAILS.md §2 · lib/tx-guardrails.ts#buildReport |
| Nothing stale reaches a wallet | Deadline-bearing calldata ships as a txChain with validUntil and a server refresh recipe; the refresh route accepts intent params only. | GUARDRAILS.md §3 · app/api/tx/refresh/route.ts |
| Only the kill switch refuses | The retail spend policy was retired 2026-10-30; a frozen or revoked account refuses every outflow on every path and every relay. | GUARDRAILS.md §4 · lib/tx-guardrails.ts#policyCheck |
| Relays re-gate on the server | Signing is client-side; acceptance is not. CoW, OpenSea and Hyperliquid submits re-derive, recover the signer and re-guard before anything reaches a venue. | GUARDRAILS.md §5 |
| Recipient and validity are venue-neutral | Proceeds return to the requesting wallet; nothing stays signable past 31 days. | lib/tx-guardrails.ts#recipientCheck · validityCheck · MAX_VALID_SEC |
| External tools are fenced | A directory MCP that returns a signable payload passes guardPlannerArtifact; the drain shapes are refused outright. | lib/planner-artifact-guard.ts#guardPlannerArtifact |
Fees, one source
| treasury | 0x9Cc0B7A0DdB091E17647d689206e730131E9892A |
|---|
| swap fee (organic chat) | 20 bps |
|---|
| swap fee (intent links) | 50 bps · 50% to the creator |
|---|
| Hyperliquid builder fee | 100 tenths of a bp |
|---|
| cross-chain fee | 20 bps · 1Click keeps 50% |
|---|
| source | lib/fees.ts (the one fee source; the treasury address appears nowhere else — grep-enforced by the audit) |
|---|
Who signs
The user’s own wallet (or, for standing intents, a delegated key under venue-side limits). Pantessa never holds a key and never takes custody.
- browser wallet over EIP-1193 / WalletConnect v2 (the chat, /i links, the embed)
- the agent-signed desk path: any viem Account drives one guarded leg at a time (pantessa SDK driveJob)
- delegated keys for standing intents (Guardians, autopilots) that the venue bars from withdrawing
Custody lanes: No institutional custody lane (Fireblocks, Copper, Fordefi, Safe) has been drilled end to end as of 2026-11-02. The desk wire is custody-shaped (poll → one unsigned leg → their signer → on-chain verification); the measurement is the open item.
Venues
Uniswap v3 (+ v4 fallback) · CoW Protocol · Aave v4 · Morpho Blue · Lido · Hyperliquid (HyperCore perps) · NEAR Intents (cross-chain via 1Click) · LiFi (settlement on Robinhood Chain · the funding bridge) · OpenSea (Seaport 1.6) · Snapshot (off-chain governance) · Robinhood Chain (bridge; tokenized stocks trade via Uniswap v4 above) · Token sends (the transfer layer) · Pantessa Wallet (reads)
Uniswap v3 (+ v4 fallback)
native builder + free MCPtx-shapedfleet · uniswap-freePantessa/website · Pantessa/free-mcps
Pinned contracts
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0x04e45aaf | exactInputSingle((address,address,uint24,address,uint256,uint256,uint160)) | lib/uniswap-venue.ts#SWAP_ROUTER_02_ABI |
| 0x5ae401dc | multicall(uint256,bytes[]) | lib/uniswap-venue.ts#SWAP_ROUTER_02_ABI |
| 0xe0e189a0 | sweepTokenWithFee(address,uint256,address,uint256,address) | lib/uniswap-venue.ts#SWAP_ROUTER_02_ABI |
| 0x9b2c0a37 | unwrapWETH9WithFee(uint256,address,uint256,address) | lib/uniswap-venue.ts#SWAP_ROUTER_02_ABI |
| 0xf2d5d56b | pull(address,uint256) | lib/uniswap-venue.ts#SWAP_ROUTER_02_ABI |
| 0xdf2ab5bb | sweepToken(address,uint256,address) | lib/uniswap-venue.ts#SWAP_ROUTER_02_ABI |
| 0x49404b7c | unwrapWETH9(uint256,address) | lib/uniswap-venue.ts#SWAP_ROUTER_02_ABI |
| 0xc6a5026a | quoteExactInputSingle((address,address,uint256,uint24,uint160)) | lib/uniswap-venue.ts#QUOTER_V2_ABI |
| 0x3593564c | execute(bytes,bytes[],uint256) | lib/uniswap-v4.ts#UNIVERSAL_ROUTER_ABI |
| 0xaa9d21cb | quoteExactInputSingle(((address,address,uint24,int24,address),bool,uint128,bytes)) | lib/uniswap-v4.ts#V4_QUOTER_ABI |
| 0x87517c45 | approve(address,address,uint160,uint48) | lib/uniswap-v4.ts#PERMIT2_ABI |
| 0x927da105 | allowance(address,address,address) | lib/uniswap-v4.ts#PERMIT2_ABI |
| 0x095ea7b3 | approve(address,uint256) | viem#erc20Abi (approve step) |
| 0xd0e30db0 | deposit() | lib/weth-wrap.ts#WETH_DEPOSIT_SELECTOR |
Operations
- quote read — nothing to sign
QuoterV2 across every fee tier, read over RPC. - swap (v3) a chain of transactions (validUntil + refresh)
approve (exact amount) → SwapRouter02 multicall(deadline, exactInputSingle | exactInput); the chain carries validUntil and a server refresh recipe, so stale calldata is never offered. - swap (v4 fallback) a chain of transactions (validUntil + refresh)
Permit2 approve → Universal Router execute(V4_SWAP[, PAY_PORTION, SWEEP]); only when v3 has no pool (NoV3PoolError), only on chains with uniswapV4 pinned. - wrap / unwrap one transaction
WETH deposit / withdraw on the pinned wrapped-native contract.
The guard in front of the signature
lib/uniswap-venue.ts guardUniswapV3Build refuses:- a target that is not the pinned SwapRouter02 on the asked chain
- an outer call that is not multicall(deadline, …) or a deadline other than the one stamped
- a pool fee tier outside FEE_TIERS or not the quoted one
- a recipient other than the signer
- an amount or minimum-out other than the quoted one
lib/uniswap-v4.ts guardUniswapV4Build refuses:- a Permit2 approval wider than the swap
- Universal Router commands other than the pinned set
- a past deadline
- an output recipient other than the signer
lib/swap-exec.ts buildGuardedSwap (the cascade) refuses:- a v3→v4 fallback on anything but NoV3PoolError, a v4→LiFi fallback on anything but GatedV4PoolError — a guard failure is a block, never a fallback trigger
app/api/tx/refresh/route.ts POST (rebuild) refuses:- client-supplied to/data/value — only intent params are accepted; every rebuild re-runs the full guard set plus an estimateGas revert probe
lib/tx-guardrails.ts recipientCheck · validityCheck · buildReport refuses:- proceeds to any wallet but the requesting one
- anything signable for more than 31 days (MAX_VALID_SEC)
- any block-level check failing → blocked: true → no consumer offers the artifact
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
| feeTiers | 100, 500, 3000, 10000 |
|---|
| defaultSlippageBps | 50 |
|---|
| deadlineSec | 600 |
|---|
| maxValidSec | 2678400 |
|---|
| swapFeeBps | 20 |
|---|
| linkSwapFeeBps | 50 |
|---|
Notes
- The fee rides as its own visible transfer step (or a PAY_PORTION command on v4), never buried in venue calldata.
- Base pins are also exported as UNI_SWAP_ROUTER_02 / UNI_QUOTER_V2 (lib/uniswap-venue.ts); the pins script asserts they equal the registry.
- Pins kept in the free MCP, not this repo:
free-mcps/services/uniswap/lib/chain.ts (Pantessa/free-mcps).
Custody: Signed by a browser or WalletConnect wallet today. A custody signer (Fireblocks, Copper, Safe) has not been drilled against the multicall deadline (an approver at lunch meets the refresh path).
CoW Protocol
native builder + free MCPtx-shapedfleet · cow-freePantessa/website · Pantessa/free-mcps
Pinned contracts
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0x095ea7b3 | approve(address,uint256) | viem#erc20Abi (approve step to the vault relayer) |
Signing domain
| domain | name: Gnosis Protocol · version: v2 · verifyingContract: 0x9008D19f58AAbD9eD0D60971565AA8510560ab41 |
|---|
| primaryType | Order |
|---|
| fields | sellToken:address, buyToken:address, receiver:address, sellAmount:uint256, buyAmount:uint256, validTo:uint32, appData:bytes32, feeAmount:uint256, kind:string, partiallyFillable:bool, sellTokenBalance:string, buyTokenBalance:string |
|---|
| source | lib/cow.ts#COW_EIP712_DOMAIN · COW_ORDER_TYPES |
|---|
Operations
- quote read — nothing to sign
The order book at api.cow.fi. - swap order a signed order (settled by the venue)
An EIP-712 GPv2 Order the wallet signs; solvers settle it in a batch auction (no MEV, no 600-second deadline race). - limit order a signed order (settled by the venue)
The same Order struct with a limit price and a validTo measured in days. - submit · cancel read — nothing to sign
Relays through /api/cow/submit, which re-gates on the server (recipient = signer, not expired, re-priced).
The guard in front of the signature
lib/cow-guardrails.ts pureChecks refuses:- slippage above 500 bps
- a receiver other than the signer
- an expired or over-long validTo
- a balance or allowance the chain does not show
app/api/cow/submit/route.ts POST (relay) refuses:- a signed order whose recipient is not the signer, that has expired, or that fails the live re-price and re-gate; a blocked quote withholds the raw order struct
lib/planner-artifact-guard.ts guardPlannerArtifact refuses:- any transaction on a chain outside the app registry
- any call to Permit2 (0x000000000022d473030f116ddee9f6b43ac78ba3) from an external tool
- bare native sends to a third party built by an external tool
- UNLIMITED token approvals
- transferFrom-family calldata and setApprovalForAll from external tools
- any generic EIP-712 order that is not a CoW order verifying against the pinned GPv2 settlement and paying the signer
- a Snapshot vote whose primaryType is not Vote, that carries an on-chain domain, or whose voter is not the requesting wallet
lib/tx-guardrails.ts recipientCheck · validityCheck · buildReport refuses:- proceeds to any wallet but the requesting one
- anything signable for more than 31 days (MAX_VALID_SEC)
- any block-level check failing → blocked: true → no consumer offers the artifact
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
| maxSlippageBps | 500 |
|---|
| maxValidSec | 2678400 |
|---|
| swapFeeBps | 20 |
|---|
| linkSwapFeeBps | 50 |
|---|
Notes
- The fee tier is written into the signed appData document, so the fee is visible in the order, never in calldata.
- A Safe can pre-sign a GPv2 order — the natural first venue for a custody lane.
- Pins kept in the free MCP, not this repo:
free-mcps/services/cow/lib/cow.ts (Pantessa/free-mcps).
Custody: Browser / WalletConnect wallets today. Safe presign (setPreSignature) is the designed custody lane; not yet drilled.
Aave v4
native builder + free MCPtx-shapedPantessa/website · Pantessa/free-mcps
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0x852a56a5 | supply(id, amount, onBehalfOf) — spoke call | lib/aave-supply.ts#AAVE_OP_SELECTORS.supply |
| 0x0ad58d2f | withdraw(id, amount, receiver) — spoke call | lib/aave-supply.ts#AAVE_OP_SELECTORS.withdraw |
| 0xd6bda0c0 | borrow(id, amount, receiver) — spoke call | lib/aave-supply.ts#AAVE_OP_SELECTORS.borrow |
| 0xb1e8f8ef | repay(id, amount, onBehalfOf) — spoke call | lib/aave-supply.ts#AAVE_OP_SELECTORS.repay |
Operations
- markets · reserves · portfolio read — nothing to sign
The official AaveKit API (hub-and-spoke). - supply · withdraw · borrow · repay a chain of transactions (validUntil + refresh)
approve (exact) → the op call on the spoke; the spoke address is resolved from the official reserves list at build time and cross-checked against the reserve-id SET of the asked asset on that spoke — never an address a model or a tool asserted.
The guard in front of the signature
lib/aave-supply.ts guardAaveOpBuild · guardAaveSupplyBuild refuses:- a final call whose target is not the spoke from the official reserves list
- a selector other than the pinned one for THIS op (a borrow can never ride a withdraw build)
- an amount word that is not the asked amount (or the live-probed withdraw-max sentinel / a repay-max within the bounded buffer)
- an approval to any spender but the spoke, or wider than the op
- a step on another chain
lib/tx-guardrails.ts recipientCheck · validityCheck · buildReport refuses:- proceeds to any wallet but the requesting one
- anything signable for more than 31 days (MAX_VALID_SEC)
- any block-level check failing → blocked: true → no consumer offers the artifact
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
Notes
- No spoke address is pinned in this repo on purpose: Aave v4 lists spokes dynamically, so the guard pins the SOURCE (the official reserves list) and the selector, then re-verifies the build against both.
- Pins kept in the free MCP, not this repo:
free-mcps/services/aave/lib/tools.ts (Pantessa/free-mcps).
Custody: Plain approve + call transactions — the easiest venue for a custody signer; not yet drilled.
Morpho Blue
native builder + free MCPtx-shapedPantessa/website · Pantessa/free-mcps
Pinned contracts
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0xa99aad89 | supply(MarketParams,uint256,uint256,address,bytes) | lib/morpho-supply.ts#MORPHO_OP_SELECTORS.lend |
| 0x238d6579 | supplyCollateral(MarketParams,uint256,address,bytes) | lib/morpho-supply.ts#MORPHO_OP_SELECTORS.supply-collateral |
| 0x50d8cd4b | borrow(MarketParams,uint256,uint256,address,address) | lib/morpho-supply.ts#MORPHO_OP_SELECTORS.borrow |
| 0x20b76e81 | repay(MarketParams,uint256,uint256,address,bytes) | lib/morpho-supply.ts#MORPHO_OP_SELECTORS.repay |
| 0x5c2bea49 | withdraw(MarketParams,uint256,uint256,address,address) | lib/morpho-supply.ts#MORPHO_OP_SELECTORS.withdraw |
| 0x8720316d | withdrawCollateral(MarketParams,uint256,address,address) | lib/morpho-supply.ts#MORPHO_OP_SELECTORS.withdraw-collateral |
Operations
- markets · position · preview read — nothing to sign
The official Blue API with a pinned on-chain fallback. - lend · supply collateral · borrow · repay · withdraw · withdraw collateral a chain of transactions (validUntil + refresh)
approve (exact) → the op on the singleton with the market tuple resolved on-chain; the per-op 32-byte word layout is pinned (MORPHO_OP_LAYOUT) and every word is verified.
The guard in front of the signature
lib/morpho-supply.ts guardMorphoOpBuild refuses:- a target other than the singleton
- a selector other than the pinned one for THIS op
- a market tuple other than the one resolved on-chain
- an onBehalf / receiver other than the signer
- an amount word other than the asked amount
- a thin health factor, a balance or borrowing power the chain does not show
lib/tx-guardrails.ts recipientCheck · validityCheck · buildReport refuses:- proceeds to any wallet but the requesting one
- anything signable for more than 31 days (MAX_VALID_SEC)
- any block-level check failing → blocked: true → no consumer offers the artifact
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
Notes
- Pins kept in the free MCP, not this repo:
free-mcps/services/morpho/lib/morpho.ts (Pantessa/free-mcps).
Custody: Plain approve + call transactions; not yet drilled with a custody signer.
Lido
native builder + free MCPtx-shapedPantessa/website · Pantessa/free-mcps
Pinned contracts
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0xa1903eab | submit(address) | lib/lido-stake.ts#STETH_SUBMIT_ABI |
Operations
- stats · position · earnings · withdrawals read — nothing to sign
RPC + Lido’s public APIs through the MCP. - stake one transaction
ONE payable submit(referral) on the pinned stETH contract for the asked ETH, built natively and re-decoded. - wrap · unwrap · request withdrawal · claim one transaction
Construction-only builds from the free MCP (pins in free-mcps/lido), guarded by the generic planner guard on this side.
The guard in front of the signature
lib/lido-stake.ts guardLidoStakeBuild refuses:- anything but a single send_transaction step
- a target other than the pinned stETH contract on Ethereum
- a value other than the asked ETH
- calldata that is not submit(referral)
lib/planner-artifact-guard.ts guardPlannerArtifact refuses:- any transaction on a chain outside the app registry
- any call to Permit2 (0x000000000022d473030f116ddee9f6b43ac78ba3) from an external tool
- bare native sends to a third party built by an external tool
- UNLIMITED token approvals
- transferFrom-family calldata and setApprovalForAll from external tools
- any generic EIP-712 order that is not a CoW order verifying against the pinned GPv2 settlement and paying the signer
- a Snapshot vote whose primaryType is not Vote, that carries an on-chain domain, or whose voter is not the requesting wallet
lib/tx-guardrails.ts recipientCheck · validityCheck · buildReport refuses:- proceeds to any wallet but the requesting one
- anything signable for more than 31 days (MAX_VALID_SEC)
- any block-level check failing → blocked: true → no consumer offers the artifact
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
| gasBufferEth | 0.002 |
|---|
| maxValidSec | 2678400 |
|---|
Notes
- Pins kept in the free MCP, not this repo:
free-mcps/services/lido/lib/chain.ts (stETH, wstETH, the withdrawal queue) (Pantessa/free-mcps).
Custody: One payable call; not yet drilled with a custody signer.
Hyperliquid (HyperCore perps)
native builder + free MCPtx-shapedcustody lane unmeasuredfleet · hyperliquid-freePantessa/website · Pantessa/free-mcps
Pinned contracts
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0xa9059cbb | transfer(address,uint256) | viem#erc20Abi (the deposit is a USDC transfer to Bridge2) |
Signing domain
| domain | chainId: 1337 |
|---|
| primaryType | HyperliquidTransaction (the venue’s L1 action envelope: order · updateLeverage · approveBuilderFee · batch) |
|---|
| fields | action (msgpack-hashed, key order pinned by canonicalizeHlAction), nonce, builder { b, f } when the builder fee is on |
|---|
| source | lib/desk-wire.ts#HL_DOMAIN_CHAIN_ID · lib/hyperliquid-exec.ts#hlActionTypedData |
|---|
Operations
- markets · books · funding · portfolio · fills read — nothing to sign
The public info API through the free MCP (read-only). - open · close · stop a Hyperliquid L1 action
An L1 order action the wallet signs; the relay (/api/hl/submit) re-derives the typed data from the raw action and nonce, recovers the signer, re-guards against the live market, then forwards. - batch a Hyperliquid L1 action
Up to 3 members in one signature (guardHlBatch). - set leverage a Hyperliquid L1 action
Cross-mode leverage within the coin’s venue range, guarded. - approve builder fee a Hyperliquid L1 action
Approves EXACTLY the fee charged (HL_BUILDER_MAX_FEE_RATE), never a looser cap. - deposit one transaction
A USDC transfer on Arbitrum to Bridge2, minimum HL_MIN_DEPOSIT_USDC.
The guard in front of the signature
lib/hyperliquid-exec.ts guardHlExecBuild · guardHlLeverageBuild · guardHlBuilderFeeApproval refuses:- an order whose coin, side, size or reduce-only flag differs from the intent
- a limit price further than 100 bps from the live mark
- leverage outside the coin’s 1–max range
- a builder field naming any address but the treasury or any fee but the configured one
- an order under $10
lib/hl-batch.ts guardHlBatch refuses:- more than 3 members
- a member whose nonce or shape is not the composed one
app/api/hl/submit/route.ts POST (relay) refuses:- a signature that does not recover to the account the action names
- an action that fails the live re-guard
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
| signingDomainChainId | 1337 |
|---|
| execSlippageBps | 100 |
|---|
| minOrderUsd | 10 |
|---|
| minDepositUsdc | 5 |
|---|
| batchMaxMembers | 3 |
|---|
| builderFeeTenthBps | 100 |
|---|
| builderMinAccountUsd | 100 |
|---|
Notes
- The builder fee (tenths of a bp) pays the treasury and is approved exactly once at exactly that rate.
- Guardians (standing stop-loss / take-profit) run under a delegated agent key that the venue bars from withdrawing.
- Pins kept in the free MCP, not this repo:
free-mcps/services/hyperliquid/lib/tools.ts (read-only) (Pantessa/free-mcps).
Custody: UNMEASURED through custody. The fixed 1337 signing domain, the approveAgent delegation for standing intents and the builder-fee approval are the most custody friction of any venue here; measure a custody signer before promising perps.
NEAR Intents (cross-chain via 1Click)
native builder + free MCPtx-shapedPantessa/website · Pantessa/free-mcps
Chains: Ethereum (1) · Optimism (10) · Robinhood Chain (4663) · Arc (5042) · Base (8453) · Arbitrum (42161). No contract is pinned in this repo for this venue — see the notes for why.
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0xa9059cbb | transfer(address,uint256) | viem#erc20Abi (an ERC-20 deposit is a transfer) |
Operations
- quote (dry run) read — nothing to sign
The 1Click quote: route, delivered amount, the venue’s own share, a one-time deposit address. - swap one transaction
ONE unsigned deposit transfer on the origin chain moving EXACTLY the quoted amount to the quote’s own deposit address; solvers deliver on the destination; settlement is tracked to SUCCESS.
The guard in front of the signature
lib/cross-chain-swap.ts guardCrossChainBuild · checkCrossChainFee · checkRecipient refuses:- a transfer that does not move exactly the quoted amount to the quote’s deposit address (born from a live fabricated-address near-miss, PR #374)
- a built tx whose chainId is not the named origin chain
- a venue share above 100 bps
- an app fee we did not request, to an address we did not pin, or above the bps we asked
- a delivery address that fails the EIP-55 checksum
lib/tx-guardrails.ts recipientCheck · validityCheck · buildReport refuses:- proceeds to any wallet but the requesting one
- anything signable for more than 31 days (MAX_VALID_SEC)
- any block-level check failing → blocked: true → no consumer offers the artifact
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
| venueShareMaxBps | 100 |
|---|
| crossChainFeeBps | 20 |
|---|
| oneClickFeeSplit | 0.5 |
|---|
| confidentialLevel | basic |
|---|
| originChainIds | 1, 10, 56, 100, 137, 4663, 5042, 8453, 42161, 43114, 534352 |
|---|
Notes
- No contract is pinned here by design: the deposit address is per quote and belongs to the venue; the guard pins the AMOUNT and the ADDRESS to the quote it just received, byte for byte.
- Robinhood Chain and Arc inbound redirect to the LiFi funding plan (lib/jobs); outbound builds here.
- Pins kept in the free MCP, not this repo:
free-mcps/services/near-intents/lib/oneclick.ts (Pantessa/free-mcps).
Custody: A single ERC-20 or native transfer; not yet drilled with a custody signer.
LiFi (settlement on Robinhood Chain · the funding bridge)
native builder + guardtx-shapedPantessa/website
Pinned contracts
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0x095ea7b3 | approve(address,uint256) | viem#erc20Abi (exact-amount approval to the router) |
Operations
- swap settlement (Robinhood Chain) a chain of transactions (validUntil + refresh)
Only when v4 has no executable pool (GatedV4PoolError): LiFi’s aggregator calldata, pinned to the per-chain router allowlist, with the approval re-decoded to the exact amount and the fill price-checked against our own quote. - funding bridge leg a chain of transactions (validUntil + refresh)
Moves the user’s own money between chains to fund an ask (no fee on funding legs).
The guard in front of the signature
lib/lifi-venue.ts guardLifiBuild · verifyLifiQuoteEcho · lifiPriceAcceptable refuses:- a target outside the router allowlist for that chain (an empty allowlist = no venue)
- an approval that is not exact-amount to the router
- a fill paying more than 200 bps worse than our quote
- a quote older than 90 seconds
lib/lifi-bridge.ts guardLifiBridgeBuild refuses:- a router outside the bridge allowlist
- a leg that does not deliver to the signer on the destination chain
lib/tx-guardrails.ts recipientCheck · validityCheck · buildReport refuses:- proceeds to any wallet but the requesting one
- anything signable for more than 31 days (MAX_VALID_SEC)
- any block-level check failing → blocked: true → no consumer offers the artifact
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
| maxQuoteShortfallBps | 200 |
|---|
| quoteTtlSec | 90 |
|---|
| legFlatUsd | 0.12 |
|---|
| policyHost | lifi.yeetful.com |
|---|
Notes
- LIFI_ROUTERS / LIFI_BRIDGE_ROUTERS env vars REPLACE the pinned allowlists at runtime; an invalid entry is dropped and an empty result fails closed.
- LiFi price and simulation checks degrade to warnings on RPC transport failure (GUARDRAILS.md, honest residuals).
Custody: Not yet drilled with a custody signer.
OpenSea (Seaport 1.6)
native builder + free MCPtx-shapedfleet · opensea-freePantessa/website · Pantessa/free-mcps
Pinned contracts
Signing domain
| domain | verifyingContract: 0x0000000000000068F116a894984e2DB1123eB395 · conduitKey: 0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000 |
|---|
| primaryType | OrderComponents |
|---|
| fields | OrderComponents, OfferItem, ConsiderationItem |
|---|
| source | lib/opensea.ts#SEAPORT_EIP712_TYPES · OPENSEA_CONDUIT_KEY |
|---|
Operations
- owned · meta · collection read — nothing to sign
The OpenSea API. - list an EIP-712 signature
A Seaport OrderComponents signature riding the pinned conduit key; the only approval ever built is setApprovalForAll to the pinned conduit, on the collection the user is listing. - buy one transaction
The fulfillment is re-encoded LOCALLY against Seaport 1.6 — never forwarded opaque from the API. - transfer one transaction
ERC-721 / ERC-1155 safeTransfer with ownership and recipient verified (guardNftTransfer).
The guard in front of the signature
lib/nft-layer.ts buildNftListing · buildNftBuy · guardNftTransfer refuses:- an order that does not ride the OpenSea conduit
- a fulfillment the local re-encode does not reproduce
- a transfer of a token the signer does not own
app/api/opensea/submit/route.ts POST (relay) refuses:- a signature that does not recover to the claimed offerer over the exact order params
- a payout outside the collection’s LIVE fee schedule
- a target other than Seaport 1.6
- a listing while the account is frozen (a sale is never spend-gated)
lib/tx-guardrails.ts recipientCheck · validityCheck · buildReport refuses:- proceeds to any wallet but the requesting one
- anything signable for more than 31 days (MAX_VALID_SEC)
- any block-level check failing → blocked: true → no consumer offers the artifact
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
Notes
- Inflows (sales) are never spend-gated; the kill switch still refuses a listing.
- Pins kept in the free MCP, not this repo:
free-mcps/services/opensea/lib/registry.ts (Pantessa/free-mcps).
Custody: Not yet drilled with a custody signer.
Snapshot (off-chain governance)
native builder + free MCPtx-shapedfleet · snapshot-freePantessa/website · Pantessa/free-mcps
Signing domain
| domain | name: snapshot · version: 0.1.4 |
|---|
| primaryType | Vote |
|---|
| fields | from:address, space:string, timestamp:uint64, proposal, choice, reason:string, app:string, metadata:string |
|---|
| source | lib/snapshot-vote.ts#SNAPSHOT_VOTE_DOMAIN · buildVoteTypedData |
|---|
Operations
- spaces · proposals · votes read — nothing to sign
The Snapshot hub. - vote an EIP-712 signature
The canonical Vote struct, built here (the MCP’s prepare_vote and the UI buttons produce the identical payload), stamped at build time, relayed to the sequencer. No chain, no contract, no value moves.
The guard in front of the signature
lib/planner-artifact-guard.ts guardPlannerArtifact refuses:- any transaction on a chain outside the app registry
- any call to Permit2 (0x000000000022d473030f116ddee9f6b43ac78ba3) from an external tool
- bare native sends to a third party built by an external tool
- UNLIMITED token approvals
- transferFrom-family calldata and setApprovalForAll from external tools
- any generic EIP-712 order that is not a CoW order verifying against the pinned GPv2 settlement and paying the signer
- a Snapshot vote whose primaryType is not Vote, that carries an on-chain domain, or whose voter is not the requesting wallet
Notes
- Off-chain: a vote signature cannot move funds. The guard still refuses a non-Vote struct behind a governance label and any on-chain domain.
Custody: An off-chain EIP-712 signature; a custody signer that supports typed data can cast it. Not yet drilled.
Robinhood Chain (bridge; tokenized stocks trade via Uniswap v4 above)
native builder + free MCPtx-shapedPantessa/website · Pantessa/free-mcps
Pinned contracts
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0x439370b1 | depositEth() | lib/robinhood-bridge.ts#INBOX_ABI |
| 0x25e16063 | withdrawEth(address) | lib/robinhood-bridge.ts#ARB_SYS_ABI |
Operations
- bridge in one transaction
depositEth() on the pinned Delayed Inbox on Ethereum, value = the asked ETH. - bridge out one transaction
withdrawEth(signer) on the ArbSys precompile on Robinhood Chain (the canonical ~7-day exit; NEAR Intents is the ~30 s exit).
The guard in front of the signature
lib/robinhood-bridge.ts guardRobinhoodBridge refuses:- a deposit not addressed to the pinned inbox on Ethereum
- a withdrawal not addressed to ArbSys on Robinhood Chain
- a destination other than the signer
- a value other than the asked amount
lib/tx-guardrails.ts recipientCheck · validityCheck · buildReport refuses:- proceeds to any wallet but the requesting one
- anything signable for more than 31 days (MAX_VALID_SEC)
- any block-level check failing → blocked: true → no consumer offers the artifact
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Bounds
Notes
- Tokenized stocks (xyz tickers) are swapped through the Uniswap v4 fallback on this chain, settled through LiFi when v4 has no executable pool — see those venues.
- Pins kept in the free MCP, not this repo:
free-mcps/services/robinhood/lib/registry.ts (Pantessa/free-mcps).
Custody: Not yet drilled with a custody signer.
Token sends (the transfer layer)
native builder + guardtx-shapedPantessa/website
Chains: Base (8453) · Ethereum (1) · Arbitrum (42161) · Optimism (10) · Robinhood Chain (4663) · Arc (5042). No contract is pinned in this repo for this venue — see the notes for why.
Selectors a build may emit
| selector | signature | derived from |
|---|
| 0xa9059cbb | transfer(address,uint256) | viem#erc20Abi (encodeFunctionData in lib/transfer-exec.ts) |
Operations
- send native one transaction
A plain value transfer with empty calldata, to the asked recipient only. - send ERC-20 one transaction
transfer(to, amount) on the token the registry (or a raw 0x address the user typed) names; decimals read on-chain.
The guard in front of the signature
lib/transfer-exec.ts buildTransferArtifact (transfer-guard pin) refuses:- calldata that does not re-decode to transfer(asked recipient, asked amount)
- a native send whose to / value / empty-calldata triple does not match the ask
- an opaque payload it cannot decode
lib/tx-guardrails.ts policyCheck (the kill switch) refuses:- every outflow while the account is frozen or revoked (ACCOUNT_FROZEN / REVOKED)
- the build when the gate itself cannot run (POLICY_ERROR, fail-closed)
Notes
- The ONLY layer that may name a third-party recipient; it takes the full (non-exempt) policy gate. Every other venue returns proceeds to the signer.
Custody: The simplest shape for a custody signer; not yet drilled.
Pantessa Wallet (reads)
free MCPread-onlyfleet · yeetful-tool-walletPantessa/free-mcps
Operations
- portfolio · gas balances · token balance · recent transactions · tx status read — nothing to sign
Multichain reads via Alchemy; spam-filtered; the fresh-data layer after a settlement. Produces nothing signable.
Notes
- Read-only by construction.
- Pins kept in the free MCP, not this repo:
free-mcps/services/yeetful-tool-wallet (Pantessa/free-mcps).
Custody: n/a (no signature).