@anywalletkit/protocol-swap2-curve 0.0.0-stage → 0.1.0
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/LICENSE +202 -0
- package/README.md +118 -2
- package/dist/activity.cjs +196 -0
- package/dist/activity.cjs.map +1 -0
- package/dist/activity.d.cts +15 -0
- package/dist/activity.d.ts +15 -0
- package/dist/activity.js +9 -0
- package/dist/activity.js.map +1 -0
- package/dist/chunk-FICPW2P2.js +864 -0
- package/dist/chunk-FICPW2P2.js.map +1 -0
- package/dist/chunk-IIPLIHNY.js +38 -0
- package/dist/chunk-IIPLIHNY.js.map +1 -0
- package/dist/chunk-RVBZFCRR.js +225 -0
- package/dist/chunk-RVBZFCRR.js.map +1 -0
- package/dist/deployments-D4pk2tPy.d.cts +73 -0
- package/dist/deployments-D4pk2tPy.d.ts +73 -0
- package/dist/index.cjs +1129 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +390 -0
- package/dist/index.d.ts +390 -0
- package/dist/index.js +115 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.cjs +1031 -0
- package/dist/protocol.cjs.map +1 -0
- package/dist/protocol.d.cts +21 -0
- package/dist/protocol.d.ts +21 -0
- package/dist/protocol.js +9 -0
- package/dist/protocol.js.map +1 -0
- package/dist/provider-1aJhLz2H.d.ts +61 -0
- package/dist/provider-B_n93qi8.d.cts +61 -0
- package/dist/provider.cjs +1006 -0
- package/dist/provider.cjs.map +1 -0
- package/dist/provider.d.cts +4 -0
- package/dist/provider.d.ts +4 -0
- package/dist/provider.js +8 -0
- package/dist/provider.js.map +1 -0
- package/module.json +23 -0
- package/package.json +78 -3
|
@@ -0,0 +1,864 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ADDRESS_PROVIDER_ABI,
|
|
3
|
+
COINS_INT,
|
|
4
|
+
COINS_UINT,
|
|
5
|
+
CURVE_DENIED_POOLS,
|
|
6
|
+
CURVE_DEPLOYMENTS,
|
|
7
|
+
EXCHANGE_SELECTOR,
|
|
8
|
+
MAX_ROUTE_POOLS,
|
|
9
|
+
MAX_ROUTE_STEPS,
|
|
10
|
+
VERSION_ABI,
|
|
11
|
+
ZERO_ADDRESS,
|
|
12
|
+
chainIdOf,
|
|
13
|
+
decodeExchange,
|
|
14
|
+
deploymentOf,
|
|
15
|
+
describeCurveActivity,
|
|
16
|
+
encodeExchange,
|
|
17
|
+
encodeGetDy
|
|
18
|
+
} from "./chunk-RVBZFCRR.js";
|
|
19
|
+
|
|
20
|
+
// src/provider.ts
|
|
21
|
+
import { getAddress as getAddress2 } from "viem";
|
|
22
|
+
import { evmRef, isEvm, sourceAssetOf as sourceAssetOf3 } from "@anywalletkit/protocol-swap2-core/util";
|
|
23
|
+
|
|
24
|
+
// src/pools/1.ts
|
|
25
|
+
var POOLS_1 = {
|
|
26
|
+
chainId: 1,
|
|
27
|
+
builtAt: "2026-11-05",
|
|
28
|
+
block: 26350656,
|
|
29
|
+
pools: [
|
|
30
|
+
{ address: "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7", name: "Curve.fi DAI/USDC/USDT", coins: ["0x6B175474E89094C44Da98b954EedeAC495271d0F", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], decimals: [18, 6, 6], poolType: 1, swapTypes: [1], codeHash: "0x954a1e212c557c85043985931498ffa3e2fcbe7dfe9cd61513f36eb47d6f4dfc", tvlUsd: 161890942, createdAt: 1599422178 },
|
|
31
|
+
{ address: "0xDC24316b9AE028F1497c275EB9192a3Ea0f67022", name: "Curve.fi ETH/stETH", coins: ["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84"], decimals: [18, 18], poolType: 1, swapTypes: [1], codeHash: "0xe2c45ce8268580c40b4c12c574f8a210375ab92998c1555451fef63630e96b35", tvlUsd: 85454194, createdAt: 1609827515 },
|
|
32
|
+
{ address: "0x862CB4E988FB66E72f128d1183829f8c05B6c6A0", name: "Yield Basis cbBTC", coins: ["0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E", "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf"], decimals: [18, 8], poolType: 20, swapTypes: [1], codeHash: "0xd19e3a232367411c825df98165c95898c08e181fe2e0f9211445f48eb4c0dc62", tvlUsd: 54490963, createdAt: 1779393887 },
|
|
33
|
+
{ address: "0x313698667d7FDD6789a9BC70821309ff891E729A", name: "Yield Basis WBTC", coins: ["0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E", "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"], decimals: [18, 8], poolType: 20, swapTypes: [1], codeHash: "0xe4ac67017f888827e6efe22cd8edc37bf562166368f6eb62837bff2e4a4a23e8", tvlUsd: 48858088, createdAt: 1779393875 },
|
|
34
|
+
{ address: "0xD001aE433f254283FeCE51d4ACcE8c53263aa186", name: "RLUSD/USDC", coins: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0x8292Bb45bf1Ee4d140127049757C2E0fF06317eD"], decimals: [6, 18], poolType: 10, swapTypes: [1], codeHash: "0x0e07a882cbde1fe43a2023b573596d0688cd4511bb04cbff49f1d9cceab84888", tvlUsd: 39310146, createdAt: 1734614699 },
|
|
35
|
+
{ address: "0xcc7d5785AD5755B6164e21495E07aDb0Ff11C2A8", name: "OETH/WETH", coins: ["0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], decimals: [18, 18], poolType: 10, swapTypes: [1], codeHash: "0x8b33e4c54cca2b340c5ac61ac287ecd06cfab84979e63c1260683abcc06f8138", tvlUsd: 38072502, createdAt: 1742850227 },
|
|
36
|
+
{ address: "0x4F52C3a81E33521e5a9A47FD9D3BE475D2279c2e", name: "Yield Basis tBTC", coins: ["0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E", "0x18084fbA666a33d37592fA2633fD49a74DD93a88"], decimals: [18, 18], poolType: 20, swapTypes: [1], codeHash: "0xaefafc4c0157bc496db238fc46d730a140174f3fb542527bb86443974ed4f7a6", tvlUsd: 35972318, createdAt: 1779393911 },
|
|
37
|
+
{ address: "0x656341Ef90b622c6634e0573772FfB7f3669b9f3", name: "Yield Basis WETH", coins: ["0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], decimals: [18, 18], poolType: 20, swapTypes: [1], codeHash: "0x116eeee684882885cda3ddf0287d0979f71d64030fbec90f1f52924cf0e7643a", tvlUsd: 29312833, createdAt: 1779393923 },
|
|
38
|
+
{ address: "0x21E27a5E5513D6e65C4f830167390997aA84843a", name: "Curve.fi Factory Pool: stETH-ng", coins: ["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84"], decimals: [18, 18], poolType: 1, swapTypes: [1], codeHash: "0x9e28a09452d2354fc4e15e3244dde27cbc4d52f12a10b91f2ca755b672bfa9be", tvlUsd: 21919007, createdAt: 1684243259 },
|
|
39
|
+
{ address: "0xc061caa073f3d95F80f8e5428d32D2d76F5e1622", name: "USDG/USDC", coins: ["0xe343167631d89B6Ffc58B88d6b7fB0228795491D", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"], decimals: [6, 6], poolType: 10, swapTypes: [1], codeHash: "0x1c7b77a94bb42408ab6d5cfd76223f0c794db9b119bb6035db91d8b09da65512", tvlUsd: 20042556, createdAt: 1757337995 },
|
|
40
|
+
{ address: "0xC2921134073151490193AC7369313c8e0b08e1E7", name: "USDtb-USDC", coins: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xC139190F447e929f090Edeb554D95AbB8b18aC1C"], decimals: [6, 18], poolType: 10, swapTypes: [1], codeHash: "0x003569f063c00de15be2ce5934449342555e009ef7ba9894ef84d302602b186f", tvlUsd: 19974424, createdAt: 1733348927 },
|
|
41
|
+
{ address: "0x83f24023d15d835a213df24fd309c47dAb5BEb32", name: "YB cbBTC", coins: ["0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E", "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf"], decimals: [18, 8], poolType: 20, swapTypes: [1], codeHash: "0xb00ba7467a75fffe15d018cc822a09b282a285f4012f857b19966046b3191b3a", tvlUsd: 17762242, createdAt: 1758723599 },
|
|
42
|
+
{ address: "0x5dc1BF6f1e983C0b21EfB003c105133736fA0743", name: "FRAXUSDe", coins: ["0x853d955aCEf822Db058eb8505911ED77F175b99e", "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3"], decimals: [18, 18], poolType: 10, swapTypes: [1], codeHash: "0x6aa12bb9b18854a3f453e240d7e960190a32f1c16a8e268a90a66c8a95fe3a86", tvlUsd: 16042488, createdAt: 1702770299 },
|
|
43
|
+
{ address: "0x13e12BB0E6A2f1A3d6901a59a9d585e89A6243e1", name: "crvUSD/frxUSD", coins: ["0xCAcd6fd266aF91b8AeD52aCCc382b4e165586E29", "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E"], decimals: [18, 18], poolType: 10, swapTypes: [1], codeHash: "0x6de2b24d7a8852d96955f6873f16402e61b5d9f3aff037f62a2004fecf31ce83", tvlUsd: 13934470, createdAt: 1752006431 },
|
|
44
|
+
{ address: "0x4DEcE678ceceb27446b35C672dC7d61F30bAD69E", name: "Curve.fi Factory Plain Pool: crvUSD/USDC", coins: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E"], decimals: [6, 18], poolType: 1, swapTypes: [1], codeHash: "0x06a0d9fefe2940f35a5e0b347ff8e2f8085c76ce487b5b234b2e3c831160e34f", tvlUsd: 13078629, createdAt: 1684066067 },
|
|
45
|
+
{ address: "0xEd279fDD11cA84bEef15AF5D39BB4d4bEE23F0cA", name: "Curve.fi Factory USD Metapool: Liquity", coins: ["0x5f98805A4E8be255a32880FDeC7F6728C6568bA0", "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490"], decimals: [18, 18], underlying: ["0x5f98805A4E8be255a32880FDeC7F6728C6568bA0", "0x6B175474E89094C44Da98b954EedeAC495271d0F", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], underlyingDecimals: [18, 18, 6, 6], basePool: "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7", poolType: 1, swapTypes: [1, 2], codeHash: "0x156700a4060f3d62786914b50cc60b2b840e6440401bea9a99c0acce0b58beda", tvlUsd: 12967284, createdAt: 1617702355 },
|
|
46
|
+
{ address: "0xf5f5B97624542D72A9E06f04804Bf81baA15e2B4", name: "TricryptoUSDT", coins: ["0xdAC17F958D2ee523a2206206994597C13D831ec7", "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], decimals: [6, 8, 18], poolType: 30, swapTypes: [1], codeHash: "0xe5a06bd0c8f12bc66b551b99a34cdd7d2a286a53b778244c930a8f6db01fef40", tvlUsd: 12898e3, createdAt: 1685482703 },
|
|
47
|
+
{ address: "0x4d9f9D15101EEC665F77210cB999639f760F831E", name: "Curve.fi Factory Plain Pool: stETH/frxETH", coins: ["0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84", "0x5E8422345238F34275888049021821E8E08CAa1f"], decimals: [18, 18], poolType: 1, swapTypes: [1], codeHash: "0x8d287c58712fcd24b18f60f4a77a4a4d1a7a8bd10e3cb4c9d4752296b307aa51", tvlUsd: 12880550, createdAt: 1677059567 },
|
|
48
|
+
{ address: "0x383E6b4437b59fff47B619CBA855CA29342A8559", name: "PayPool", coins: ["0x6c3ea9036406852006290770BEdFcAbA0e23A0e8", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"], decimals: [6, 6], poolType: 10, swapTypes: [1], codeHash: "0x36356aefa486ac281df5aa3efb601b135b95da2c266bc4bf627aa6f4b4b22703", tvlUsd: 12266641, createdAt: 1703113055 },
|
|
49
|
+
{ address: "0xD51a44d3FaE010294C616388b506AcdA1bfAAE46", name: "Curve.fi USD-BTC-ETH", coins: ["0xdAC17F958D2ee523a2206206994597C13D831ec7", "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], decimals: [6, 8, 18], poolType: 3, swapTypes: [1], codeHash: "0x9cb858c1d8e8ab8ba7dc273f146d428965b0ca686d05fb02cb4ffc62149ec928", tvlUsd: 10625171, createdAt: 1626218283 },
|
|
50
|
+
{ address: "0x390f3595bCa2Df7d23783dFd126427CCeb997BF4", name: "Curve.fi Factory Plain Pool: crvUSD/USDT", coins: ["0xdAC17F958D2ee523a2206206994597C13D831ec7", "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E"], decimals: [6, 18], poolType: 1, swapTypes: [1], codeHash: "0x06a0d9fefe2940f35a5e0b347ff8e2f8085c76ce487b5b234b2e3c831160e34f", tvlUsd: 9808682, createdAt: 1684066103 },
|
|
51
|
+
{ address: "0xDB74dfDD3BB46bE8Ce6C33dC9D82777BCFc3dEd5", name: "weETH/WETH-ng", coins: ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee"], decimals: [18, 18], poolType: 10, swapTypes: [1], codeHash: "0xf9b0b2342e2132b069f65bb801081a730df7cf80b2ef5a8b9a3fc7a6324724f3", tvlUsd: 9757307, createdAt: 1713832907 },
|
|
52
|
+
{ address: "0xB7ECB2AA52AA64a717180E030241bC75Cd946726", name: "Curve.fi Factory Plain Pool: tBTC/WBTC", coins: ["0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "0x18084fbA666a33d37592fA2633fD49a74DD93a88"], decimals: [8, 18], poolType: 1, swapTypes: [1], codeHash: "0x06a0d9fefe2940f35a5e0b347ff8e2f8085c76ce487b5b234b2e3c831160e34f", tvlUsd: 8360462, createdAt: 1692136331 },
|
|
53
|
+
{ address: "0x5018BE882DccE5E3F2f3B0913AE2096B9b3fB61f", name: "USDC/fxUSD", coins: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0x085780639CC2cACd35E474e71f4d000e2405d8f6"], decimals: [6, 18], poolType: 10, swapTypes: [1], codeHash: "0x4a0e13c96d5dddf3d9a22d3ad7b65e6735199e857996056cbc4718ef4869bb48", tvlUsd: 7959448, createdAt: 1719632039 },
|
|
54
|
+
{ address: "0xB576491F1E6e5E62f1d8F26062Ee822B40B0E0d4", name: "Curve CVX-ETH", coins: ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B"], decimals: [18, 18], poolType: 2, swapTypes: [1], codeHash: "0x56ba0e921b89ed274e747d68fb8e49ba91fcc6fc4f7c1aaa5294c74b6a4b4d72", tvlUsd: 5926700, createdAt: 1639223635 },
|
|
55
|
+
{ address: "0xEFc6516323FbD28e80B85A497B65A86243a54B3E", name: "BOLD/USDC Pool", coins: ["0x6440f144b7e50D6a8439336510312d2F54beB01D", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"], decimals: [18, 6], poolType: 10, swapTypes: [1], codeHash: "0xd2c72b78d7d96bb962fa6429c4bb2e5dce6d92a5bc6712541ab76fe8e4570f07", tvlUsd: 5611794, createdAt: 1747597079 },
|
|
56
|
+
{ address: "0x7F86Bf177Dd4F3494b841a37e810A34dD56c829B", name: "TricryptoUSDC", coins: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], decimals: [6, 8, 18], poolType: 30, swapTypes: [1], codeHash: "0xffceb70c60b48d7d02df8305161e44ec2454c1bc23fabc528e9a9ec71e4e7806", tvlUsd: 4972786, createdAt: 1685446211 },
|
|
57
|
+
{ address: "0x0Bdb2c3AF83EE1d3196FA64d3162e54624B5f6b0", name: "USAT/USDT", coins: ["0x07041776f5007ACa2A54844F50503a18A72A8b68", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], decimals: [6, 6], poolType: 10, swapTypes: [1], codeHash: "0x9d0252403d580a95341bbddbecea09bbe280bd4d87f28ee8531a01d33119ba01", tvlUsd: 4647056, createdAt: 1772798639 },
|
|
58
|
+
{ address: "0xC09e82f81Cb811DB0922dD48206fc2e212322caf", name: "World Liberty USD1 Pool", coins: ["0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d", "0x4f493B7dE8aAC7d55F71853688b1F7C8F0243C85"], decimals: [18, 18], underlying: ["0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], underlyingDecimals: [18, 6, 6], basePool: "0x4f493B7dE8aAC7d55F71853688b1F7C8F0243C85", poolType: 10, swapTypes: [1, 2], codeHash: "0x25478b25c12a81937ddb75e0c5ed8ca8ab248a102316873d092f49ca870b8cca", tvlUsd: 4343338, createdAt: 1756668467 },
|
|
59
|
+
{ address: "0x9c3B46C0Ceb5B9e304FCd6D88Fc50f7DD24B31Bc", name: "Curve.fi Factory Plain Pool: frxETH/WETH", coins: ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "0x5E8422345238F34275888049021821E8E08CAa1f"], decimals: [18, 18], poolType: 1, swapTypes: [1], codeHash: "0x06a0d9fefe2940f35a5e0b347ff8e2f8085c76ce487b5b234b2e3c831160e34f", tvlUsd: 4279560, createdAt: 1692135095 },
|
|
60
|
+
{ address: "0x4f493B7dE8aAC7d55F71853688b1F7C8F0243C85", name: "Curve.fi Strategic USD Reserves", coins: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], decimals: [6, 6], poolType: 10, swapTypes: [1], codeHash: "0x5f0f1709fa823592ad75b27e32af00a8715d620dcb269be7c26fd5c873c1ce0e", tvlUsd: 4252884, createdAt: 1737825647 },
|
|
61
|
+
{ address: "0x2889302a794dA87fBF1D6Db415C1492194663D13", name: "TricryptoLLAMA", coins: ["0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E", "0x18084fbA666a33d37592fA2633fD49a74DD93a88", "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"], decimals: [18, 18, 18], poolType: 30, swapTypes: [1], codeHash: "0x0c6780573f9c77a247365e2cbeae61fe0af7ea94ded696b5ee5e6462ce51b02e", tvlUsd: 4217439, createdAt: 1686845315 },
|
|
62
|
+
{ address: "0x98a7F18d4E56Cfe84E3D081B40001B3d5bD3eB8B", name: "Curve EURS-USDC", coins: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xdB25f211AB05b1c97D595516F45794528a807ad8"], decimals: [6, 2], poolType: 2, swapTypes: [1], codeHash: "0x6c0b789b9f2ee0cbb53935cbe4f88e7d66401e1b4508514c097e7bd81e8ea931", tvlUsd: 3939896, createdAt: 1635766643 },
|
|
63
|
+
{ address: "0x66039342C66760874047c36943B1e2d8300363BB", name: "HemiBTC/cbBTC/WBTC", coins: ["0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf", "0x06ea695B91700071B161A434fED42D1DcbAD9f00"], decimals: [8, 8, 8], poolType: 10, swapTypes: [1], codeHash: "0x54a9f7fe4f6e0880c3e7f886d1a0500619b0539dd9d9067221a526ece460e6f7", tvlUsd: 3547580, createdAt: 1764180299 },
|
|
64
|
+
{ address: "0xE521BA88837B2726E5343ccA91adA6f19F356C45", name: "USDx/USDT", coins: ["0xa1fA7777974312f7d801A8880714a218F76233f8", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], decimals: [18, 6], poolType: 10, swapTypes: [1], codeHash: "0x74bb764c9dffe15ac160f6d01f6bdc1e4b03d39722083e674476ed6843c11d33", tvlUsd: 3020901, createdAt: 1788328955 },
|
|
65
|
+
{ address: "0x6F63deEDc9870D6c16FC644C6654748352cdc87c", name: "apxUSD-USDC v3", coins: ["0x98A878b1Cd98131B271883B390f68D2c90674665", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"], decimals: [18, 6], poolType: 10, swapTypes: [1], codeHash: "0xe511d7fa636d58614f82e35f2f333d1ed931f75baed8b7b89d2b1ef09825ef26", tvlUsd: 2796538, createdAt: 1785427007 },
|
|
66
|
+
{ address: "0x4eBdF703948ddCEA3B11f675B4D1Fba9d2414A14", name: "TriCRV", coins: ["0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "0xD533a949740bb3306d119CC777fa900bA034cd52"], decimals: [18, 18, 18], poolType: 30, swapTypes: [1], codeHash: "0xf29fb95ca44fe2f979303e309cbaba61d44dd503fddeb111caae94e1b0857154", tvlUsd: 2439038, createdAt: 1690291775 },
|
|
67
|
+
{ address: "0x04710a7B238386Da58EfAd8b65E150e5E17AA522", name: "USDC/sUSDat", coins: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xD166337499E176bbC38a1FBd113Ab144e5bd2Df7"], decimals: [6, 18], poolType: 20, swapTypes: [1], codeHash: "0x11ecb979f7468e539cb2ee92b8cf7c59d56b1c97b9fdce333fe1d35ac5c8e110", tvlUsd: 2187783, createdAt: 1785550511 },
|
|
68
|
+
{ address: "0xE47E8Ced9D94AA43C922627782E29b41a93202AF", name: "FIDD/USDC", coins: ["0x7C135549504245B5eAe64fc0E99Fa5ebabb8e35D", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"], decimals: [18, 6], poolType: 10, swapTypes: [1], codeHash: "0x11743a6ed542b23b65182e0c5a7b7d90b668a189f287b7c0c367b2f910d46c10", tvlUsd: 2074444, createdAt: 1770210611 },
|
|
69
|
+
{ address: "0x8273Cb2cF9AF3228fD14AF25B5B1De2A9676C372", name: "FIDD/USDT", coins: ["0x7C135549504245B5eAe64fc0E99Fa5ebabb8e35D", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], decimals: [18, 6], poolType: 10, swapTypes: [1], codeHash: "0xb1b0592d31b5fc1b46f56ffaecca522725e94a0e56facab038cb92d8b5e0f2e5", tvlUsd: 1750912, createdAt: 1770210935 },
|
|
70
|
+
{ address: "0x839d6bDeDFF886404A6d7a788ef241e4e28F4802", name: "cbBTC/wBTC", coins: ["0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf", "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"], decimals: [8, 8], poolType: 10, swapTypes: [1], codeHash: "0x5270c4f3873d43de1babb9754a903f0de33054dfb7d562c3a3fcadbb8fd3fbca", tvlUsd: 1688187, createdAt: 1725600707 },
|
|
71
|
+
{ address: "0xa4c567c662349BeC3D0fB94C4e7f85bA95E208e4", name: "Curve.fi Factory Plain Pool: msETH/WETH", coins: ["0x64351fC9810aDAd17A690E4e1717Df5e7e085160", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], decimals: [18, 18], poolType: 1, swapTypes: [1], codeHash: "0x148d1345059482faa8834aff0630c9a4b47393df8edf9d99605b8f2f04752f62", tvlUsd: 1672158, createdAt: 1690864487 },
|
|
72
|
+
{ address: "0xbcb91E689114B9Cc865AD7871845C95241Df4105", name: "Curve.fi Factory USD Metapool: PWRD Metapool", coins: ["0xF0a93d4994B3d98Fb5e3A2F90dBc2d69073Cb86b", "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490"], decimals: [18, 18], underlying: ["0xF0a93d4994B3d98Fb5e3A2F90dBc2d69073Cb86b", "0x6B175474E89094C44Da98b954EedeAC495271d0F", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], underlyingDecimals: [18, 18, 6, 6], basePool: "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7", poolType: 1, swapTypes: [1, 2], codeHash: "0xf6083ac638c10e3ca56ad0183f22c4bb24fda0f4c180165327954b3dfae28541", tvlUsd: 1438819, createdAt: 1632839676 },
|
|
73
|
+
{ address: "0x635EF0056A597D13863B73825CcA297236578595", name: "GHO/crvUSD", coins: ["0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f", "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E"], decimals: [18, 18], poolType: 10, swapTypes: [1], codeHash: "0x1517d1f4caa802ab0ddf9032274a7ff3781a1453ef7b278fc63245b492154ce2", tvlUsd: 1377020, createdAt: 1709732591 },
|
|
74
|
+
{ address: "0xC15F285679a1Ef2d25F53D4CbD0265E1D02F2A92", name: "Curve.fi Factory Crypto Pool: FXN/ETH", coins: ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "0x365AccFCa291e7D3914637ABf1F7635dB165Bb09"], decimals: [18, 18], poolType: 2, swapTypes: [1], codeHash: "0x6dfb9f924888fe0d10b50c35ced3f2cf372073a7e524450f1ebe491415db66e0", tvlUsd: 1244529, createdAt: 1695111311 },
|
|
75
|
+
{ address: "0x625E92624Bc2D88619ACCc1788365A69767f6200", name: "pyUSD/crvUSD", coins: ["0x6c3ea9036406852006290770BEdFcAbA0e23A0e8", "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E"], decimals: [6, 18], poolType: 10, swapTypes: [1], codeHash: "0x9c3b1c5ac877c1719736bb325d05eb2806f292776a2121a6f1e8a54d31960dbe", tvlUsd: 1175516, createdAt: 1703109587 },
|
|
76
|
+
{ address: "0xD9FF8396554A0d18B2CFbeC53e1979b7ecCe8373", name: "YB WBTC", coins: ["0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E", "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"], decimals: [18, 8], poolType: 20, swapTypes: [1], codeHash: "0x1578c5a836891e466a1fa5879bc7f0e36bfd9fc625586765541191d8cd3880ae", tvlUsd: 1167762, createdAt: 1758723347 },
|
|
77
|
+
{ address: "0x971add32Ea87f10bD192671630be3BE8A11b8623", name: "Curve.fi Factory Plain Pool: cvxCrv/Crv", coins: ["0xD533a949740bb3306d119CC777fa900bA034cd52", "0x62B9c7356A2Dc64a1969e19C23e4f579F9810Aa7"], decimals: [18, 18], poolType: 1, swapTypes: [1], codeHash: "0x148d1345059482faa8834aff0630c9a4b47393df8edf9d99605b8f2f04752f62", tvlUsd: 1151010, createdAt: 1678280183 },
|
|
78
|
+
{ address: "0xF4d0CF32908b2C7f1021339c43Df0F77f06896d7", name: "USDC/USDat", coins: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0x23238f20b894f29041f48D88eE91131C395Aaa71"], decimals: [6, 6], poolType: 10, swapTypes: [1], codeHash: "0x3c0abdd2996e01d3bff6d4430c231f8dd9f539985066729c28fbb2596ecd6e99", tvlUsd: 1107886, createdAt: 1775403179 },
|
|
79
|
+
{ address: "0x5B03CcCAb7BA3010fA5CAd23746cbf0794938e96", name: "Curve Strategic Ethena Reserves", coins: ["0xdAC17F958D2ee523a2206206994597C13D831ec7", "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3"], decimals: [6, 18], poolType: 10, swapTypes: [1], codeHash: "0xbe6391aadd1d4d306c76728d664997ab7a1ef56c16565ca0d1526050b9c93890", tvlUsd: 1084518, createdAt: 1739457767 },
|
|
80
|
+
{ address: "0x4f062658EaAF2C1ccf8C8e36D6824CDf41167956", name: "Curve.fi GUSD/3Crv", coins: ["0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd", "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490"], decimals: [2, 18], underlying: ["0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd", "0x6B175474E89094C44Da98b954EedeAC495271d0F", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], underlyingDecimals: [2, 18, 6, 6], basePool: "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7", poolType: 1, swapTypes: [1, 2], codeHash: "0xce79330162abf07fc163331f9d9d1553b93dbf509eeafa1215fafa6113c5088e", tvlUsd: 1068354, createdAt: 1602040124 },
|
|
81
|
+
{ address: "0xD6937eA8D33B0C21348F36F7895FdE3054bA4927", name: "frxUSD/USDT", coins: ["0xCAcd6fd266aF91b8AeD52aCCc382b4e165586E29", "0xdAC17F958D2ee523a2206206994597C13D831ec7"], decimals: [18, 6], poolType: 10, swapTypes: [1], codeHash: "0xadf65a4e5ed895c5c85762d0b52d482664f1e26976e8401b39e95cd838e25998", tvlUsd: 1005528, createdAt: 1789499843 }
|
|
82
|
+
]
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// src/pools/10.ts
|
|
86
|
+
var POOLS_10 = {
|
|
87
|
+
chainId: 10,
|
|
88
|
+
builtAt: "2026-11-05",
|
|
89
|
+
block: 159152475,
|
|
90
|
+
pools: [
|
|
91
|
+
{ address: "0xD1b30BA128573fcd7D141C8A987961b40e047BB6", name: "crvUSD/USDT", coins: ["0xC52D7F23a2e460248Db6eE192Cb23dD12bDDCbf6", "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58"], decimals: [18, 6], poolType: 10, swapTypes: [1], codeHash: "0xde251e17bf12e902d51f15ea5c2658888801dbb5f6c5095e226bdb808084bd98", tvlUsd: 250955, createdAt: 1703088383 }
|
|
92
|
+
]
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// src/pools/100.ts
|
|
96
|
+
var POOLS_100 = {
|
|
97
|
+
chainId: 100,
|
|
98
|
+
builtAt: "2026-11-05",
|
|
99
|
+
block: 49126652,
|
|
100
|
+
pools: [
|
|
101
|
+
{ address: "0x7f90122BF0700F9E7e1F688fe926940E8839F353", name: "Curve.fi wxDAI/USDC/USDT", coins: ["0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", "0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83", "0x4ECaBa5870353805a9F068101A40E0f32ed605C6"], decimals: [18, 6, 6], poolType: 1, swapTypes: [1], codeHash: "0x855fc847a134dc1d35593a59c460e334938f53cb115b2befa8174138a1bb3df6", tvlUsd: 447779, createdAt: 1625016390 },
|
|
102
|
+
{ address: "0x0eCEC6F5276d2Ec6bB864F063D2b76393d6A1A74", name: "USDCe/EURe", coins: ["0x2a22f9c3b484c3629090FeED35F17Ff8F88f76F0", "0x420CA0f9B9b604cE0fd9C18EF134C705e5Fa3430"], decimals: [6, 18], poolType: 20, swapTypes: [1], codeHash: "0x0287322b54143499eae6ce611f7895d7f37426f60565a7d1e228dac396ad1a89", tvlUsd: 360118, createdAt: 1786365280 }
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// src/pools/143.ts
|
|
107
|
+
var POOLS_143 = {
|
|
108
|
+
chainId: 143,
|
|
109
|
+
builtAt: "2026-11-05",
|
|
110
|
+
block: 119683641,
|
|
111
|
+
pools: [
|
|
112
|
+
{ address: "0xFd945d71D4E9609a1FAb0aE9c30dA8088E7AEE1E", name: "USDat/USDC", coins: ["0x0Bb150DFa86EA5d7742F07FEfCD8E8edA81D64eF", "0x754704Bc059F8C67012fEd69BC8A327a5aafb603"], decimals: [6, 6], poolType: 10, swapTypes: [1], codeHash: "0xd5d05317249e8e17bd8c67a05048a7115ec719e3f4198ddfa560b7c0b3b620f6", tvlUsd: 2005448, createdAt: 1784210436 },
|
|
113
|
+
{ address: "0x942644106B073E30D72c2C5D7529D5C296ea91ab", name: "3pool", coins: ["0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a", "0x754704Bc059F8C67012fEd69BC8A327a5aafb603", "0xe7cd86e13AC4309349F30B3435a9d337750fC82D"], decimals: [6, 6, 6], poolType: 10, swapTypes: [1], codeHash: "0x93a67dae1693a9327ff151167502f6785ac856025182eebd61150f4e0ea92ffa", tvlUsd: 1442204, createdAt: 1763939652 },
|
|
114
|
+
{ address: "0xD665CaAD68ACb093AFF27eC6c71Ccc4F29c28147", name: "AUSD/trUSD", coins: ["0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a", "0x770a579Ea200784723B31b8668b0773ba80393c9"], decimals: [6, 18], poolType: 10, swapTypes: [1], codeHash: "0xb7af5a0364e252d950458f28c2d14434dd2961cef09ca1e2f90d7b1a96403a00", tvlUsd: 683014, createdAt: 1790778034 }
|
|
115
|
+
]
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// src/pools/196.ts
|
|
119
|
+
var POOLS_196 = {
|
|
120
|
+
chainId: 196,
|
|
121
|
+
builtAt: "2026-11-05",
|
|
122
|
+
block: 75134757,
|
|
123
|
+
pools: [
|
|
124
|
+
{ address: "0x5B3f7F05b79f3cCBe8F33374A578e14dBBb28478", name: "USDC/USDT0", coins: ["0xB6CEceAB302E2E4948951eE7843FC24E92933061", "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"], decimals: [6, 6], poolType: 10, swapTypes: [1], codeHash: "0x78281e9e5a691fe225a5c246be69cc35d48e81f4e1c0bcca178121fa41612961", tvlUsd: 300301, createdAt: 1786522937 },
|
|
125
|
+
{ address: "0x31F066aA0A687d4F383F96a514984AF727Eb8e38", name: "USDG/USD0", coins: ["0x4ae46a509F6b1D9056937BA4500cb143933D2dc8", "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"], decimals: [6, 6], poolType: 10, swapTypes: [1], codeHash: "0x855800c63268949eadd5206e5729c69e768f017722f275e90c4185b1fb0733bc", tvlUsd: 300095, createdAt: 1758717026 }
|
|
126
|
+
]
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// src/pools/8453.ts
|
|
130
|
+
var POOLS_8453 = {
|
|
131
|
+
chainId: 8453,
|
|
132
|
+
builtAt: "2026-11-05",
|
|
133
|
+
block: 53566756,
|
|
134
|
+
pools: [
|
|
135
|
+
{ address: "0x302A94E3C28c290EAF2a4605FC52e11Eb915f378", name: "superOETHb/WETH", coins: ["0x4200000000000000000000000000000000000006", "0xDBFeFD2e8460a6Ee4955A68582F85708BAEA60A3"], decimals: [18, 18], poolType: 10, swapTypes: [1], codeHash: "0xd77abce9f34194324a3f8633aa5132f90aaa293ce9b1d7cfe9616bfaff0b9794", tvlUsd: 5842454, createdAt: 1737744997 },
|
|
136
|
+
{ address: "0x11C1fBd4b3De66bC0565779b35171a6CF3E71f59", name: "Curve.fi Factory Crypto Pool: cbETH/WETH", coins: ["0x4200000000000000000000000000000000000006", "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22"], decimals: [18, 18], poolType: 2, swapTypes: [1], codeHash: "0xbba8650811de0f6d2cc92316e9826589443d72feebb6805b2655e81073abe834", tvlUsd: 1016724, createdAt: 1693260297 },
|
|
137
|
+
{ address: "0xfac15A759d0F887Bc7F5ab874491258CF6EC8acE", name: "TriBitcoin", coins: ["0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf", "0x236aa50979D5f3De3Bd1Eeb40E81137F22ab794b", "0x0555E30da8f98308EdB960aa94C0Db47230d2B9c"], decimals: [8, 18, 8], poolType: 10, swapTypes: [1], codeHash: "0x51b2520df586800fd89a56f3a098e1a50e175f72b28088201682deb31bec0022", tvlUsd: 563901, createdAt: 1760081729 },
|
|
138
|
+
{ address: "0x6e53131F68a034873b6bFA15502aF094Ef0c5854", name: "tricrypto", coins: ["0x417Ac0e078398C154EdFadD9Ef675d30Be60Af93", "0x236aa50979D5f3De3Bd1Eeb40E81137F22ab794b", "0x4200000000000000000000000000000000000006"], decimals: [18, 18, 18], poolType: 30, swapTypes: [1], codeHash: "0x437ca50fd4d25807efaa7d45077d247057a5e16b90609fcfde0b51f3673426d3", tvlUsd: 270418, createdAt: 1693263329 },
|
|
139
|
+
{ address: "0xf6C5F01C7F3148891ad0e19DF78743D31E390D1f", name: "Curve.fi Factory Plain Pool: 4pool", coins: ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA", "0xEB466342C4d449BC9f53A865D5Cb90586f405215", "0x417Ac0e078398C154EdFadD9Ef675d30Be60Af93"], decimals: [6, 6, 6, 18], poolType: 1, swapTypes: [1], codeHash: "0xca87b5689cf421c7b6a160ea2b22bd23ef9267477918f39a2bbdf3cb838a987d", tvlUsd: 254106, createdAt: 1693751021 }
|
|
140
|
+
]
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// src/pools/9745.ts
|
|
144
|
+
var POOLS_9745 = {
|
|
145
|
+
chainId: 9745,
|
|
146
|
+
builtAt: "2026-11-05",
|
|
147
|
+
block: 36960466,
|
|
148
|
+
pools: [
|
|
149
|
+
{ address: "0x2D84D79C852f6842AbE0304b70bBaA1506AdD457", name: "USDT0/USDe", coins: ["0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb", "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34"], decimals: [6, 18], poolType: 10, swapTypes: [1], codeHash: "0xc001cdbdd189f52d922cba4eec3137b5698c715d2370d67a41b937e7793b8bd2", tvlUsd: 719322, createdAt: 1758191172 },
|
|
150
|
+
{ address: "0x085BaD2C28Bdd4A40396072D3eb2636BF7Afa39c", name: "yzUSD/USDT0", coins: ["0x6695c0f8706C5ACe3Bdf8995073179cCA47926dc", "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"], decimals: [18, 6], poolType: 10, swapTypes: [1], codeHash: "0x8714b6160e5494b54383f64ebd4c8607093175dd697e48655cfd21df80b81804", tvlUsd: 596466, createdAt: 1762342995 }
|
|
151
|
+
]
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// src/pools/42161.ts
|
|
155
|
+
var POOLS_42161 = {
|
|
156
|
+
chainId: 42161,
|
|
157
|
+
builtAt: "2026-11-05",
|
|
158
|
+
block: 521558965,
|
|
159
|
+
pools: [
|
|
160
|
+
{ address: "0x7f90122BF0700F9E7e1F688fe926940E8839F353", name: "Curve.fi USDC/USDT", coins: ["0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"], decimals: [6, 6], poolType: 1, swapTypes: [1], codeHash: "0xc9c2956ac40175996b15ae3a750b84226736322c5c1aef3e6815b77aab3cb27e", tvlUsd: 630740, createdAt: 1631439440 },
|
|
161
|
+
{ address: "0x186cF879186986A20aADFb7eAD50e3C20cb26CeC", name: "2BTC-ng", coins: ["0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f", "0x6c84a8f1c29108F47a79964b5Fe888D4f4D0dE40"], decimals: [8, 18], poolType: 10, swapTypes: [1], codeHash: "0xaeb505d765c57572cafa881bfcae2cba4e39f933fa7eea85e952ca3b5e1e6a7d", tvlUsd: 509842, createdAt: 1718829260 },
|
|
162
|
+
{ address: "0x82670f35306253222F8a165869B28c64739ac62e", name: "Tricrypto-crvUSD", coins: ["0x498Bf2B1e120FeD3ad3D42EA2165E9b73f99C1e5", "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f", "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"], decimals: [18, 8, 18], poolType: 30, swapTypes: [1], codeHash: "0x35da327ca48b6e428478467c3996176d71855383e82d30664f95886822fd507d", tvlUsd: 328993, createdAt: 1704150579 },
|
|
163
|
+
{ address: "0x49b720F1Aab26260BEAec93A7BeB5BF2925b2A8F", name: "Strategic USD Reserves", coins: ["0xaf88d065e77c8cC2239327C5EDb3A432268e5831", "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"], decimals: [6, 6], poolType: 10, swapTypes: [1], codeHash: "0x27724587b6447859a96567a97e5bf015b8e5ae3d90ffdbe97a098c30b268703c", tvlUsd: 257764, createdAt: 1739092049 }
|
|
164
|
+
]
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/pools/index.ts
|
|
168
|
+
var CURVE_POOLS = Object.freeze({
|
|
169
|
+
1: POOLS_1,
|
|
170
|
+
10: POOLS_10,
|
|
171
|
+
100: POOLS_100,
|
|
172
|
+
143: POOLS_143,
|
|
173
|
+
196: POOLS_196,
|
|
174
|
+
8453: POOLS_8453,
|
|
175
|
+
9745: POOLS_9745,
|
|
176
|
+
42161: POOLS_42161
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// src/routes.ts
|
|
180
|
+
import { getAddress } from "viem";
|
|
181
|
+
import { ccAssetByToken } from "@anywalletkit/swap2-assets";
|
|
182
|
+
var MAX_QUOTE_CANDIDATES = 30;
|
|
183
|
+
var MAX_EXPLORED = 2e4;
|
|
184
|
+
var lc = (a) => a.toLowerCase();
|
|
185
|
+
var STABLE_POOL_TYPES = /* @__PURE__ */ new Set([1, 10]);
|
|
186
|
+
function intermediateAllowed(chainId, deployment, token) {
|
|
187
|
+
const t = lc(token);
|
|
188
|
+
if (t === lc(deployment.eth)) return true;
|
|
189
|
+
if (t === lc(deployment.weth)) return t !== lc(ZERO_ADDRESS);
|
|
190
|
+
if (!/^0x[0-9a-f]{40}$/.test(t) || t === lc(ZERO_ADDRESS)) return false;
|
|
191
|
+
const listed = ccAssetByToken(`eip155:${chainId}`, t);
|
|
192
|
+
return !!listed?.contract && lc(listed.contract) === t;
|
|
193
|
+
}
|
|
194
|
+
function underlyingAllowed(pool, index) {
|
|
195
|
+
const under = pool.underlying;
|
|
196
|
+
if (!under || under.length < 2 || !pool.swapTypes.includes(2)) return false;
|
|
197
|
+
if (!pool.basePool) return false;
|
|
198
|
+
const base = index.get(lc(pool.basePool));
|
|
199
|
+
if (!base || base === pool) return false;
|
|
200
|
+
const meta = pool.coins.length - 1;
|
|
201
|
+
if (under.length !== meta + base.coins.length) return false;
|
|
202
|
+
return under.every((c, k) => lc(c) === lc(k < meta ? pool.coins[k] : base.coins[k - meta]));
|
|
203
|
+
}
|
|
204
|
+
function poolTypeAllowed(family, poolType) {
|
|
205
|
+
return family === "ng5" ? [1, 2, 3, 10, 20, 30].includes(poolType) : [10, 20, 30].includes(poolType);
|
|
206
|
+
}
|
|
207
|
+
var graphs = /* @__PURE__ */ new WeakMap();
|
|
208
|
+
function poolIndex(chainId, deployment, table) {
|
|
209
|
+
return graphFor(chainId, deployment, table).byAddress;
|
|
210
|
+
}
|
|
211
|
+
function graphFor(chainId, deployment, table) {
|
|
212
|
+
if (!table) return { edges: /* @__PURE__ */ new Map(), byAddress: /* @__PURE__ */ new Map() };
|
|
213
|
+
let perDeployment = graphs.get(table);
|
|
214
|
+
if (!perDeployment) graphs.set(table, perDeployment = /* @__PURE__ */ new WeakMap());
|
|
215
|
+
let g = perDeployment.get(deployment);
|
|
216
|
+
if (g) return g;
|
|
217
|
+
g = { edges: /* @__PURE__ */ new Map(), byAddress: /* @__PURE__ */ new Map() };
|
|
218
|
+
const denied = CURVE_DENIED_POOLS[chainId];
|
|
219
|
+
const eth = lc(deployment.eth);
|
|
220
|
+
const add = (s) => {
|
|
221
|
+
const k = lc(s.tokenIn);
|
|
222
|
+
const list = g.edges.get(k);
|
|
223
|
+
if (list) list.push(s);
|
|
224
|
+
else g.edges.set(k, [s]);
|
|
225
|
+
};
|
|
226
|
+
for (const pool of table.chainId === chainId ? table.pools : []) {
|
|
227
|
+
const key = lc(pool.address);
|
|
228
|
+
if (denied?.has(key) || g.byAddress.has(key) || !poolTypeAllowed(deployment.family, pool.poolType)) continue;
|
|
229
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(pool.address) || pool.coins.length < 2 || pool.coins.length > 8) continue;
|
|
230
|
+
if (deployment.family === "lite4" && [...pool.coins, ...pool.underlying ?? []].some((c) => lc(c) === eth)) continue;
|
|
231
|
+
g.byAddress.set(key, pool);
|
|
232
|
+
}
|
|
233
|
+
for (const pool of g.byAddress.values()) {
|
|
234
|
+
const pairs = /* @__PURE__ */ new Set();
|
|
235
|
+
if (pool.swapTypes.includes(1)) {
|
|
236
|
+
pool.coins.forEach((a, i) => pool.coins.forEach((b, j) => {
|
|
237
|
+
if (i === j || lc(a) === lc(b)) return;
|
|
238
|
+
pairs.add(`${lc(a)}>${lc(b)}`);
|
|
239
|
+
add({ kind: "pool", pool, swapType: 1, i, j, tokenIn: getAddress(a), tokenOut: getAddress(b) });
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
const under = pool.underlying;
|
|
243
|
+
if (under && underlyingAllowed(pool, g.byAddress) && (deployment.family === "ng5" || pool.poolType === 10)) {
|
|
244
|
+
under.forEach((a, i) => under.forEach((b, j) => {
|
|
245
|
+
if (i === j || lc(a) === lc(b) || pairs.has(`${lc(a)}>${lc(b)}`)) return;
|
|
246
|
+
add({ kind: "pool", pool, swapType: 2, i, j, tokenIn: getAddress(a), tokenOut: getAddress(b) });
|
|
247
|
+
}));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (lc(deployment.weth) !== lc(ZERO_ADDRESS)) {
|
|
251
|
+
add({ kind: "wrap", weth: getAddress(deployment.weth), tokenIn: getAddress(deployment.eth), tokenOut: getAddress(deployment.weth) });
|
|
252
|
+
add({ kind: "wrap", weth: getAddress(deployment.weth), tokenIn: getAddress(deployment.weth), tokenOut: getAddress(deployment.eth) });
|
|
253
|
+
}
|
|
254
|
+
const v = erc4626Of(deployment);
|
|
255
|
+
if (v) {
|
|
256
|
+
add({ kind: "erc4626", vault: getAddress(v.vault), deposit: true, tokenIn: getAddress(v.asset), tokenOut: getAddress(v.vault) });
|
|
257
|
+
add({ kind: "erc4626", vault: getAddress(v.vault), deposit: false, tokenIn: getAddress(v.vault), tokenOut: getAddress(v.asset) });
|
|
258
|
+
}
|
|
259
|
+
perDeployment.set(deployment, g);
|
|
260
|
+
return g;
|
|
261
|
+
}
|
|
262
|
+
function erc4626Of(d) {
|
|
263
|
+
return d.erc4626 && d.family === "ng5" && d.version === "1.2.0" ? d.erc4626 : void 0;
|
|
264
|
+
}
|
|
265
|
+
var minTvl = (r) => r.reduce((m, s) => s.kind === "pool" ? Math.min(m, s.pool.tvlUsd) : m, Number.POSITIVE_INFINITY);
|
|
266
|
+
var poolCount = (r) => r.filter((s) => s.kind === "pool").length;
|
|
267
|
+
function findRoutes(chainId, deployment, table, tokenIn, tokenOut, limit = MAX_QUOTE_CANDIDATES) {
|
|
268
|
+
const g = graphFor(chainId, deployment, table);
|
|
269
|
+
const want = lc(tokenOut);
|
|
270
|
+
const found = [];
|
|
271
|
+
let explored = 0;
|
|
272
|
+
let exhausted = false;
|
|
273
|
+
const walk = (at, path, seenTokens, seenPools) => {
|
|
274
|
+
if (exhausted) return;
|
|
275
|
+
for (const s of g.edges.get(at) ?? []) {
|
|
276
|
+
if (++explored > MAX_EXPLORED) {
|
|
277
|
+
exhausted = true;
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const next = lc(s.tokenOut);
|
|
281
|
+
if (seenTokens.has(next)) continue;
|
|
282
|
+
if (next !== want && !intermediateAllowed(chainId, deployment, next)) continue;
|
|
283
|
+
if (s.kind === "pool" && (seenPools.has(lc(s.pool.address)) || poolCount(path) >= MAX_ROUTE_POOLS)) continue;
|
|
284
|
+
if (s.kind !== "pool" && path.some((p) => p.kind === s.kind)) continue;
|
|
285
|
+
const steps = [...path, s];
|
|
286
|
+
if (next === want) {
|
|
287
|
+
if (poolCount(steps) > 0 || steps.some((x) => x.kind === "erc4626")) found.push(steps);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
if (steps.length >= MAX_ROUTE_STEPS) continue;
|
|
291
|
+
seenTokens.add(next);
|
|
292
|
+
if (s.kind === "pool") seenPools.add(lc(s.pool.address));
|
|
293
|
+
walk(next, steps, seenTokens, seenPools);
|
|
294
|
+
seenTokens.delete(next);
|
|
295
|
+
if (s.kind === "pool") seenPools.delete(lc(s.pool.address));
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
walk(lc(tokenIn), [], /* @__PURE__ */ new Set([lc(tokenIn)]), /* @__PURE__ */ new Set());
|
|
299
|
+
found.sort((a, b) => poolCount(a) - poolCount(b) || minTvl(b) - minTvl(a) || a.length - b.length);
|
|
300
|
+
return { routes: found.slice(0, limit).map((steps) => ({ steps, label: labelOf(steps) })), truncated: exhausted || found.length > limit };
|
|
301
|
+
}
|
|
302
|
+
function labelOf(steps) {
|
|
303
|
+
return steps.map((s) => s.kind === "pool" ? `${s.pool.name}${s.swapType === 2 ? " (underlying)" : ""}` : s.kind === "wrap" ? s.tokenOut === s.weth ? "wrap" : "unwrap" : s.deposit ? "scrvUSD deposit" : "scrvUSD redeem").join(" \u2192 ");
|
|
304
|
+
}
|
|
305
|
+
function routeArgs(family, route) {
|
|
306
|
+
if (route.steps.length < 1 || route.steps.length > MAX_ROUTE_STEPS) throw new Error(`curve: a route has 1\u2013${MAX_ROUTE_STEPS} steps`);
|
|
307
|
+
const path = [route.steps[0].tokenIn];
|
|
308
|
+
const params = [];
|
|
309
|
+
for (const s of route.steps) {
|
|
310
|
+
const swap = s.kind === "pool" ? s.pool.address : s.kind === "wrap" ? s.weth : s.vault;
|
|
311
|
+
path.push(getAddress(swap), s.tokenOut);
|
|
312
|
+
const row = s.kind === "pool" ? [BigInt(s.i), BigInt(s.j), BigInt(s.swapType), BigInt(s.pool.poolType), BigInt((s.swapType === 2 ? s.pool.underlying : s.pool.coins).length)] : s.kind === "wrap" ? [0n, 0n, 8n, 0n, 0n] : [s.deposit ? 0n : 1n, 0n, 9n, 0n, 0n];
|
|
313
|
+
params.push(family === "ng5" ? row : row.slice(0, 4));
|
|
314
|
+
}
|
|
315
|
+
while (path.length < 11) path.push(ZERO_ADDRESS);
|
|
316
|
+
const cols = family === "ng5" ? 5 : 4;
|
|
317
|
+
while (params.length < 5) params.push(new Array(cols).fill(0n));
|
|
318
|
+
return { route: path, params };
|
|
319
|
+
}
|
|
320
|
+
function routePools(args) {
|
|
321
|
+
const out = [];
|
|
322
|
+
for (let k = 0; k < 5; k++) {
|
|
323
|
+
const swap = args.route[2 * k + 1];
|
|
324
|
+
const t = args.params[k]?.[2];
|
|
325
|
+
if (!swap || lc(swap) === lc(ZERO_ADDRESS)) break;
|
|
326
|
+
if (t === 1n || t === 2n) out.push(swap);
|
|
327
|
+
}
|
|
328
|
+
return out;
|
|
329
|
+
}
|
|
330
|
+
function checkRoute(chainId, deployment, table, args, tokenIn, tokenOut) {
|
|
331
|
+
const cols = deployment.family === "ng5" ? 5 : 4;
|
|
332
|
+
if (args.route.length !== 11 || args.params.length !== 5 || args.params.some((r) => r.length !== cols)) return `the route is not address[11] with uint256[${cols}][5]`;
|
|
333
|
+
const index = poolIndex(chainId, deployment, table);
|
|
334
|
+
const zero = lc(ZERO_ADDRESS);
|
|
335
|
+
const eth = lc(deployment.eth);
|
|
336
|
+
const weth = lc(deployment.weth);
|
|
337
|
+
const v = erc4626Of(deployment);
|
|
338
|
+
let steps = 0;
|
|
339
|
+
while (steps < 5 && lc(args.route[2 * steps + 1]) !== zero) steps++;
|
|
340
|
+
if (steps === 0) return "the route has no step";
|
|
341
|
+
if (steps > MAX_ROUTE_STEPS) return `the route has ${steps} steps, more than ${MAX_ROUTE_STEPS}`;
|
|
342
|
+
for (let k = 2 * steps + 1; k < 11; k++) if (lc(args.route[k]) !== zero) return "the route names addresses after its end";
|
|
343
|
+
for (let k = steps; k < 5; k++) if (args.params[k].some((x) => x !== 0n)) return "the swap params carry rows after the route's end";
|
|
344
|
+
if (lc(args.route[0]) !== lc(tokenIn)) return `the route starts at ${args.route[0]}, not the source token`;
|
|
345
|
+
if (lc(args.route[2 * steps]) !== lc(tokenOut)) return `the route ends at ${args.route[2 * steps]}, not the destination token`;
|
|
346
|
+
for (let k = 1; k < steps; k++) {
|
|
347
|
+
if (!intermediateAllowed(chainId, deployment, args.route[2 * k])) return `step ${k} hands the swap through ${args.route[2 * k]}, a token the catalog does not list on this chain`;
|
|
348
|
+
}
|
|
349
|
+
const pools = /* @__PURE__ */ new Set();
|
|
350
|
+
let wraps = 0;
|
|
351
|
+
let vaults = 0;
|
|
352
|
+
for (let k = 0; k < steps; k++) {
|
|
353
|
+
const a = lc(args.route[2 * k]);
|
|
354
|
+
const swap = lc(args.route[2 * k + 1]);
|
|
355
|
+
const b = lc(args.route[2 * k + 2]);
|
|
356
|
+
const row = args.params[k];
|
|
357
|
+
const type = row[2];
|
|
358
|
+
if (a === b) return `step ${k + 1} trades a token for itself`;
|
|
359
|
+
if (type === 1n || type === 2n) {
|
|
360
|
+
if (CURVE_DENIED_POOLS[chainId]?.has(swap)) return `step ${k + 1} crosses ${args.route[2 * k + 1]}, a pool this module refuses (fake coin, drained in 2023, or over a dead venue)`;
|
|
361
|
+
const pool = index.get(swap);
|
|
362
|
+
if (!pool) return `step ${k + 1} crosses ${args.route[2 * k + 1]}, which is not in the pool allowlist`;
|
|
363
|
+
if (pools.has(swap)) return `the route crosses ${args.route[2 * k + 1]} twice`;
|
|
364
|
+
pools.add(swap);
|
|
365
|
+
if (!pool.swapTypes.includes(type === 1n ? 1 : 2)) return `step ${k + 1} uses swap_type ${type}, which pool ${pool.name} does not allow`;
|
|
366
|
+
if (row[3] !== BigInt(pool.poolType)) return `step ${k + 1} names pool_type ${row[3]}, not pool ${pool.name}'s ${pool.poolType}`;
|
|
367
|
+
if (type === 2n && deployment.family === "lite4" && pool.poolType !== 10) return `step ${k + 1}: exchange_underlying is for stable-ng metapools on this router`;
|
|
368
|
+
if (type === 2n && !underlyingAllowed(pool, index)) return `step ${k + 1}: exchange_underlying on pool ${pool.name} needs its base pool in the allowlist`;
|
|
369
|
+
const list = type === 1n ? pool.coins : pool.underlying;
|
|
370
|
+
if (!list) return `step ${k + 1}: pool ${pool.name} lists no underlying coins`;
|
|
371
|
+
const i = row[0], j = row[1];
|
|
372
|
+
if (i >= BigInt(list.length) || j >= BigInt(list.length) || i === j) return `step ${k + 1}: coin indexes ${i}/${j} are not two coins of pool ${pool.name}`;
|
|
373
|
+
if (lc(list[Number(i.toString())]) !== a || lc(list[Number(j.toString())]) !== b) return `step ${k + 1}: pool ${pool.name}'s coins ${i}/${j} are not the hop's tokens`;
|
|
374
|
+
if (deployment.family === "ng5" && row[4] !== BigInt(list.length)) return `step ${k + 1} names ${row[4]} coins, not pool ${pool.name}'s ${list.length}`;
|
|
375
|
+
if (deployment.family === "lite4" && (a === eth || b === eth)) return `step ${k + 1}: this router does not pass the native coin to pools`;
|
|
376
|
+
if (STABLE_POOL_TYPES.has(pool.poolType) && (i > 127n || j > 127n)) return `step ${k + 1}: coin index out of range`;
|
|
377
|
+
} else if (type === 8n) {
|
|
378
|
+
if (weth === zero) return "this chain's router has no wrapped native";
|
|
379
|
+
if (swap !== weth) return `step ${k + 1} wraps through ${args.route[2 * k + 1]}, not the pinned wrapped native`;
|
|
380
|
+
if (!(a === eth && b === weth || a === weth && b === eth)) return `step ${k + 1}: swap_type 8 is only native \u2194 the pinned wrapped native here`;
|
|
381
|
+
if (row.some((x, c) => c !== 2 && x !== 0n)) return `step ${k + 1}: a wrap carries no other swap params`;
|
|
382
|
+
if (++wraps > 1) return "the route wraps more than once";
|
|
383
|
+
} else if (type === 9n) {
|
|
384
|
+
if (!v) return `swap_type 9 (ERC-4626) is not available on ${deployment.label}'s router ${deployment.version}`;
|
|
385
|
+
if (swap !== lc(v.vault)) return `step ${k + 1}: ERC-4626 hop through ${args.route[2 * k + 1]}, not the pinned vault`;
|
|
386
|
+
const deposit = row[0] === 0n && a === lc(v.asset) && b === lc(v.vault);
|
|
387
|
+
const redeem = row[0] === 1n && a === lc(v.vault) && b === lc(v.asset);
|
|
388
|
+
if (!deposit && !redeem) return `step ${k + 1}: the ERC-4626 hop is not a deposit of the vault's asset or a redeem of its shares`;
|
|
389
|
+
if (row.some((x, c) => c > 0 && c !== 2 && x !== 0n)) return `step ${k + 1}: an ERC-4626 hop carries no other swap params`;
|
|
390
|
+
if (++vaults > 1) return "the route crosses the vault more than once";
|
|
391
|
+
} else {
|
|
392
|
+
return `step ${k + 1} uses swap_type ${type}, which this module never builds`;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (pools.size > MAX_ROUTE_POOLS) return `the route crosses ${pools.size} pools, more than ${MAX_ROUTE_POOLS}`;
|
|
396
|
+
if (pools.size === 0 && vaults === 0) return "the route crosses no pool";
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/rpc.ts
|
|
401
|
+
import { timeoutSignal } from "@anywalletkit/protocol-swap2-core/util";
|
|
402
|
+
var RPC_BATCH_MAX = 10;
|
|
403
|
+
function rpcClient(rpcUrls) {
|
|
404
|
+
async function batch(chainId, calls, signal) {
|
|
405
|
+
let lastErr;
|
|
406
|
+
for (const url of rpcUrls[chainId] ?? []) {
|
|
407
|
+
try {
|
|
408
|
+
const res = await fetch(url, {
|
|
409
|
+
method: "POST",
|
|
410
|
+
headers: { "content-type": "application/json" },
|
|
411
|
+
body: JSON.stringify(calls.map((c, id) => ({ jsonrpc: "2.0", id, ...c }))),
|
|
412
|
+
signal: signal ?? timeoutSignal(12e3)
|
|
413
|
+
});
|
|
414
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
415
|
+
const body = await res.json();
|
|
416
|
+
if (!Array.isArray(body)) throw new Error(body.error?.message ?? "batch refused");
|
|
417
|
+
const out = calls.map(() => null);
|
|
418
|
+
for (const r of body) if (typeof r.id === "number" && r.id >= 0 && r.id < out.length && r.error === void 0) out[r.id] = r.result ?? null;
|
|
419
|
+
return out;
|
|
420
|
+
} catch (e) {
|
|
421
|
+
lastErr = e;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
throw new Error(`curve: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);
|
|
425
|
+
}
|
|
426
|
+
return async function rpc(chainId, calls, signal) {
|
|
427
|
+
if (calls.length <= RPC_BATCH_MAX) return batch(chainId, calls, signal);
|
|
428
|
+
const chunks = [];
|
|
429
|
+
for (let i = 0; i < calls.length; i += RPC_BATCH_MAX) chunks.push(calls.slice(i, i + RPC_BATCH_MAX));
|
|
430
|
+
return (await Promise.all(chunks.map((c) => batch(chainId, c, signal)))).flat();
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
var ethCall = (to, data) => ({ method: "eth_call", params: [{ to, data }, "latest"] });
|
|
434
|
+
function wordAddress(raw) {
|
|
435
|
+
return typeof raw === "string" && /^0x[0-9a-fA-F]{64}$/.test(raw) ? `0x${raw.slice(-40)}`.toLowerCase() : null;
|
|
436
|
+
}
|
|
437
|
+
function wordUint(raw) {
|
|
438
|
+
return typeof raw === "string" && /^0x[0-9a-fA-F]{64}$/.test(raw) ? BigInt(raw) : null;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// src/slippage.ts
|
|
442
|
+
import { bigintToNumber } from "@anywalletkit/core";
|
|
443
|
+
import { ccAssetByToken as ccAssetByToken2 } from "@anywalletkit/swap2-assets";
|
|
444
|
+
import { suggestSlippage } from "@anywalletkit/protocol-swap2-core/slippage";
|
|
445
|
+
import { sourceAssetOf } from "@anywalletkit/protocol-swap2-core/util";
|
|
446
|
+
function curveImpactBps(amountIn, out, probeOut) {
|
|
447
|
+
const probeIn = amountIn / 1000n;
|
|
448
|
+
if (probeIn <= 0n || probeOut === null || probeOut === void 0 || probeOut <= 0n) return void 0;
|
|
449
|
+
const ratioBps = out * probeIn * 10000n / (probeOut * amountIn);
|
|
450
|
+
return Math.max(0, bigintToNumber(10000n - ratioBps));
|
|
451
|
+
}
|
|
452
|
+
function curveAutoSlippageBps(params, priceImpactBps) {
|
|
453
|
+
const nativeOut = /^0x0+$/.test(params.destToken);
|
|
454
|
+
return suggestSlippage({
|
|
455
|
+
fromChain: params.sourceChain,
|
|
456
|
+
toChain: params.destChain,
|
|
457
|
+
fromSymbol: sourceAssetOf(params)?.symbol ?? "",
|
|
458
|
+
toSymbol: ccAssetByToken2(params.destChain, nativeOut ? "" : params.destToken)?.symbol ?? "",
|
|
459
|
+
...priceImpactBps !== void 0 ? { priceImpactBps } : {}
|
|
460
|
+
}).bps;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// src/intent.ts
|
|
464
|
+
var INTENT_ID = /^curve:([1-9][0-9]{0,15}):[0-9a-f]{16}(?:~[0-9a-f]{32})?$/;
|
|
465
|
+
function mintCurveIntentId(chainId) {
|
|
466
|
+
const nonce = globalThis.crypto.getRandomValues(new Uint8Array(8));
|
|
467
|
+
return `curve:${chainId}:${Array.from(nonce, (b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
468
|
+
}
|
|
469
|
+
function curveIntentChain(intentId) {
|
|
470
|
+
const m = typeof intentId === "string" ? INTENT_ID.exec(intentId) : null;
|
|
471
|
+
const id = m ? Number(m[1]) : NaN;
|
|
472
|
+
return Number.isSafeInteger(id) ? id : null;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// src/verify.ts
|
|
476
|
+
import { decodeFunctionResult, encodeFunctionData, keccak256 } from "viem";
|
|
477
|
+
import { sourceAssetOf as sourceAssetOf2 } from "@anywalletkit/protocol-swap2-core/util";
|
|
478
|
+
import { slippageFloor } from "@anywalletkit/protocol-swap2-core/validate";
|
|
479
|
+
var lc2 = (a) => a.toLowerCase();
|
|
480
|
+
var isAddress = (a) => /^0x[0-9a-fA-F]{40}$/.test(a);
|
|
481
|
+
var own = (o, k) => Object.prototype.hasOwnProperty.call(o, k) ? o[k] : void 0;
|
|
482
|
+
function curveQuoteCheck(tables = {}) {
|
|
483
|
+
const deployments = tables.deployments ?? CURVE_DEPLOYMENTS;
|
|
484
|
+
const pools = tables.pools ?? CURVE_POOLS;
|
|
485
|
+
return function verify(params, quote) {
|
|
486
|
+
const chainId = chainIdOf(params.sourceChain);
|
|
487
|
+
const d = deploymentOf(deployments, chainId);
|
|
488
|
+
if (!d || params.destChain !== params.sourceChain) return "not a same-chain swap on a pinned Curve router";
|
|
489
|
+
const tx = quote.txRequest;
|
|
490
|
+
if (!tx?.data || !tx.to || tx.serializedTx !== void 0) return "the quote carries no router call";
|
|
491
|
+
if (!isAddress(tx.to) || lc2(tx.to) !== lc2(d.router)) return `the call targets ${tx.to}, not the Curve router`;
|
|
492
|
+
if (tx.chainId !== void 0 && tx.chainId !== chainId) return `the call is for chain ${tx.chainId}`;
|
|
493
|
+
if (curveIntentChain(quote.intentId) !== chainId) return `the quote names ${String(quote.intentId).slice(0, 40)}, not a curve:${chainId} swap`;
|
|
494
|
+
const src = sourceAssetOf2(params);
|
|
495
|
+
if (!src) return `unknown source token ${params.sourceToken}`;
|
|
496
|
+
const nativeIn = !src.contract;
|
|
497
|
+
const nativeOut = /^0x0+$/.test(params.destToken);
|
|
498
|
+
if (!nativeOut && !isAddress(params.destToken)) return "destination token must be an EVM address";
|
|
499
|
+
if (!isAddress(params.destAddress)) return "recipient must be an EVM address";
|
|
500
|
+
if (!nativeIn && lc2(src.contract) === lc2(d.eth) || !nativeOut && lc2(params.destToken) === lc2(d.eth)) return "the router's native sentinel is not a token";
|
|
501
|
+
const tokenIn = nativeIn ? d.eth : src.contract;
|
|
502
|
+
const tokenOut = nativeOut ? d.eth : params.destToken;
|
|
503
|
+
let amountIn, minOut, value;
|
|
504
|
+
try {
|
|
505
|
+
amountIn = BigInt(params.amountIn);
|
|
506
|
+
minOut = BigInt(quote.minDestAmount);
|
|
507
|
+
value = BigInt(tx.value ?? "0");
|
|
508
|
+
} catch {
|
|
509
|
+
return "the request does not name amounts";
|
|
510
|
+
}
|
|
511
|
+
if (nativeIn ? value !== amountIn || tx.approvalAddress !== void 0 : value !== 0n || !tx.approvalAddress || !isAddress(tx.approvalAddress) || lc2(tx.approvalAddress) !== lc2(d.router)) {
|
|
512
|
+
return nativeIn ? "a native input is paid as exactly the input in value, with no approval" : "a token input attaches no value and approves exactly the Curve router";
|
|
513
|
+
}
|
|
514
|
+
const call = decodeExchange(d.family, tx.data);
|
|
515
|
+
if (!call) return "the router call is not exchange(route, params, amount, min, receiver)";
|
|
516
|
+
if (call.selector !== EXCHANGE_SELECTOR[d.family]) return `selector ${call.selector} is not the explicit-receiver exchange ${EXCHANGE_SELECTOR[d.family]}`;
|
|
517
|
+
if (!call.receiver || lc2(call.receiver) !== lc2(params.destAddress)) return `the swap pays ${call.receiver ?? "the sender"}, not the recipient`;
|
|
518
|
+
if (call.pools && call.pools.some((p) => lc2(p) !== lc2(ZERO_ADDRESS))) return "the call names zap pools this module never uses";
|
|
519
|
+
if (call.amount !== amountIn) return `the swap sells ${call.amount}, not the ${amountIn} input`;
|
|
520
|
+
if (call.minDy <= 0n) return "the swap has no minimum (min_dy 0)";
|
|
521
|
+
if (call.minDy !== minOut) return `the swap's minimum ${call.minDy} is not the quote's ${minOut}`;
|
|
522
|
+
if (quote.providerData?.minOut !== void 0 && quote.providerData.minOut !== minOut.toString()) return "the quote's facts disagree on the minimum";
|
|
523
|
+
return checkRoute(chainId, d, own(pools, chainId), call, tokenIn, tokenOut);
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
var curveVerifyQuote = curveQuoteCheck();
|
|
527
|
+
var curvePins = Object.freeze({
|
|
528
|
+
callTargets: (chain) => routerFor(CURVE_DEPLOYMENTS, chain),
|
|
529
|
+
spenders: (chain) => routerFor(CURVE_DEPLOYMENTS, chain),
|
|
530
|
+
verifyQuote: curveVerifyQuote
|
|
531
|
+
});
|
|
532
|
+
function routerFor(deployments, chain) {
|
|
533
|
+
const d = deploymentOf(deployments, chainIdOf(chain));
|
|
534
|
+
return d ? [d.router] : [];
|
|
535
|
+
}
|
|
536
|
+
function curveOnChain(opts) {
|
|
537
|
+
const deployments = opts.deployments ?? CURVE_DEPLOYMENTS;
|
|
538
|
+
const pools = opts.pools ?? CURVE_POOLS;
|
|
539
|
+
const rpc = rpcClient(opts.rpcUrls);
|
|
540
|
+
const warn = opts.onWarning ?? ((m) => console.warn(m));
|
|
541
|
+
const verified = /* @__PURE__ */ new Map();
|
|
542
|
+
function verifyDeployment(chainId) {
|
|
543
|
+
let p = verified.get(chainId);
|
|
544
|
+
if (!p) {
|
|
545
|
+
const d = deploymentOf(deployments, chainId);
|
|
546
|
+
p = (async () => {
|
|
547
|
+
if (!d) throw new Error(`curve: no pinned router on chain ${chainId}`);
|
|
548
|
+
const [code, version, listed] = await rpc(chainId, [
|
|
549
|
+
{ method: "eth_getCode", params: [d.router, "latest"] },
|
|
550
|
+
ethCall(d.router, encodeFunctionData({ abi: VERSION_ABI, functionName: "version" })),
|
|
551
|
+
ethCall(d.addressProvider, encodeFunctionData({ abi: ADDRESS_PROVIDER_ABI, functionName: "get_address", args: [2n] }))
|
|
552
|
+
]);
|
|
553
|
+
if (typeof code !== "string" || code.length <= 2 || lc2(keccak256(code)) !== lc2(d.codeHash)) {
|
|
554
|
+
throw new Error(`curve: the router on chain ${chainId} is not the pinned code (code hash mismatch) \u2014 refusing`);
|
|
555
|
+
}
|
|
556
|
+
let v = "";
|
|
557
|
+
try {
|
|
558
|
+
v = typeof version === "string" ? decodeFunctionResult({ abi: VERSION_ABI, functionName: "version", data: version }) : "";
|
|
559
|
+
} catch {
|
|
560
|
+
}
|
|
561
|
+
if (v !== d.version) throw new Error(`curve: the router on chain ${chainId} reports version ${v || "none"}, not ${d.version} \u2014 refusing`);
|
|
562
|
+
const ap = wordAddress(listed);
|
|
563
|
+
if (ap && ap !== lc2(d.addressProviderRouter) && ap !== lc2(d.router)) {
|
|
564
|
+
warn(`curve: the AddressProvider on ${d.label} lists router ${ap} (id 2); this module keeps the pinned ${d.router}`);
|
|
565
|
+
}
|
|
566
|
+
})();
|
|
567
|
+
p.catch(() => verified.delete(chainId));
|
|
568
|
+
verified.set(chainId, p);
|
|
569
|
+
}
|
|
570
|
+
return p;
|
|
571
|
+
}
|
|
572
|
+
async function checkSealed(quote, tx) {
|
|
573
|
+
const r = await inspectSealed(quote, tx, false);
|
|
574
|
+
return typeof r === "string" ? r : null;
|
|
575
|
+
}
|
|
576
|
+
async function inspectSealed(quote, tx, probe) {
|
|
577
|
+
const chainId = curveIntentChain(quote.intentId);
|
|
578
|
+
const d = chainId === null ? void 0 : deploymentOf(deployments, chainId);
|
|
579
|
+
if (chainId === null || !d) return "the quote is not a Curve swap on a pinned chain";
|
|
580
|
+
const quoted = quote.txRequest;
|
|
581
|
+
if (!quoted?.data || !quoted.to || !tx.data) return "the quote or the transaction carries no router call";
|
|
582
|
+
if (tx.data.length !== quoted.data.length || lc2(tx.data) !== lc2(quoted.data)) return "the transaction is not the quoted router call";
|
|
583
|
+
if (!isAddress(tx.to) || lc2(tx.to) !== lc2(d.router) || lc2(quoted.to) !== lc2(d.router)) return `the transaction calls ${tx.to}, not the Curve router`;
|
|
584
|
+
if ((tx.value ?? "0") !== (quoted.value ?? "0")) return "the transaction's value is not the quote's";
|
|
585
|
+
if (tx.chainId !== void 0 && tx.chainId !== chainId || quoted.chainId !== void 0 && quoted.chainId !== chainId) return `the transaction is not for chain ${chainId}`;
|
|
586
|
+
if ((tx.approvalAddress ?? "").toLowerCase() !== (quoted.approvalAddress ?? "").toLowerCase()) return "the transaction's approval is not the quote's";
|
|
587
|
+
const call = decodeExchange(d.family, quoted.data);
|
|
588
|
+
if (!call || call.selector !== EXCHANGE_SELECTOR[d.family]) return "the quoted call is not the explicit-receiver exchange";
|
|
589
|
+
if (call.minDy <= 0n) return "the swap has no minimum (min_dy 0)";
|
|
590
|
+
const last = lastToken(call);
|
|
591
|
+
const reason = checkRoute(chainId, d, own(pools, chainId), call, call.route[0], last);
|
|
592
|
+
if (reason) return reason;
|
|
593
|
+
await verifyDeployment(chainId);
|
|
594
|
+
const index = poolIndex(chainId, d, own(pools, chainId));
|
|
595
|
+
const hops = routePools(call).map((a) => index.get(lc2(a)));
|
|
596
|
+
const calls = [ethCall(d.router, encodeGetDy(d.family, call, call.amount))];
|
|
597
|
+
for (const pool of hops) {
|
|
598
|
+
calls.push({ method: "eth_getCode", params: [pool.address, "latest"] });
|
|
599
|
+
pool.coins.forEach((_, k) => calls.push(ethCall(pool.address, `${COINS_UINT}${k.toString(16).padStart(64, "0")}`)));
|
|
600
|
+
}
|
|
601
|
+
const probeIn = call.amount / 1000n;
|
|
602
|
+
const probeAt = calls.length;
|
|
603
|
+
if (probe && probeIn > 0n) calls.push(ethCall(d.router, encodeGetDy(d.family, call, probeIn)));
|
|
604
|
+
const res = await rpc(chainId, calls);
|
|
605
|
+
let at = 1;
|
|
606
|
+
const retry = [];
|
|
607
|
+
for (const pool of hops) {
|
|
608
|
+
const code = res[at++];
|
|
609
|
+
if (typeof code !== "string" || code.length <= 2 || lc2(keccak256(code)) !== lc2(pool.codeHash)) return `pool ${pool.name} (${pool.address}) is not the pinned code`;
|
|
610
|
+
for (let k = 0; k < pool.coins.length; k++) {
|
|
611
|
+
const coin = wordAddress(res[at++]);
|
|
612
|
+
if (coin === null) retry.push({ pool, k });
|
|
613
|
+
else if (coin !== lc2(pool.coins[k])) return `pool ${pool.name} now reports coin ${k} = ${coin}, not the pinned ${pool.coins[k]}`;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (retry.length) {
|
|
617
|
+
const again = await rpc(chainId, retry.map(({ pool, k }) => ethCall(pool.address, `${COINS_INT}${k.toString(16).padStart(64, "0")}`)));
|
|
618
|
+
for (const [n, { pool, k }] of retry.entries()) {
|
|
619
|
+
const coin = wordAddress(again[n]);
|
|
620
|
+
if (coin !== lc2(pool.coins[k])) return `pool ${pool.name} does not report its pinned coin ${k}`;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
const out = wordUint(res[0]);
|
|
624
|
+
if (out === null) return "the router no longer quotes this route";
|
|
625
|
+
if (out < call.minDy) return `price moved \u2014 the pools now pay ${out}, under your minimum ${call.minDy}`;
|
|
626
|
+
return { out, probeOut: probe && probeIn > 0n ? wordUint(res[probeAt]) : null, amount: call.amount, minDy: call.minDy };
|
|
627
|
+
}
|
|
628
|
+
return { rpc, verifyDeployment, checkSealed, inspectSealed };
|
|
629
|
+
}
|
|
630
|
+
function lastToken(call) {
|
|
631
|
+
let k = 0;
|
|
632
|
+
while (k < 5 && lc2(call.route[2 * k + 1]) !== lc2(ZERO_ADDRESS)) k++;
|
|
633
|
+
return call.route[2 * k];
|
|
634
|
+
}
|
|
635
|
+
var CURVE_AUTO_SLIPPAGE_DRIFT_BPS = 5;
|
|
636
|
+
function curveRemotePins(opts) {
|
|
637
|
+
const deployments = opts.deployments ?? CURVE_DEPLOYMENTS;
|
|
638
|
+
const fixedSlippage = opts.defaultSlippageBps;
|
|
639
|
+
if (fixedSlippage !== void 0 && (!Number.isInteger(fixedSlippage) || fixedSlippage <= 0 || fixedSlippage >= 5e3)) throw new Error("curve: defaultSlippageBps must be 1..4999");
|
|
640
|
+
const verifyQuote = curveQuoteCheck(opts);
|
|
641
|
+
const chain = curveOnChain(opts);
|
|
642
|
+
return Object.freeze({
|
|
643
|
+
callTargets: (c) => routerFor(deployments, c),
|
|
644
|
+
spenders: (c) => routerFor(deployments, c),
|
|
645
|
+
verifyQuote,
|
|
646
|
+
async verifyBuild(quote, tx, params) {
|
|
647
|
+
if (!params) return "the request this quote answered is unknown";
|
|
648
|
+
const reason = verifyQuote(params, quote);
|
|
649
|
+
if (reason) return reason;
|
|
650
|
+
try {
|
|
651
|
+
const auto = params.slippageBps === void 0 && fixedSlippage === void 0;
|
|
652
|
+
const seen = await chain.inspectSealed(quote, tx, auto);
|
|
653
|
+
if (typeof seen === "string") return seen;
|
|
654
|
+
const { out, probeOut, amount, minDy } = seen;
|
|
655
|
+
let dest;
|
|
656
|
+
try {
|
|
657
|
+
dest = BigInt(quote.destAmount);
|
|
658
|
+
} catch {
|
|
659
|
+
return "the quote names no output";
|
|
660
|
+
}
|
|
661
|
+
const bps = params.slippageBps ?? fixedSlippage ?? Math.min(9999, curveAutoSlippageBps(params, curveImpactBps(amount, out, probeOut)) + CURVE_AUTO_SLIPPAGE_DRIFT_BPS);
|
|
662
|
+
if (slippageFloor(dest, bps) > out) return `the quote promises ${dest}, more than ${bps} bps above the ${out} the pools pay now`;
|
|
663
|
+
const fresh = dest < out ? dest : out;
|
|
664
|
+
if (minDy < slippageFloor(fresh, bps)) return `the swap's minimum ${minDy} is more than ${bps} bps under the ${fresh} the pools pay now`;
|
|
665
|
+
return null;
|
|
666
|
+
} catch (e) {
|
|
667
|
+
return e instanceof Error ? e.message.replace(/^curve: /, "") : String(e);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// src/provider.ts
|
|
674
|
+
var DEFAULT_TTL_MS = 18e4;
|
|
675
|
+
function curveProvider(config) {
|
|
676
|
+
const deployments = config.deployments ?? CURVE_DEPLOYMENTS;
|
|
677
|
+
const pools = config.pools ?? CURVE_POOLS;
|
|
678
|
+
const ttl = config.quoteTtlMs ?? DEFAULT_TTL_MS;
|
|
679
|
+
const fixedSlippage = config.defaultSlippageBps;
|
|
680
|
+
if (fixedSlippage !== void 0 && (!Number.isInteger(fixedSlippage) || fixedSlippage <= 0 || fixedSlippage >= 5e3)) throw new Error("curve: defaultSlippageBps must be 1..4999");
|
|
681
|
+
const chain = curveOnChain({ rpcUrls: config.rpcUrls, deployments, pools, ...config.onWarning ? { onWarning: config.onWarning } : {} });
|
|
682
|
+
const rpc = chain.rpc;
|
|
683
|
+
const selfCheck = curveQuoteCheck({ deployments, pools });
|
|
684
|
+
const tableOf = (chainId) => Object.prototype.hasOwnProperty.call(pools, chainId) ? pools[chainId] : void 0;
|
|
685
|
+
const chainIdOf2 = (caip2) => {
|
|
686
|
+
if (!isEvm(caip2)) return null;
|
|
687
|
+
const id = evmRef(caip2);
|
|
688
|
+
return deploymentOf(deployments, id) && config.rpcUrls[id]?.length && tableOf(id)?.pools.length ? id : null;
|
|
689
|
+
};
|
|
690
|
+
async function price(chainId, d, routes, amount, signal) {
|
|
691
|
+
const raw = await rpc(chainId, routes.map((r) => ethCall(d.router, encodeGetDy(d.family, routeArgs(d.family, r), amount))), signal);
|
|
692
|
+
return raw.map(wordUint);
|
|
693
|
+
}
|
|
694
|
+
return {
|
|
695
|
+
name: "curve",
|
|
696
|
+
describeActivity: (tx, ctx) => describeCurveActivity(tx, ctx, deployments),
|
|
697
|
+
supportsSameChain: true,
|
|
698
|
+
enabled: () => config.enabled ?? true,
|
|
699
|
+
supportsChain: (caip2) => chainIdOf2(caip2) !== null,
|
|
700
|
+
supportsChainPair: (from, to) => from === to && chainIdOf2(from) !== null,
|
|
701
|
+
supportsRoute(from, to) {
|
|
702
|
+
return from.chain === to.chain && chainIdOf2(from.chain) !== null;
|
|
703
|
+
},
|
|
704
|
+
async getQuote(params, signal) {
|
|
705
|
+
const refuse = (why) => {
|
|
706
|
+
params.onRefusal?.(`curve: ${why}`);
|
|
707
|
+
return null;
|
|
708
|
+
};
|
|
709
|
+
if (params.flex) return refuse("amount-flexible deposits are not supported");
|
|
710
|
+
if (params.sourceChain !== params.destChain) return refuse("same-chain swaps only");
|
|
711
|
+
const chainId = chainIdOf2(params.sourceChain);
|
|
712
|
+
if (chainId === null) return refuse(`no Curve router, pool allowlist or RPC for ${params.sourceChain}`);
|
|
713
|
+
const d = deploymentOf(deployments, chainId);
|
|
714
|
+
const src = sourceAssetOf3(params);
|
|
715
|
+
if (!src) return refuse(`unknown source token ${params.sourceToken}`);
|
|
716
|
+
const nativeIn = !src.contract;
|
|
717
|
+
const nativeOut = /^0x0+$/.test(params.destToken);
|
|
718
|
+
if (!nativeOut && !/^0x[0-9a-fA-F]{40}$/.test(params.destToken)) return refuse("destination token must be an EVM address");
|
|
719
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress)) return refuse("recipient must be an EVM address");
|
|
720
|
+
let amountIn;
|
|
721
|
+
try {
|
|
722
|
+
amountIn = BigInt(params.amountIn);
|
|
723
|
+
} catch {
|
|
724
|
+
return refuse("amount is not an integer");
|
|
725
|
+
}
|
|
726
|
+
if (amountIn <= 0n) return refuse("amount must be positive");
|
|
727
|
+
if (params.slippageBps !== void 0 && (!Number.isInteger(params.slippageBps) || params.slippageBps < 0 || params.slippageBps >= 1e4)) return refuse("slippage must be 0..9999 bps");
|
|
728
|
+
if (!nativeIn && src.contract.toLowerCase() === d.eth.toLowerCase()) return refuse("the native coin is named by the catalog, not by the router's 0xEeee sentinel");
|
|
729
|
+
if (!nativeOut && params.destToken.toLowerCase() === d.eth.toLowerCase()) return refuse("name a native output with the zero address, not the router's 0xEeee sentinel");
|
|
730
|
+
const tokenIn = getAddress2(nativeIn ? d.eth : src.contract);
|
|
731
|
+
const tokenOut = getAddress2(nativeOut ? d.eth : params.destToken);
|
|
732
|
+
if (tokenIn === tokenOut) return refuse("same token in and out");
|
|
733
|
+
const wrapPair = [getAddress2(d.eth), getAddress2(d.weth)];
|
|
734
|
+
if (wrapPair.includes(tokenIn) && wrapPair.includes(tokenOut)) return refuse("that is a wrap/unwrap, not a swap");
|
|
735
|
+
try {
|
|
736
|
+
await chain.verifyDeployment(chainId);
|
|
737
|
+
const { routes, truncated } = findRoutes(chainId, d, tableOf(chainId), tokenIn, tokenOut);
|
|
738
|
+
if (!routes.length) return refuse("no allowlisted Curve pool route for this pair");
|
|
739
|
+
const outs = await price(chainId, d, routes, amountIn, signal);
|
|
740
|
+
let best = null;
|
|
741
|
+
outs.forEach((out2, i) => {
|
|
742
|
+
if (out2 !== null && out2 > 0n && (!best || out2 > best.out)) best = { route: routes[i], out: out2 };
|
|
743
|
+
});
|
|
744
|
+
if (!best) return refuse("no allowlisted Curve pool quotes this pair and amount");
|
|
745
|
+
const { route, out } = best;
|
|
746
|
+
let priceImpactBps;
|
|
747
|
+
const probeIn = amountIn / 1000n;
|
|
748
|
+
if (probeIn > 0n) {
|
|
749
|
+
try {
|
|
750
|
+
const [probeOut] = await price(chainId, d, [route], probeIn, signal);
|
|
751
|
+
priceImpactBps = curveImpactBps(amountIn, out, probeOut);
|
|
752
|
+
} catch {
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
const bps = params.slippageBps ?? fixedSlippage ?? curveAutoSlippageBps(params, priceImpactBps);
|
|
756
|
+
const minOut = out * BigInt(1e4 - bps) / 10000n;
|
|
757
|
+
if (minOut <= 0n) return refuse("the minimum rounds to zero for this amount");
|
|
758
|
+
if (params.minAmountOut !== void 0 && minOut < BigInt(params.minAmountOut)) {
|
|
759
|
+
return refuse(`floor breach (min=${minOut} < floor=${params.minAmountOut})`);
|
|
760
|
+
}
|
|
761
|
+
const args = routeArgs(d.family, route);
|
|
762
|
+
const recipient = getAddress2(params.destAddress);
|
|
763
|
+
const data = encodeExchange(d.family, args, amountIn, minOut, recipient);
|
|
764
|
+
const quote = {
|
|
765
|
+
provider: "curve",
|
|
766
|
+
// One id per quote: a remote stub keys the request a build is checked against by it.
|
|
767
|
+
intentId: mintCurveIntentId(chainId),
|
|
768
|
+
depositAddress: "",
|
|
769
|
+
depositMemo: null,
|
|
770
|
+
txRequest: {
|
|
771
|
+
to: d.router,
|
|
772
|
+
data,
|
|
773
|
+
value: nativeIn ? amountIn.toString() : "0",
|
|
774
|
+
chainId,
|
|
775
|
+
...nativeIn ? {} : { approvalAddress: d.router }
|
|
776
|
+
},
|
|
777
|
+
sourceAmount: amountIn.toString(),
|
|
778
|
+
destAmount: out.toString(),
|
|
779
|
+
minDestAmount: minOut.toString(),
|
|
780
|
+
feeUsd: 0,
|
|
781
|
+
etaSeconds: 15,
|
|
782
|
+
reliability: 0.97,
|
|
783
|
+
validUntilMs: Date.now() + ttl,
|
|
784
|
+
// Pool fees are inside the router-priced output; nothing is added on top.
|
|
785
|
+
providerData: {
|
|
786
|
+
route: route.label,
|
|
787
|
+
poolFee: "pools",
|
|
788
|
+
router: d.router,
|
|
789
|
+
family: d.family,
|
|
790
|
+
tokenIn,
|
|
791
|
+
tokenOut,
|
|
792
|
+
amountIn: amountIn.toString(),
|
|
793
|
+
minOut: minOut.toString(),
|
|
794
|
+
slippageBps: String(bps),
|
|
795
|
+
pools: routePools(args).join(","),
|
|
796
|
+
candidates: `${routes.length}${truncated ? "+" : ""}`,
|
|
797
|
+
...priceImpactBps !== void 0 ? { priceImpactBps: String(priceImpactBps) } : {}
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
const why = selfCheck(params, quote);
|
|
801
|
+
if (why) return refuse(`built a call its own check refuses (${why})`);
|
|
802
|
+
return quote;
|
|
803
|
+
} catch (e) {
|
|
804
|
+
return refuse(e instanceof Error ? e.message.replace(/^curve: /, "") : String(e));
|
|
805
|
+
}
|
|
806
|
+
},
|
|
807
|
+
/**
|
|
808
|
+
* Right before broadcast (after any approval): the transaction is byte for byte the sealed quote, each hop pool is
|
|
809
|
+
* still the pinned code with the pinned coins (the immutable router's code and version were checked once for the
|
|
810
|
+
* chain), and the exact route still pays at least the signed minimum. Refuse with the reason instead of sending a swap that would revert or was altered.
|
|
811
|
+
*/
|
|
812
|
+
async preflightDeposit(quote, tx) {
|
|
813
|
+
const reason = await chain.checkSealed(quote, tx);
|
|
814
|
+
if (reason) throw new Error(`curve: ${reason}. Nothing was sent; refresh the quote.`);
|
|
815
|
+
},
|
|
816
|
+
async buildDeposit(quote) {
|
|
817
|
+
const tx = quote.txRequest;
|
|
818
|
+
if (!tx?.to || !tx.data) throw new Error("swap2: Curve quote has no transaction request");
|
|
819
|
+
return {
|
|
820
|
+
chain: "",
|
|
821
|
+
to: tx.to,
|
|
822
|
+
value: tx.value ?? "0",
|
|
823
|
+
data: tx.data,
|
|
824
|
+
...tx.chainId !== void 0 ? { chainId: tx.chainId } : {},
|
|
825
|
+
...tx.gasLimit ? { gasLimit: tx.gasLimit } : {},
|
|
826
|
+
...tx.approvalAddress ? { approvalAddress: tx.approvalAddress } : {}
|
|
827
|
+
};
|
|
828
|
+
},
|
|
829
|
+
/** Same-chain: the swap is done when its transaction is mined successfully. */
|
|
830
|
+
async trackIntent(ref) {
|
|
831
|
+
if (!ref.sourceTxHash) return { state: "pending" };
|
|
832
|
+
const chainId = curveIntentChain(ref.intentId);
|
|
833
|
+
if (chainId === null || !deploymentOf(deployments, chainId) || !config.rpcUrls[chainId]?.length) return { state: "pending" };
|
|
834
|
+
try {
|
|
835
|
+
const [receipt] = await rpc(chainId, [{ method: "eth_getTransactionReceipt", params: [ref.sourceTxHash] }]);
|
|
836
|
+
if (!receipt) return { state: "pending" };
|
|
837
|
+
return receipt.status === "0x1" ? { state: "completed", destTxHash: ref.sourceTxHash } : { state: "failed" };
|
|
838
|
+
} catch {
|
|
839
|
+
return { state: "pending" };
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
export {
|
|
846
|
+
MAX_QUOTE_CANDIDATES,
|
|
847
|
+
intermediateAllowed,
|
|
848
|
+
underlyingAllowed,
|
|
849
|
+
poolTypeAllowed,
|
|
850
|
+
poolIndex,
|
|
851
|
+
findRoutes,
|
|
852
|
+
routeArgs,
|
|
853
|
+
routePools,
|
|
854
|
+
checkRoute,
|
|
855
|
+
CURVE_POOLS,
|
|
856
|
+
curveQuoteCheck,
|
|
857
|
+
curveVerifyQuote,
|
|
858
|
+
curvePins,
|
|
859
|
+
curveOnChain,
|
|
860
|
+
CURVE_AUTO_SLIPPAGE_DRIFT_BPS,
|
|
861
|
+
curveRemotePins,
|
|
862
|
+
curveProvider
|
|
863
|
+
};
|
|
864
|
+
//# sourceMappingURL=chunk-FICPW2P2.js.map
|