@continuumdao/ctm-mpc-defi 0.2.62 → 0.2.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/catalog.cjs +329 -79
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +217 -27
- package/dist/agent/catalog.js +325 -80
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/aerodrome/SKILL.md +16 -14
- package/dist/agent/skills/continuum-dao/SKILL.md +2 -2
- package/dist/agent/skills/railgun/SKILL.md +10 -4
- package/dist/agent/skills/yield-compare/SKILL.md +5 -5
- package/dist/index.cjs +5 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aerodrome/index.cjs +476 -282
- package/dist/protocols/evm/aerodrome/index.cjs.map +1 -1
- package/dist/protocols/evm/aerodrome/index.d.ts +38 -13
- package/dist/protocols/evm/aerodrome/index.js +473 -284
- package/dist/protocols/evm/aerodrome/index.js.map +1 -1
- package/dist/protocols/evm/continuum-dao/index.cjs +397 -70
- package/dist/protocols/evm/continuum-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/continuum-dao/index.d.ts +27 -3
- package/dist/protocols/evm/continuum-dao/index.js +398 -71
- package/dist/protocols/evm/continuum-dao/index.js.map +1 -1
- package/dist/protocols/evm/curve-dao/index.cjs +54 -6
- package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/curve-dao/index.js +54 -6
- package/dist/protocols/evm/curve-dao/index.js.map +1 -1
- package/dist/protocols/evm/euler-v2/index.cjs +45 -10
- package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
- package/dist/protocols/evm/euler-v2/index.d.ts +10 -2
- package/dist/protocols/evm/euler-v2/index.js +44 -11
- package/dist/protocols/evm/euler-v2/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: aerodrome
|
|
3
|
-
description: Aerodrome AMM
|
|
3
|
+
description: Aero (formerly Aerodrome) AMM — Metarouter swaps, LP, Slipstream CL, gauges, and MPC multisign. Protocol id stays aerodrome.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Aero (MCP)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Protocol id stays **`aerodrome`**. Tool names stay **`ctm_aerodrome_*`**. Launch chains: **Base `8453` (default)**, Ethereum `1`, OP Mainnet `10`, Arbitrum `42161`, Robinhood Chain `4663`, Arc `5042`, Ink `57073`. Coinbase stock LP is **Base only**. LpSugar pool index is the legacy Base deployment; other chains use factory `getPool` via `ctm_aerodrome_discover_pools`. V2 swaps go through the shared Metarouter.
|
|
9
9
|
|
|
10
|
-
Native ETH in the app and MCP is **`0x0000000000000000000000000000000000000000`**. Map to WETH
|
|
10
|
+
Native ETH in the app and MCP is **`0x0000000000000000000000000000000000000000`**. Map to that chain’s WETH at the router boundary (Base/OP/Ink `0x4200…0006`). Do not pass Curve’s `0xeeee…` placeholder. Arc wrapped native is not wired yet.
|
|
11
11
|
|
|
12
12
|
## Quote first (Coinbase B20 / AAPLc)
|
|
13
13
|
|
|
14
|
-
**Do not** dump LpSugar or paginate factories. `ctm_aerodrome_fetch_pools` and `ctm_aerodrome_fetch_lp_yields` return **at most ~100 important pairs
|
|
14
|
+
**Do not** dump LpSugar or paginate factories. `ctm_aerodrome_fetch_pools` and `ctm_aerodrome_fetch_lp_yields` return **at most ~100 important pairs** from the Base Sugar index (empty on other chains). Optional `query` only shrinks that set. B20 stock LP yields are `ctm_aerodrome_fetch_stock_lp_yields` on Base only. Tickers resolve inside quote / discover.
|
|
15
15
|
|
|
16
16
|
For a price, **call `ctm_aerodrome_quote` immediately**:
|
|
17
17
|
|
|
@@ -20,16 +20,16 @@ ctm_aerodrome_quote({ chainId: 8453, tokenIn: "USDC", tokenOut: "AAPLc", amountH
|
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
- `tokenIn` / `tokenOut` accept **tickers** (`AAPLc`, `USDC`, `ETH`, `WETH`, `AERO`) or 0x addresses. Do **not** ask the user for a B20 contract address.
|
|
23
|
-
- B20 stocks are **8 decimals**. Omit `tokenInDecimals`.
|
|
23
|
+
- B20 stocks are **8 decimals** and **Base only**. Omit `tokenInDecimals`.
|
|
24
24
|
- Quote output includes `amountOutHuman` and `priceImpactPercent` (0–100, vs a tiny same-route probe; `null` if the probe failed). State both before building a swap.
|
|
25
|
-
- To see **which pools exist** for a token (not a price): `ctm_aerodrome_discover_pools({ token: "AAPLc" })` — factory `getPool` vs USDC/WETH/AERO (optional `tokenOut`). Then quote.
|
|
25
|
+
- To see **which pools exist** for a token (not a price): `ctm_aerodrome_discover_pools({ token: "AAPLc", chainId: 8453 })` — factory `getPool` vs USDC/WETH/AERO (optional `tokenOut`). Then quote.
|
|
26
26
|
|
|
27
|
-
Use `get_defi_protocol_supported_tokens` only as a slim ticker list (ETH, USDC, AERO, B20). `issued` for a stock is `totalSupply > 0` on quote/discover (unissued throws).
|
|
27
|
+
Use `get_defi_protocol_supported_tokens` only as a slim ticker list (ETH, USDC, AERO, and B20 on Base). `issued` for a stock is `totalSupply > 0` on quote/discover (unissued throws).
|
|
28
28
|
|
|
29
29
|
## Before writes
|
|
30
30
|
|
|
31
31
|
1. `load_defi_protocol({ protocolId: "aerodrome" })` — activates **market-data** (includes quote)
|
|
32
|
-
2. `get_defi_protocol_supported_chains` — must
|
|
32
|
+
2. `get_defi_protocol_supported_chains` — the chain you pass must be a launch chain with a node `rpcGateway`. Base `8453` is the default, not the only chain.
|
|
33
33
|
3. Writes: `activate_tool_group` with `aerodrome:swap`, `aerodrome:lp`, or `aerodrome:rewards`
|
|
34
34
|
|
|
35
35
|
`aerodrome:trading` expands to swaps + lp + rewards (not market-data).
|
|
@@ -38,7 +38,7 @@ Use `get_defi_protocol_supported_tokens` only as a slim ticker list (ETH, USDC,
|
|
|
38
38
|
|
|
39
39
|
After the quote (include `amountOutHuman` and `priceImpactPercent`), **stop and ask** before any `ctm_aerodrome_build_*_multisign`:
|
|
40
40
|
|
|
41
|
-
1. `get_multi_sign_gas_options({ chainId
|
|
41
|
+
1. `get_multi_sign_gas_options({ chainId })` — same launch chain as the quote. Confirm `useCustomGas` **false** (live RPC, default) vs **true** (Custom Gas Config from the chain registry).
|
|
42
42
|
2. Confirm the **30-minute** multiSignRequest deadline (members must agree, Get Sig, and broadcast before it expires). The on-chain router/NFPM deadline uses the same window. Omit `expiryDate` for 30 minutes; pass `expiryDate` as unix seconds only if they choose a different window.
|
|
43
43
|
|
|
44
44
|
Do not create the request until they confirm both.
|
|
@@ -57,9 +57,11 @@ Do not create the request until they confirm both.
|
|
|
57
57
|
Same as the Multi-Sign Liquidity tab:
|
|
58
58
|
|
|
59
59
|
```
|
|
60
|
-
ctm_aerodrome_quote_add_liquidity({ chainId
|
|
60
|
+
ctm_aerodrome_quote_add_liquidity({ chainId, tokenA: "ETH", tokenB: "USDC", amountAHuman: "0.01" })
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
`chainId` is the launch chain for this request. Base `8453` is the default. Coinbase stock pairs stay on Base.
|
|
64
|
+
|
|
63
65
|
- One-sided: pass **either** `amountAHuman` or `amountBHuman`. The other side is filled from the current vAMM/sAMM reserves, or from Slipstream `slot0` when there is no v2 pool.
|
|
64
66
|
- Tickers work (`AAPLc`, `USDC`, `ETH`). B20 stocks are 8 decimals. Unissued stocks (`totalSupply == 0`) error the same as the dialog.
|
|
65
67
|
- **ETH / Coinbase stock has no pool.** `seedable` is `false` and `hint` tells you to pair the stock vs **USDC**. Do not first-deposit an empty vAMM.
|
|
@@ -84,11 +86,11 @@ Skip emissions when `claimEmissions` is `null` (no gauge). Slipstream unstaked f
|
|
|
84
86
|
|
|
85
87
|
## Addresses
|
|
86
88
|
|
|
87
|
-
|
|
89
|
+
Baked per launch chain from https://app.aero.xyz/docs/security/ (launched 2026-10-22). Do not invent addresses. Pass the chain the user is on: Base `8453` (default), Ethereum `1`, OP Mainnet `10`, Arbitrum `42161`, Robinhood Chain `4663`, Arc `5042`, or Ink `57073`.
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
V2 swaps use the shared Metarouter on every launch chain. On Base, v2 add-liquidity still quotes the legacy router. Other chains do not encode v2 add-liquidity yet. LpSugar is the Base pool index only. Arc has no known WETH or USDC. The tracked token is new AERO on Base and xAERO on the other launch chains.
|
|
90
92
|
|
|
91
|
-
Coinbase B20 stocks (AAPLc, NVDAc, PYPLc, AMDc, ORCLc, BRK.Bc, …) trade on **Slipstream 3** (`clFactory3`) vs USDC. Tickers resolve from the live Coinbase tokenized-stocks API. There is no baked-in address list. Pass the ticker — do not ask for a contract address. Stock-backed **loans** (lend/borrow USDC against B20 collateral) are Morpho — `load_defi_protocol morpho` and `ctm_morpho_fetch_stock_markets`, not
|
|
93
|
+
Coinbase B20 stocks (AAPLc, NVDAc, PYPLc, AMDc, ORCLc, BRK.Bc, …) stay on **Base only** and trade on **Slipstream 3** (`clFactory3`) vs USDC. Tickers resolve from the live Coinbase tokenized-stocks API. There is no baked-in address list. Pass the ticker — do not ask for a contract address. Stock-backed **loans** (lend/borrow USDC against B20 collateral) are Morpho — `load_defi_protocol morpho` and `ctm_morpho_fetch_stock_markets`, not Aero LP. Sugar tokens whose address uses the B20 ASSET prefix `0xb200…` are also treated as stocks. `issued` is live `totalSupply() > 0`. Quotes use factory `getPool` discovery + MixedRouteQuoterV3 (path bitmasks). Sugar `forSwaps` alone misses these pools. Native ETH → stock is typically WETH → USDC → stock.
|
|
92
94
|
|
|
93
95
|
## Out of scope
|
|
94
96
|
|
|
@@ -67,7 +67,7 @@ When a proposal has a `forumKey`, fetch that thread (`ctm_continuum_dao_forum_re
|
|
|
67
67
|
1. `get_forum_session` then `forum_me`. If `loggedIn`, reuse the ticket. Only if there is no session or `loggedIn` is false: `forum_sign_in_eligible` then `build_forum_sign_in_multisign`. Pass `address` on forum writes so the tool loads that node session before posting.
|
|
68
68
|
2. If it is only an idea: `forum_create_idea`. Stop (no propose).
|
|
69
69
|
3. If it is a proposal: `forum_create_topic` with the matching Governance `section` (proposal-threshold veCTM). Keep the returned `url`.
|
|
70
|
-
4. Compose actions with `ctm_continuum_dao_compose_proposal_action` (prefer ABI from `etherscan__get_contract_abi` with chainid 59144/59141, type-check values, preview table). Then offer `ctm_continuum_dao_simulate_proposal` — pass `account` for another EOA, or `keyGenId` / omit `account` for the preferred KeyGen. Write `foundry.files` and run `foundry__forge_script` on a Linea fork with no `--broadcast
|
|
70
|
+
4. Compose actions with `ctm_continuum_dao_compose_proposal_action` (prefer ABI from `etherscan__get_contract_abi` with chainid 59144/59141, type-check values, preview table). Then offer `ctm_continuum_dao_simulate_proposal` — pass `account` for another EOA, or `keyGenId` / omit `account` for the preferred KeyGen. Write each `foundry.files` source unchanged (`abi.encodeCall` on the function signature, not raw hex calldata) and run `foundry__forge_script` on a Linea fork with no `--broadcast` until every file has a result. Isolated `eth_call` is not success. Stop if `ok` is false or a forge script reverts, and quote the bubbled revert.
|
|
71
71
|
5. `build_propose_bravo_multisign` or `build_propose_delta_multisign` with that `url` as `forumKey`, plus `description` and `type` (KeyGen submit only). The tool writes the governance catalog, then submits the multi-sign request. It refuses a reverting `propose()` or (when the RPC supports it) sequential `eth_simulateV1` execute. Sequential execute still requires the forge scripts above.
|
|
72
72
|
6. If the catalog POST failed, retry with `register_proposal` and the same `forumKey`, `description`, `type`, input names, and `onchainId`. A 409 updates the existing row. Do not create a second propose.
|
|
73
73
|
|
|
@@ -84,7 +84,7 @@ Forum sign-in and sign-out are **agent/MCP only**. There is no Sign in / Sign ou
|
|
|
84
84
|
|
|
85
85
|
Propose builders **hard-fail** if `getVotes(KeyGen) <` live `proposalThreshold()` — no sign request is created. On-chain rule (vectm `ContinuumDAO`): `max(1000 ether, 1% of past total voting power)`. Do not hardcode `1000`. The standalone simulate tool only **warns** when a different `account` is short.
|
|
86
86
|
|
|
87
|
-
`build_propose_*` dry-runs `propose()` from the preferred signer KeyGen and refuses a revert or a short `getVotes`. `ctm_continuum_dao_simulate_proposal` is the same voting-power + `propose()` dry-run for a **different** `account` (draft / committee EOA) without submitting. It always reads `getVotes(account)` vs live `proposalThreshold()`; if the address is short, the result includes `warning` — read that aloud (Committee is not exempt). Both paths return `foundry.files`: a propose script (prank the proposer) and sequential execute scripts (prank the governor; no timelock). Bravo is one execute script; Delta is one file per option. Later actions in the same `run()` see earlier state. Isolated `eth_call` / `cast call` cannot do that. `forumKey` is not required on the standalone simulate tool.
|
|
87
|
+
`build_propose_*` dry-runs `propose()` from the preferred signer KeyGen and refuses a revert or a short `getVotes`. `ctm_continuum_dao_simulate_proposal` is the same voting-power + `propose()` dry-run for a **different** `account` (draft / committee EOA) without submitting. It always reads `getVotes(account)` vs live `proposalThreshold()`; if the address is short, the result includes `warning` — read that aloud (Committee is not exempt). Both paths return `foundry.files`: a propose script (prank the proposer) and sequential execute scripts (prank the governor; no timelock). Each action is `abi.encodeCall` on its Solidity signature. Write that source unchanged and finish `foundry__forge_script` (no `--broadcast`) for every file in the same turn; quote a bubbled revert and stop. Bravo is one execute script; Delta is one file per option. Later actions in the same `run()` see earlier state. Isolated `eth_call` / `cast call` cannot do that. `forumKey` is not required on the standalone simulate tool.
|
|
88
88
|
|
|
89
89
|
## Tools
|
|
90
90
|
|
|
@@ -19,16 +19,21 @@ The 0zk address and its balances are stored on the KeyGen record. Each node hold
|
|
|
19
19
|
| Public tokens that show the Railgun icon | `ctm_railgun_fetch_popular_assets` |
|
|
20
20
|
| This KeyGen's shielded balances | `ctm_railgun_fetch_private_balances` |
|
|
21
21
|
| Shield a public ERC-20 into the 0zk address | `ctm_railgun_build_shield_multisign` |
|
|
22
|
+
| Shield the chain’s native gas by wrapping it first | `ctm_railgun_build_shield_multisign` with `wrapNative` and the wrapped token address |
|
|
23
|
+
| Unwrap the wrapped gas token back to native gas | `ctm_railgun_build_unwrap_multisign` |
|
|
22
24
|
| Quote the shield, transfer, or unshield fee | `ctm_railgun_fee_quote` |
|
|
25
|
+
| List broadcasters before a private transfer or unshield is executed | `ctm_railgun_list_broadcasters` |
|
|
23
26
|
| Start a private transfer | `ctm_railgun_private_transfer` |
|
|
24
27
|
| Start an unshield to a public address | `ctm_railgun_unshield` |
|
|
25
28
|
| Agree or reject a pending spend from Join, node chat, or Telegram | `list_sign_requests_awaiting_join`, then `sign_request_agree` |
|
|
26
|
-
|
|
|
29
|
+
| Choose a broadcaster and execute a private transfer or unshield | `ctm_railgun_list_broadcasters`, then `broadcast_sign_result` with the `RailgunSpend:` id. No Get Sig |
|
|
30
|
+
| Shelve a private transfer or unshield that is ready or failed | `shelve_sign_request` with the `RailgunSpend:` id |
|
|
31
|
+
| History of private transfers and unshields | `ctm_railgun_list_spends` |
|
|
27
32
|
| Agree this node's share when the spend id is already known | `ctm_railgun_agree_spend` |
|
|
28
33
|
|
|
29
34
|
Call `ctm_railgun_fee_quote` before a shield, private transfer, or unshield, and tell the user the fee. Shield and unshield take a Railgun percentage from the amount. A private transfer has no protocol fee. Unshield and private transfer also take a broadcaster fee from the private balance. `purpose` on a private transfer or unshield, and `purposeText` on a shield, is the Purpose shown on Join. `thoughts` on `sign_request_agree` or `ctm_railgun_agree_spend` is stored on the Railgun spend the same way as on a normal sign request.
|
|
30
35
|
|
|
31
|
-
Call `ctm_railgun_ensure_wallet` first. Use the returned `railgunAddress` as the shield recipient. Call `ctm_railgun_fetch_private_balances` before an unshield or private transfer. Pass `refresh: true` when the stored scan may be stale. If `walletConfigured` is false, call `ctm_railgun_ensure_wallet` and then fetch again.
|
|
36
|
+
Omit `keyGenId` to use the node preferred KeyGen. Call `ctm_railgun_ensure_wallet` first. Use the returned `railgunAddress` as the shield recipient. `ctm_railgun_fetch_popular_assets` does not take a KeyGen. Call `ctm_railgun_fetch_private_balances` before an unshield or private transfer. Pass `refresh: true` when the stored scan may be stale. If `walletConfigured` is false, call `ctm_railgun_ensure_wallet` and then fetch again.
|
|
32
37
|
|
|
33
38
|
`ctm_railgun_fetch_popular_assets` is the public icon list, not the shielded holdings.
|
|
34
39
|
|
|
@@ -36,13 +41,14 @@ Call `ctm_railgun_ensure_wallet` first. Use the returned `railgunAddress` as the
|
|
|
36
41
|
|
|
37
42
|
`ctm_railgun_ensure_wallet` returns `shieldSignature` when this KeyGen already has one. Do not pass `shieldSignature` into `ctm_railgun_build_shield_multisign`. The server reads it from the KeyGen.
|
|
38
43
|
|
|
39
|
-
1. Call `ctm_railgun_build_shield_multisign` with the amount and the 0zk address from `ctm_railgun_ensure_wallet`. If a shield key is stored, this submits the approve-and-shield transaction.
|
|
44
|
+
1. Call `ctm_railgun_build_shield_multisign` with the amount and the 0zk address from `ctm_railgun_ensure_wallet`. If a shield key is stored, this submits the approve-and-shield transaction. To shield the chain’s native gas, set `wrapNative` and pass the wrapped gas token as `tokenAddress`. That deposits native gas into the wrapped token, then shields it.
|
|
40
45
|
2. If no shield key is stored, the call returns a personal_sign. Submit it with `sign_request_agree`, then `trigger_sign_result`. The signature is stored on the KeyGen. Call `ctm_railgun_build_shield_multisign` again with the same amount and 0zk address. Do not pass `shieldSignature`.
|
|
46
|
+
3. `ctm_railgun_build_unwrap_multisign` withdraws that wrapped token back to native gas. It is a normal sign request: `sign_request_agree`, `trigger_sign_result`, then `broadcast_sign_result`. It does not spend the 0zk wallet.
|
|
41
47
|
|
|
42
48
|
The personal_sign is only of the text `RAILGUN_SHIELD`. It does not contain the amount. If allowance is short, the shield call includes an approve, and a zero-approve reset when a non-zero allowance is still too small. Shielding spends the KeyGen threshold key, not the 0zk spending key.
|
|
43
49
|
|
|
44
50
|
## Private transfer and unshield
|
|
45
51
|
|
|
46
|
-
A private transfer is signed with this node's management key before the spend is stored. An unshield is signed with this node's management key the same way. These start a pending spend and agree this node's share. The response is `pending` until `approvals` reaches `quorum`. The same spend appears on the other KeyGen nodes in `list_sign_requests_awaiting_join` with `agreementKind: railgun_spend`. When an operator asks whether any sign requests are pending, in node chat or Telegram, include those rows. Show the asset, `amountWei` in base units, the destination address, the memo, the proposal time, and the deadline. Agree or reject with `sign_request_agree` and the row's `requestId` (`RailgunSpend:<keyGenId>:<spendId>`). `accept: false` rejects it. Do not call `trigger_sign_result`. `ctm_railgun_agree_spend` is the same agree when the keyGen id and spend id are already known. When the quorum is reached, the spend leaves Join and appears on the originator's Execute tab, and in `list_sign_requests_ready` on that node. The originator executes it with `broadcast_sign_result` and that same requestId.
|
|
52
|
+
A private transfer is signed with this node's management key before the spend is stored. An unshield is signed with this node's management key the same way. These start a pending spend and agree this node's share. The response is `pending` until `approvals` reaches `quorum`. The same spend appears on the other KeyGen nodes in `list_sign_requests_awaiting_join` with `agreementKind: railgun_spend`. When an operator asks whether any sign requests are pending, in node chat or Telegram, include those rows. Show the asset, `amountWei` in base units, the destination address, the memo, the proposal time, and the deadline. Agree or reject with `sign_request_agree` and the row's `requestId` (`RailgunSpend:<keyGenId>:<spendId>`). `accept: false` rejects it. Do not call `trigger_sign_result`. `ctm_railgun_agree_spend` is the same agree when the keyGen id and spend id are already known. When the quorum is reached, the spend leaves Join and appears on the originator's Execute tab, and in `list_sign_requests_ready` on that node. The originator executes it with `broadcast_sign_result` and that same requestId. Immediately before that, call `ctm_railgun_list_broadcasters` with the row's chain, token, and kind (`unshield` or `transfer`). Tell the user the ratios. Pass the chosen `feesId` as `broadcasterFeesId` and `railgunAddress` as `broadcasterAddress`. The `recommended` row is the cheapest fee ratio that is at least 1:1. Omit both fields to use that row. A cheaper ratio is a discount the broadcaster may refuse; do not pick one unless the user asks for it. There is no Get Sig step. Shelve a ready or failed spend with `shelve_sign_request` and the same requestId. `ctm_railgun_list_spends` is the History list: executed, failed, rejected, shelved, and expired, plus anything still pending. Automated jobs must skip `agreementKind: railgun_spend`. A later balance scan shows the result. Unshield defaults the recipient to the KeyGen Ethereum address.
|
|
47
53
|
|
|
48
54
|
A private transfer to a contact uses `toContactName` on `ctm_railgun_private_transfer`. That reads `railgunAddress` from the address book, not the contact’s Ethereum `address`. If the contact has no 0zk address, say so and do not invent one. Save one with `add_to_address_book_registry` on an Ethereum contact that is not a contract. Pass `railgunAddress` as an empty string to clear it. `remove_from_address_book_registry` removes the contact, including its 0zk address.
|
|
@@ -17,7 +17,7 @@ For **USDC / USDT**, the authored plan notes **must** mention Morpho stock-backe
|
|
|
17
17
|
|
|
18
18
|
For **USDC / USDT**, plan notes **must** also mention Hyperliquid Core lend as an **optional extra**: supply USDC/USDT0 on HyperCore to earn utilization **APR** (`ctm_hyperliquid_fetch_lend_markets`); HYPE/UBTC collateral earns nothing. Do **not** add a Hyperliquid Execute workstream or call `ctm_hyperliquid_fetch_lend_markets` unless the operator says yes or already asked about Hyperliquid / HL lend / Core lending. That leaf is research-only (`toolGroups: ["defi_discovery", "defi:hyperliquid:lend", "keygen", "keygen_messaging"]`) — report quote-token `supplyYearlyRate` as **APR** plus `borrowYearlyRate` as context; skip collateral rows; category `idle`. Do not treat Core lend as vault APR or perp funding.
|
|
19
19
|
|
|
20
|
-
Each Execute protocol leaf must list `toolGroups: ["defi_discovery", "defi:<protocol>:market-data", "keygen", "keygen_messaging"]` (canonical ids: `aave-v4`, `compound-v3`, `euler-v2`, `morpho`, `maple-syrup`, `curve-dao`, `aerodrome`, `pendle`) and `budget: { maxRounds: 16, maxWallClockMs: 240000 }`. Slim leaves cannot search/activate packs — without `defi_discovery` they never see `load_defi_protocol` or official `ctm_*` fetch tools. Do **not** use `agent_bash` / `agent_read_file` / `agent_grep` on a yield leaf — call the official fetch (`ctm_aave_v4_fetch_markets`, `ctm_compound_v3_fetch_markets`, `ctm_morpho_fetch_earn_vaults`, `ctm_morpho_fetch_blue_markets` with `loan: "USDC"` / `"USDT"`, `ctm_aerodrome_fetch_lp_yields` on Base `8453`, `ctm_pendle_fetch_markets` / `ctm_pendle_search_assets`, …) then post `mpc-task-result`. Ticker filters (`underlying: "USDT"`, Morpho `loan: "USDC"`) are valid on Aave/Maple/Morpho fetches — do not invent ERC-20 addresses. Morpho leaf: report vault `netApy` and Blue `netSupplyApyLabel`; footnote `rewards[]` as variable extras — do not add them on top of net APY a second time. Skip empty Blue books (no supply TVL). `ctm_morpho_fetch_stock_markets` only after the operator says yes. Aave v4 is Ethereum-first (`1`; also 10 / 43114). Maple is Ethereum (`1`). Aerodrome is Base (`8453`) only. Pendle is any Core `chainId` ∩ node registry — research-only fetch, no build.
|
|
20
|
+
Each Execute protocol leaf must list `toolGroups: ["defi_discovery", "defi:<protocol>:market-data", "keygen", "keygen_messaging"]` (canonical ids: `aave-v4`, `compound-v3`, `euler-v2`, `morpho`, `maple-syrup`, `curve-dao`, `aerodrome`, `pendle`) and `budget: { maxRounds: 16, maxWallClockMs: 240000 }`. Slim leaves cannot search/activate packs — without `defi_discovery` they never see `load_defi_protocol` or official `ctm_*` fetch tools. Do **not** use `agent_bash` / `agent_read_file` / `agent_grep` on a yield leaf — call the official fetch (`ctm_aave_v4_fetch_markets`, `ctm_compound_v3_fetch_markets`, `ctm_morpho_fetch_earn_vaults`, `ctm_morpho_fetch_blue_markets` with `loan: "USDC"` / `"USDT"`, `ctm_aerodrome_fetch_lp_yields` on an Aero launch chain (protocol id `aerodrome`; Base `8453` default, also `1`, `10`, `42161`, `4663`, `5042`, `57073`; Sugar APR is the Base index), `ctm_pendle_fetch_markets` / `ctm_pendle_search_assets`, …) then post `mpc-task-result`. Ticker filters (`underlying: "USDT"`, Morpho `loan: "USDC"`, Euler `underlyingAddress: "USDC"`) are valid on Aave/Maple/Morpho/Euler fetches — do not invent ERC-20 addresses. Euler resolves the ticker from that chain's vault catalog. Morpho leaf: report vault `netApy` and Blue `netSupplyApyLabel`; footnote `rewards[]` as variable extras — do not add them on top of net APY a second time. Skip empty Blue books (no supply TVL). `ctm_morpho_fetch_stock_markets` only after the operator says yes. Aave v4 is Ethereum-first (`1`; also 10 / 43114). Maple is Ethereum (`1`). Aerodrome is Base (`8453`) only. Pendle is any Core `chainId` ∩ node registry — research-only fetch, no build.
|
|
21
21
|
|
|
22
22
|
## Units and caveats
|
|
23
23
|
|
|
@@ -43,14 +43,14 @@ Call `get_defi_protocol_skill({ protocolId: "yield-compare" })` for this map, th
|
|
|
43
43
|
2. `ctm_aave_v4_fetch_markets` / `ctm_compound_v3_fetch_markets` / `ctm_euler_v2_fetch_lend_vaults` / `ctm_morpho_fetch_earn_vaults` (WETH)
|
|
44
44
|
3. `ctm_gmx_fetch_gm_apy` — GM ETH-sided (Arbitrum) **only if they asked about GMX / GM / LP**
|
|
45
45
|
4. `ctm_curve_dao_fetch_lp_yields` — ETH/stETH-style pools in the ~100 catalog
|
|
46
|
-
5. `ctm_aerodrome_fetch_lp_yields` —
|
|
46
|
+
5. `ctm_aerodrome_fetch_lp_yields` — Aero LP (protocol id `aerodrome`) on Base `8453` by default, and on Ethereum `1`, OP Mainnet `10`, Arbitrum `42161`, Robinhood `4663`, Arc `5042`, Ink `57073`. Sugar emissions APR is the Base index; other chains may return an empty list, then use `ctm_aerodrome_discover_pools`.
|
|
47
47
|
6. `ctm_pendle_fetch_markets` / `ctm_pendle_search_assets` — optional PT / YT / LP implied APY (research-only; no build)
|
|
48
48
|
7. Perp funding / HL vaults — **only if they asked** (see Perp funding)
|
|
49
49
|
|
|
50
50
|
### USDC / USDT
|
|
51
51
|
|
|
52
52
|
1. Aave / Compound / Euler lend / Morpho earn (`ctm_morpho_fetch_earn_vaults`) / Morpho Blue loan markets (`ctm_morpho_fetch_blue_markets({ loan: "USDC" })`) / Maple (`ctm_maple_fetch_markets`). Morpho: rank on `netApy` / `netSupplyApyLabel`; footnote `rewards[]` as variable extras.
|
|
53
|
-
2. `ctm_aerodrome_fetch_lp_yields` (Base) and `ctm_curve_dao_fetch_lp_yields` if they want DEX LP
|
|
53
|
+
2. `ctm_aerodrome_fetch_lp_yields` (Aero launch chains, Base default) and `ctm_curve_dao_fetch_lp_yields` if they want DEX LP
|
|
54
54
|
3. `ctm_pendle_fetch_markets` — optional PT / YT / LP implied APY if they asked about Pendle (research-only)
|
|
55
55
|
4. `ctm_gmx_fetch_gm_apy` / `ctm_hyperliquid_fetch_vault_apys` / perp funding — **only if they asked** about GMX, HL vaults, or funding
|
|
56
56
|
5. Morpho stock-backed USDC loans — **optional extra in plan notes only**. Call `ctm_morpho_fetch_stock_markets` only if they say yes.
|
|
@@ -77,8 +77,8 @@ Aave / Morpho / Euler / `ctm_curve_dao_fetch_lp_yields`
|
|
|
77
77
|
|
|
78
78
|
## DEX / stocks
|
|
79
79
|
|
|
80
|
-
- Main-pair LP only:
|
|
81
|
-
- Stock LP: `ctm_aerodrome_fetch_stock_lp_yields` (B20) **only if the user asked about stocks**.
|
|
80
|
+
- Main-pair LP only: Aero `ctm_aerodrome_fetch_lp_yields` (protocol id `aerodrome`; launch chains above, Base default), Curve `fetch_lp_yields` (~100 each). Optional Pendle LP implied APY via `ctm_pendle_fetch_markets` (research-only).
|
|
81
|
+
- Stock LP: `ctm_aerodrome_fetch_stock_lp_yields` (B20, Base `8453` only) **only if the user asked about stocks**.
|
|
82
82
|
- Morpho stock-backed loans: `ctm_morpho_fetch_stock_markets` **only after they say yes** (or already asked about stocks / stock-backed loans). Isolated equity credit, not idle stables. Always mention as an optional extra in USDC/USDT Best Yield plan notes.
|
|
83
83
|
- Hyperliquid HIP-3: `ctm_hyperliquid_fetch_stock_markets` is **trading**, not idle savings. Include HIP-3 **funding** only if they asked about stocks.
|
|
84
84
|
|
package/dist/index.cjs
CHANGED
|
@@ -171,13 +171,14 @@ var init_coinbaseB20 = __esm({
|
|
|
171
171
|
});
|
|
172
172
|
function isAerodromeChainSupported(chainId) {
|
|
173
173
|
const n = typeof chainId === "number" ? chainId : Number.parseInt(String(chainId), 10);
|
|
174
|
-
return n
|
|
174
|
+
return AERO_CHAIN_IDS.includes(n);
|
|
175
175
|
}
|
|
176
|
-
var AERODROME_PROTOCOL_ID, AERODROME_CHAIN_ID, AERODROME_WETH_BASE, AERODROME_USDC_BASE;
|
|
176
|
+
var AERODROME_PROTOCOL_ID, AERODROME_CHAIN_ID, AERO_CHAIN_IDS, AERODROME_WETH_BASE, AERODROME_USDC_BASE;
|
|
177
177
|
var init_support = __esm({
|
|
178
178
|
"src/protocols/evm/aerodrome/support.ts"() {
|
|
179
179
|
AERODROME_PROTOCOL_ID = "aerodrome";
|
|
180
180
|
AERODROME_CHAIN_ID = 8453;
|
|
181
|
+
AERO_CHAIN_IDS = [8453, 1, 10, 42161, 4663, 5042, 57073];
|
|
181
182
|
AERODROME_WETH_BASE = "0x4200000000000000000000000000000000000006";
|
|
182
183
|
AERODROME_USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
183
184
|
}
|
|
@@ -3767,10 +3768,10 @@ var aerodromeProtocolModule = {
|
|
|
3767
3768
|
id: "aerodrome.quote",
|
|
3768
3769
|
protocolId: AERODROME_PROTOCOL_ID,
|
|
3769
3770
|
chainCategory: "evm",
|
|
3770
|
-
description: "Quote an
|
|
3771
|
+
description: "Quote an Aero swap (protocol id aerodrome) via factory discovery and pool getAmountOut / Metaquoter. Base 8453 by default; also Ethereum, OP Mainnet, Arbitrum, Robinhood, Arc, and Ink. Tickers (AAPLc, USDC, ETH) accepted. Stock tickers are Base only.",
|
|
3771
3772
|
commonParams: [],
|
|
3772
3773
|
params: {
|
|
3773
|
-
chainId: { type: "number", required: true, description:
|
|
3774
|
+
chainId: { type: "number", required: true, description: "Aero chain: 8453 (Base, default), 1, 10, 42161, 4663, 5042, or 57073." },
|
|
3774
3775
|
tokenIn: { type: "address", required: true, description: "Ticker (AAPLc, USDC, ETH, WETH, AERO) or 0x / 0x0 native" },
|
|
3775
3776
|
tokenOut: { type: "address", required: true, description: "Ticker (AAPLc, USDC, ETH, WETH, AERO) or 0x / 0x0 native" },
|
|
3776
3777
|
amountHuman: { type: "string", required: true, description: "Human-readable input amount (B20 stocks are 8 decimals)" }
|