@raac/rpc 2.0.0-beta.17 → 2.0.0-beta.19

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.
Files changed (31) hide show
  1. package/dist/RPCLibrary.js +2 -0
  2. package/dist/artifacts/faucet/Faucet.json +254 -0
  3. package/dist/contracts/curve/common/_helpers.js +3 -3
  4. package/dist/contracts/curve/common/getPoolInterface.js +16 -0
  5. package/dist/contracts/curve/common/getPoolState.js +105 -0
  6. package/dist/contracts/curve/common/index.js +2 -0
  7. package/dist/contracts/faucet/getState.js +45 -0
  8. package/dist/contracts/faucet/index.js +1 -0
  9. package/dist/contracts/zap/aladdin/inspectCurvePool.js +67 -0
  10. package/dist/pools/rwaVault/adapters/erc721/getERC721VaultAdapterAssetValue.js +1 -1
  11. package/dist/pools/rwaVault/adapters/erc721/getERC721VaultAdapterTotalValue.js +1 -1
  12. package/dist/pools/rwaVault/getRegisteredAdapters.js +1 -1
  13. package/dist/pools/rwaVault/previewDeposit.js +1 -1
  14. package/dist/pools/rwaVault/previewWithdraw.js +1 -1
  15. package/dist/types/RPCLibrary.d.ts +2 -0
  16. package/dist/types/contracts/curve/common/_helpers.d.ts +7 -1
  17. package/dist/types/contracts/curve/common/getPoolInterface.d.ts +12 -0
  18. package/dist/types/contracts/curve/common/getPoolState.d.ts +43 -0
  19. package/dist/types/contracts/curve/common/index.d.ts +2 -0
  20. package/dist/types/contracts/faucet/getState.d.ts +27 -0
  21. package/dist/types/contracts/faucet/index.d.ts +1 -0
  22. package/dist/types/contracts/zap/aladdin/inspectCurvePool.d.ts +28 -0
  23. package/dist/types/pools/rwaVault/adapters/erc721/getERC721VaultAdapterAssetValue.d.ts +1 -1
  24. package/dist/types/pools/rwaVault/adapters/erc721/getERC721VaultAdapterTotalValue.d.ts +1 -1
  25. package/dist/types/pools/rwaVault/getRWAVaultInfo.d.ts +1 -1
  26. package/dist/types/pools/rwaVault/getRegisteredAdapters.d.ts +1 -1
  27. package/dist/types/pools/rwaVault/previewDeposit.d.ts +1 -1
  28. package/dist/types/pools/rwaVault/previewWithdraw.d.ts +1 -1
  29. package/dist/types/utils/artifacts.d.ts +51 -0
  30. package/dist/utils/artifacts.js +3 -0
  31. package/package.json +1 -1
@@ -383,6 +383,7 @@ const getMinterInfo_1 = require("./contracts/tokens/leRAAC/getMinterInfo");
383
383
  // Aladdin Zap
384
384
  const getRoutes_1 = require("./contracts/zap/aladdin/getRoutes");
385
385
  const getCurvePoolToken_1 = require("./contracts/zap/aladdin/getCurvePoolToken");
386
+ const inspectCurvePool_1 = require("./contracts/zap/aladdin/inspectCurvePool");
386
387
  const getPool2Token_1 = require("./contracts/zap/aladdin/getPool2Token");
387
388
  const getOwner_1 = require("./contracts/zap/aladdin/getOwner");
388
389
  const getVersion_1 = require("./contracts/zap/aladdin/getVersion");
@@ -728,6 +729,7 @@ class RPCLibrary {
728
729
  aladdin: {
729
730
  getRoutes: getRoutes_1.getRoutes,
730
731
  getCurvePoolToken: getCurvePoolToken_1.getCurvePoolToken,
732
+ inspectCurvePool: inspectCurvePool_1.inspectCurvePool,
731
733
  getPool2Token: getPool2Token_1.getPool2Token,
732
734
  getOwner: getOwner_1.getOwner,
733
735
  getVersion: getVersion_1.getVersion,
@@ -0,0 +1,254 @@
1
+ {
2
+ "_comment": "Hand-written from the deployed Sepolia faucet 0xcFcAE14bC0Ef0CB5CD4466b916F518A393d7f2a7 (no source in the repos); every selector checked against its bytecode.",
3
+ "abi": [
4
+ {
5
+ "type": "function",
6
+ "name": "allTokens",
7
+ "constant": true,
8
+ "stateMutability": "view",
9
+ "payable": false,
10
+ "inputs": [],
11
+ "outputs": [
12
+ {
13
+ "type": "address[]",
14
+ "name": ""
15
+ }
16
+ ]
17
+ },
18
+ {
19
+ "type": "function",
20
+ "name": "tokens",
21
+ "constant": true,
22
+ "stateMutability": "view",
23
+ "payable": false,
24
+ "inputs": [
25
+ {
26
+ "type": "uint256",
27
+ "name": "index"
28
+ }
29
+ ],
30
+ "outputs": [
31
+ {
32
+ "type": "address",
33
+ "name": ""
34
+ }
35
+ ]
36
+ },
37
+ {
38
+ "type": "function",
39
+ "name": "approvedToken",
40
+ "constant": true,
41
+ "stateMutability": "view",
42
+ "payable": false,
43
+ "inputs": [
44
+ {
45
+ "type": "address",
46
+ "name": "token"
47
+ }
48
+ ],
49
+ "outputs": [
50
+ {
51
+ "type": "bool",
52
+ "name": ""
53
+ }
54
+ ]
55
+ },
56
+ {
57
+ "type": "function",
58
+ "name": "tokenCap",
59
+ "constant": true,
60
+ "stateMutability": "view",
61
+ "payable": false,
62
+ "inputs": [
63
+ {
64
+ "type": "address",
65
+ "name": "token"
66
+ }
67
+ ],
68
+ "outputs": [
69
+ {
70
+ "type": "uint256",
71
+ "name": ""
72
+ }
73
+ ]
74
+ },
75
+ {
76
+ "type": "function",
77
+ "name": "whitelisted",
78
+ "constant": true,
79
+ "stateMutability": "view",
80
+ "payable": false,
81
+ "inputs": [
82
+ {
83
+ "type": "address",
84
+ "name": "account"
85
+ }
86
+ ],
87
+ "outputs": [
88
+ {
89
+ "type": "bool",
90
+ "name": ""
91
+ }
92
+ ]
93
+ },
94
+ {
95
+ "type": "function",
96
+ "name": "owner",
97
+ "constant": true,
98
+ "stateMutability": "view",
99
+ "payable": false,
100
+ "inputs": [],
101
+ "outputs": [
102
+ {
103
+ "type": "address",
104
+ "name": ""
105
+ }
106
+ ]
107
+ },
108
+ {
109
+ "type": "function",
110
+ "name": "paused",
111
+ "constant": true,
112
+ "stateMutability": "view",
113
+ "payable": false,
114
+ "inputs": [],
115
+ "outputs": [
116
+ {
117
+ "type": "bool",
118
+ "name": ""
119
+ }
120
+ ]
121
+ },
122
+ {
123
+ "type": "function",
124
+ "name": "claim",
125
+ "constant": false,
126
+ "payable": false,
127
+ "inputs": [
128
+ {
129
+ "type": "address",
130
+ "name": "token"
131
+ },
132
+ {
133
+ "type": "uint256",
134
+ "name": "amount"
135
+ }
136
+ ],
137
+ "outputs": []
138
+ },
139
+ {
140
+ "type": "function",
141
+ "name": "claimMultiple",
142
+ "constant": false,
143
+ "payable": false,
144
+ "inputs": [
145
+ {
146
+ "type": "address[]",
147
+ "name": "tokens"
148
+ },
149
+ {
150
+ "type": "uint256[]",
151
+ "name": "amounts"
152
+ }
153
+ ],
154
+ "outputs": []
155
+ },
156
+ {
157
+ "type": "function",
158
+ "name": "addToken",
159
+ "constant": false,
160
+ "payable": false,
161
+ "inputs": [
162
+ {
163
+ "type": "address",
164
+ "name": "token"
165
+ },
166
+ {
167
+ "type": "uint256",
168
+ "name": "cap"
169
+ }
170
+ ],
171
+ "outputs": []
172
+ },
173
+ {
174
+ "type": "function",
175
+ "name": "updateTokenCap",
176
+ "constant": false,
177
+ "payable": false,
178
+ "inputs": [
179
+ {
180
+ "type": "address",
181
+ "name": "token"
182
+ },
183
+ {
184
+ "type": "uint256",
185
+ "name": "cap"
186
+ }
187
+ ],
188
+ "outputs": []
189
+ },
190
+ {
191
+ "type": "function",
192
+ "name": "withdraw",
193
+ "constant": false,
194
+ "payable": false,
195
+ "inputs": [
196
+ {
197
+ "type": "address",
198
+ "name": "token"
199
+ },
200
+ {
201
+ "type": "uint256",
202
+ "name": "amount"
203
+ }
204
+ ],
205
+ "outputs": []
206
+ },
207
+ {
208
+ "type": "function",
209
+ "name": "whitelist",
210
+ "constant": false,
211
+ "payable": false,
212
+ "inputs": [
213
+ {
214
+ "type": "address",
215
+ "name": "account"
216
+ },
217
+ {
218
+ "type": "bool",
219
+ "name": "status"
220
+ }
221
+ ],
222
+ "outputs": []
223
+ },
224
+ {
225
+ "type": "function",
226
+ "name": "pause",
227
+ "constant": false,
228
+ "payable": false,
229
+ "inputs": [],
230
+ "outputs": []
231
+ },
232
+ {
233
+ "type": "function",
234
+ "name": "unpause",
235
+ "constant": false,
236
+ "payable": false,
237
+ "inputs": [],
238
+ "outputs": []
239
+ },
240
+ {
241
+ "type": "function",
242
+ "name": "transferOwnership",
243
+ "constant": false,
244
+ "payable": false,
245
+ "inputs": [
246
+ {
247
+ "type": "address",
248
+ "name": "newOwner"
249
+ }
250
+ ],
251
+ "outputs": []
252
+ }
253
+ ]
254
+ }
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getCurvePools = exports.CURVE_POOL_READ_ABI = void 0;
6
+ exports.CURVE_POOL_WRITE_ABI = exports.getCurvePools = exports.CURVE_POOL_READ_ABI = void 0;
7
7
  exports.resolveCurvePool = resolveCurvePool;
8
8
  exports.getCurvePoolContract = getCurvePoolContract;
9
9
  exports.getCurvePoolFlavourContract = getCurvePoolFlavourContract;
@@ -45,7 +45,7 @@ function getCurvePoolContract(chainId, poolAddressOrId, provider) {
45
45
  * uint256[2] / uint256[3] arrays; stableswap-ng indexes with int128 and takes a dynamic uint256[]. Encoding one
46
46
  * against another reverts, so the pool's configured flavour picks the ABI.
47
47
  */
48
- const CURVE_POOL_WRITE_ABI = {
48
+ exports.CURVE_POOL_WRITE_ABI = {
49
49
  twocrypto: [
50
50
  "function get_dy(uint256 i, uint256 j, uint256 dx) view returns (uint256)",
51
51
  "function calc_withdraw_one_coin(uint256 token_amount, uint256 i) view returns (uint256)",
@@ -80,7 +80,7 @@ function getCurvePoolFlavourContract(chainId, poolAddressOrId, runner) {
80
80
  if (!runner) {
81
81
  runner = new ethers_1.ethers.JsonRpcProvider(chains_1.default[chainId].rpcs[0]);
82
82
  }
83
- return { entry, contract: new ethers_1.ethers.Contract(entry.contract, CURVE_POOL_WRITE_ABI[entry.flavour], runner) };
83
+ return { entry, contract: new ethers_1.ethers.Contract(entry.contract, exports.CURVE_POOL_WRITE_ABI[entry.flavour], runner) };
84
84
  }
85
85
  /** Checks an amounts array matches the pool's coin count before it reaches the encoder. */
86
86
  function assertCoinCount(entry, amounts, what) {
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPoolInterface = void 0;
4
+ const ethers_1 = require("ethers");
5
+ const _helpers_1 = require("./_helpers");
6
+ /**
7
+ * The pool's swap and liquidity ABI for its flavour, for encoding calls that are sent elsewhere (e.g. queued in a
8
+ * Safe) instead of through `exchange` / `addLiquidity` / `removeLiquidity` / `removeLiquidityOneCoin`. Reads the config
9
+ * only; no RPC call is made.
10
+ *
11
+ * @param chainId - The chain/network to use.
12
+ * @param poolAddressOrId - The pool's key in the chain config's `curve` section, or its address.
13
+ * @returns The interface (stableswap-ng indexes coins with int128 and takes dynamic arrays, the crypto pools uint256 and fixed arrays).
14
+ */
15
+ const getPoolInterface = (chainId, poolAddressOrId) => new ethers_1.ethers.Interface(_helpers_1.CURVE_POOL_WRITE_ABI[(0, _helpers_1.resolveCurvePool)(chainId, poolAddressOrId).flavour]);
16
+ exports.getPoolInterface = getPoolInterface;
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getPoolState = void 0;
7
+ const ethers_1 = require("ethers");
8
+ const chains_1 = __importDefault(require("../../../configs/chains"));
9
+ const amount_1 = require("../../../utils/amount");
10
+ const rpcError_1 = require("../../../utils/rpcError");
11
+ const _helpers_1 = require("./_helpers");
12
+ const getPools_1 = require("./getPools");
13
+ const COMMON = [
14
+ "function balances(uint256) view returns (uint256)",
15
+ "function totalSupply() view returns (uint256)",
16
+ "function get_virtual_price() view returns (uint256)",
17
+ "function fee() view returns (uint256)",
18
+ "function A() view returns (uint256)",
19
+ ];
20
+ /**
21
+ * Price getters per flavour. twocrypto-ng has one price and no index; tricrypto-ng and stableswap-ng take k for
22
+ * coin k + 1. All price in coin 0.
23
+ */
24
+ const PRICE_ABI = {
25
+ twocrypto: [
26
+ "function price_oracle() view returns (uint256)",
27
+ "function last_prices() view returns (uint256)",
28
+ "function price_scale() view returns (uint256)",
29
+ "function lp_price() view returns (uint256)",
30
+ "function mid_fee() view returns (uint256)",
31
+ "function out_fee() view returns (uint256)",
32
+ ],
33
+ tricrypto: [
34
+ "function price_oracle(uint256) view returns (uint256)",
35
+ "function last_prices(uint256) view returns (uint256)",
36
+ "function price_scale(uint256) view returns (uint256)",
37
+ "function lp_price() view returns (uint256)",
38
+ "function mid_fee() view returns (uint256)",
39
+ "function out_fee() view returns (uint256)",
40
+ ],
41
+ stableswap: ["function price_oracle(uint256) view returns (uint256)", "function get_p(uint256) view returns (uint256)"],
42
+ };
43
+ const FEE_DECIMALS = 10;
44
+ const ONE = BigInt(10) ** BigInt(amount_1.WAD_DECIMALS);
45
+ /**
46
+ * Reads a Curve pool's composition, prices and fees in one go: balances, LP supply, virtual and LP price, the
47
+ * oracle, spot and (crypto) scale price of every coin in coin 0, each balance's value in coin 0, and the fee and A.
48
+ *
49
+ * @param chainId - The chain/network to use.
50
+ * @param poolAddressOrId - The pool's key in the chain config's `curve` section, or its address.
51
+ * @param provider - Optional ethers.js Provider instance.
52
+ * @returns The pool's state; values and TVL are in coin 0's units at the oracle price.
53
+ */
54
+ const getPoolState = async (chainId, poolAddressOrId, provider) => {
55
+ const entry = (0, _helpers_1.resolveCurvePool)(chainId, poolAddressOrId);
56
+ const pool = (0, getPools_1.getPool)(chainId, entry.id);
57
+ if (!provider)
58
+ provider = new ethers_1.ethers.JsonRpcProvider(chains_1.default[chainId].rpcs[0]);
59
+ const contract = new ethers_1.ethers.Contract(entry.contract, [...COMMON, ...PRICE_ABI[entry.flavour]], provider);
60
+ const crypto = entry.flavour !== "stableswap";
61
+ const others = pool.coins.slice(1).map((_, k) => k);
62
+ // twocrypto-ng's price getters take no index; it has a single other coin.
63
+ const each = (method) => Promise.all(others.map((k) => (entry.flavour === "twocrypto" ? contract[method]() : contract[method](k))));
64
+ try {
65
+ const [balances, supply, virtualPrice, fee, A, oracle, spot, scale, lpPrice, mid, out] = await Promise.all([
66
+ Promise.all(pool.coins.map((_, i) => contract.balances(i))),
67
+ contract.totalSupply(),
68
+ contract.get_virtual_price(),
69
+ contract.fee(),
70
+ contract.A(),
71
+ each("price_oracle"),
72
+ each(crypto ? "last_prices" : "get_p"),
73
+ crypto ? each("price_scale") : Promise.resolve(null),
74
+ crypto ? contract.lp_price() : Promise.resolve(null),
75
+ crypto ? contract.mid_fee() : Promise.resolve(null),
76
+ crypto ? contract.out_fee() : Promise.resolve(null),
77
+ ]);
78
+ const unit = pool.coins[0];
79
+ const prices = (p) => [ONE, ...p].map((v) => (0, amount_1.toAmount)(v, amount_1.WAD_DECIMALS, unit.symbol));
80
+ const oraclePrices = prices(oracle);
81
+ // balance (coin decimals) * price (1e18) -> coin 0 decimals
82
+ const values = balances.map((b, i) => (0, amount_1.toAmount)((b * oraclePrices[i].value * BigInt(10) ** BigInt(unit.decimals)) / (BigInt(10) ** BigInt(pool.coins[i].decimals) * ONE), unit.decimals, unit.symbol));
83
+ const tvl = values.reduce((sum, v) => sum + v.value, BigInt(0));
84
+ const lp = lpPrice ?? (supply > BigInt(0) ? (tvl * BigInt(10) ** BigInt(amount_1.WAD_DECIMALS + amount_1.WAD_DECIMALS - unit.decimals)) / supply : BigInt(0));
85
+ return {
86
+ pool,
87
+ balances: balances.map((b, i) => (0, amount_1.toAmount)(b, pool.coins[i].decimals, pool.coins[i].symbol)),
88
+ totalSupply: (0, amount_1.toAmount)(supply, amount_1.WAD_DECIMALS, "LP"),
89
+ virtualPrice: (0, amount_1.toAmount)(virtualPrice, amount_1.WAD_DECIMALS),
90
+ lpPrice: (0, amount_1.toAmount)(lp, amount_1.WAD_DECIMALS, unit.symbol),
91
+ oraclePrices,
92
+ spotPrices: prices(spot),
93
+ priceScale: scale ? prices(scale) : null,
94
+ values,
95
+ tvl: (0, amount_1.toAmount)(tvl, unit.decimals, unit.symbol),
96
+ fee: (0, amount_1.toScaled)(fee, FEE_DECIMALS),
97
+ feeRange: mid !== null && out !== null ? { mid: (0, amount_1.toScaled)(mid, FEE_DECIMALS), out: (0, amount_1.toScaled)(out, FEE_DECIMALS) } : null,
98
+ A,
99
+ };
100
+ }
101
+ catch (error) {
102
+ throw (0, rpcError_1.toRpcError)("curve.common.getPoolState", error, { chainId, address: entry.contract });
103
+ }
104
+ };
105
+ exports.getPoolState = getPoolState;
@@ -20,6 +20,8 @@ __exportStar(require("./calcWithdrawOneCoin"), exports);
20
20
  __exportStar(require("./exchange"), exports);
21
21
  __exportStar(require("./getDy"), exports);
22
22
  __exportStar(require("./getPools"), exports);
23
+ __exportStar(require("./getPoolInterface"), exports);
24
+ __exportStar(require("./getPoolState"), exports);
23
25
  __exportStar(require("./getVirtualPrice"), exports);
24
26
  __exportStar(require("./removeLiquidity"), exports);
25
27
  __exportStar(require("./removeLiquidityOneCoin"), exports);
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getState = void 0;
7
+ const ethers_1 = require("ethers");
8
+ const chains_1 = __importDefault(require("../../configs/chains"));
9
+ const amount_1 = require("../../utils/amount");
10
+ const artifacts_1 = require("../../utils/artifacts");
11
+ const contracts_1 = require("../../utils/contracts");
12
+ const rpcError_1 = require("../../utils/rpcError");
13
+ const ERC20 = ["function symbol() view returns (string)", "function decimals() view returns (uint8)", "function balanceOf(address) view returns (uint256)"];
14
+ /**
15
+ * Reads the testnet faucet: its owner, whether it is paused, and every token it gives out with its balance and per-claim cap.
16
+ * The faucet has no deposit function; it is topped up with a plain ERC20 transfer.
17
+ *
18
+ * @param chainId - The chain/network to use; only chains with a `faucet` contract in their config (Sepolia).
19
+ * @param provider - Optional ethers.js Provider instance.
20
+ */
21
+ const getState = async (chainId, provider) => {
22
+ if (!provider)
23
+ provider = new ethers_1.ethers.JsonRpcProvider(chains_1.default[chainId].rpcs[0]);
24
+ const address = (0, contracts_1.getContractAddress)(chainId, "faucet");
25
+ const faucet = new ethers_1.ethers.Contract(address, (0, artifacts_1.getABI)("faucet"), provider);
26
+ try {
27
+ const [owner, paused, list] = await Promise.all([faucet.owner(), faucet.paused(), faucet.allTokens()]);
28
+ const tokens = await Promise.all(list.map(async (token) => {
29
+ const erc20 = new ethers_1.ethers.Contract(token, ERC20, provider);
30
+ const [symbol, decimals, balance, cap, approved] = await Promise.all([
31
+ erc20.symbol(),
32
+ erc20.decimals().then(Number),
33
+ erc20.balanceOf(address),
34
+ faucet.tokenCap(token),
35
+ faucet.approvedToken(token),
36
+ ]);
37
+ return { address: ethers_1.ethers.getAddress(token), symbol, decimals, balance: (0, amount_1.toAmount)(balance, decimals, symbol), cap: (0, amount_1.toAmount)(cap, decimals, symbol), approved };
38
+ }));
39
+ return { address: ethers_1.ethers.getAddress(address), owner, paused, tokens };
40
+ }
41
+ catch (error) {
42
+ throw (0, rpcError_1.toRpcError)("faucet.getState", error, { chainId, address });
43
+ }
44
+ };
45
+ exports.getState = getState;
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./claim"), exports);
18
+ __exportStar(require("./getState"), exports);
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.inspectCurvePool = void 0;
7
+ const ethers_1 = require("ethers");
8
+ const chains_1 = __importDefault(require("../../../configs/chains"));
9
+ const rpcError_1 = require("../../../utils/rpcError");
10
+ const _types_1 = require("./_types");
11
+ /**
12
+ * The zap's Curve swap calls by pool type (TokenZapLogic.swap), for pools indexed by plain `coins(i)`. The base, A, Y,
13
+ * meta and factory meta pools all swap through the same 4-argument int128 `exchange`, so they share CurveBasePool here.
14
+ */
15
+ const SWAP_SIGNATURES = [
16
+ [_types_1.AladdinPoolType.CurveCryptoPool, "exchange(uint256,uint256,uint256,uint256)"],
17
+ [_types_1.AladdinPoolType.CurveFactoryPlainPool, "exchange(int128,int128,uint256,uint256,address)"],
18
+ [_types_1.AladdinPoolType.CurveTriCryptoPool, "exchange(uint256,uint256,uint256,uint256,bool)"],
19
+ [_types_1.AladdinPoolType.CurveBasePool, "exchange(int128,int128,uint256,uint256)"],
20
+ ];
21
+ const MAX_COINS = 8;
22
+ const ERC20 = ["function symbol() view returns (string)", "function decimals() view returns (uint8)"];
23
+ /**
24
+ * Reads a Curve pool that may not be in the chain config, so a zap route can be built through it: its coins in index
25
+ * order with their symbols, and which zap pool types it can swap as. The types come from the swap function selectors in
26
+ * its deployed bytecode, which Vyper and Solidity dispatchers embed; a match means the call exists, not that the pool
27
+ * behaves as that type in every other way.
28
+ *
29
+ * @param chainId - The chain/network to use.
30
+ * @param pool - The pool address.
31
+ * @param provider - Optional ethers.js Provider instance.
32
+ * @throws If the address has no code or no `coins(0)`.
33
+ */
34
+ const inspectCurvePool = async (chainId, pool, provider) => {
35
+ if (!provider)
36
+ provider = new ethers_1.ethers.JsonRpcProvider(chains_1.default[chainId].rpcs[0]);
37
+ const address = ethers_1.ethers.getAddress(pool);
38
+ try {
39
+ const code = await provider.getCode(address);
40
+ if (code === "0x")
41
+ throw new Error(`${address} has no contract code`);
42
+ // Newer pools index coins with uint256, older ones with int128.
43
+ const byUint = new ethers_1.ethers.Contract(address, ["function coins(uint256) view returns (address)"], provider);
44
+ const byInt = new ethers_1.ethers.Contract(address, ["function coins(int128) view returns (address)"], provider);
45
+ const coinAt = (i) => byUint.coins(i).catch(() => byInt.coins(i)).catch(() => null);
46
+ const addresses = [];
47
+ for (let i = 0; i < MAX_COINS; i++) {
48
+ const coin = await coinAt(i);
49
+ if (!coin || coin === ethers_1.ethers.ZeroAddress)
50
+ break;
51
+ addresses.push(ethers_1.ethers.getAddress(coin));
52
+ }
53
+ if (!addresses.length)
54
+ throw new Error(`${address} has no coins(0); it is not a Curve pool this can read`);
55
+ const coins = await Promise.all(addresses.map(async (coin) => {
56
+ const erc20 = new ethers_1.ethers.Contract(coin, ERC20, provider);
57
+ const [symbol, decimals] = await Promise.all([erc20.symbol().catch(() => "?"), erc20.decimals().then(Number).catch(() => 18)]);
58
+ return { address: coin, symbol, decimals };
59
+ }));
60
+ const poolTypes = SWAP_SIGNATURES.filter(([, sig]) => code.toLowerCase().includes(ethers_1.ethers.id(sig).slice(2, 10))).map(([type]) => type);
61
+ return { pool: address, coins, poolTypes };
62
+ }
63
+ catch (error) {
64
+ throw (0, rpcError_1.toRpcError)("zap.aladdin.inspectCurvePool", error, { chainId, address });
65
+ }
66
+ };
67
+ exports.inspectCurvePool = inspectCurvePool;
@@ -9,7 +9,7 @@ const rpcError_1 = require("../../../../utils/rpcError");
9
9
  * @param adapterAddress The ERC721 vault adapter address.
10
10
  * @param tokenId The NFT token id.
11
11
  * @param signer The signer to read with.
12
- * @returns The oracle value in crvUSD base units, 18 decimals.
12
+ * @returns The oracle value in USD, 18 decimals.
13
13
  */
14
14
  async function getERC721VaultAdapterAssetValue(adapterAddress, tokenId, signer) {
15
15
  if (!signer) {
@@ -8,7 +8,7 @@ const rpcError_1 = require("../../../../utils/rpcError");
8
8
  * Reads the value of all NFTs held by an ERC721 vault adapter.
9
9
  * @param adapterAddress The ERC721 vault adapter address.
10
10
  * @param signer The signer to read with.
11
- * @returns The summed oracle value in crvUSD base units, 18 decimals.
11
+ * @returns The summed oracle value in USD, 18 decimals.
12
12
  */
13
13
  async function getERC721VaultAdapterTotalValue(adapterAddress, signer) {
14
14
  if (!signer) {
@@ -42,7 +42,7 @@ async function readAdapter(address, provider) {
42
42
  adapter.totalValue().catch(() => null),
43
43
  erc721 ? adapter.getDepositedTokens() : Promise.resolve([]),
44
44
  ]);
45
- return { type, token, tokenSymbol, tokenDecimals, value: value === null ? null : (0, amount_1.toAmount)(value, amount_1.WAD_DECIMALS, "crvUSD"), tokenIds: [...tokenIds] };
45
+ return { type, token, tokenSymbol, tokenDecimals, value: value === null ? null : (0, amount_1.toAmount)(value, amount_1.WAD_DECIMALS, erc721 ? "USD" : "crvUSD"), tokenIds: [...tokenIds] };
46
46
  }
47
47
  /**
48
48
  * Every adapter registered on the RWA vault, read from the vault's own arrays rather than the chain config (which
@@ -6,7 +6,7 @@ const rpcError_1 = require("../../utils/rpcError");
6
6
  /**
7
7
  * Previews how many vault shares are minted for depositing `assetValue`.
8
8
  * @param chainId The chain id.
9
- * @param assetValue The asset value in vault value base units (crvUSD, 18 decimals, as returned by the vault adapters).
9
+ * @param assetValue The asset value in vault value base units (USD for house NFTs, 18 decimals, as returned by the vault adapters).
10
10
  * @param provider The provider to read with.
11
11
  * @returns The shares (rounded down), in share token (RWA index token) base units.
12
12
  */
@@ -6,7 +6,7 @@ const rpcError_1 = require("../../utils/rpcError");
6
6
  /**
7
7
  * Previews how many vault shares are burned to withdraw `assetValue`.
8
8
  * @param chainId The chain id.
9
- * @param assetValue The asset value in vault value base units (crvUSD, 18 decimals, as returned by the vault adapters).
9
+ * @param assetValue The asset value in vault value base units (USD for house NFTs, 18 decimals, as returned by the vault adapters).
10
10
  * @param provider The provider to read with.
11
11
  * @returns The shares (rounded up), in share token (RWA index token) base units.
12
12
  */
@@ -301,6 +301,7 @@ import { burnFrom as burnFromLeRAAC } from "./contracts/tokens/leRAAC/burnFrom";
301
301
  import { getMinterInfo as getMinterInfoLeRAAC } from "./contracts/tokens/leRAAC/getMinterInfo";
302
302
  import { getRoutes as getRoutesAladdin } from "./contracts/zap/aladdin/getRoutes";
303
303
  import { getCurvePoolToken as getCurvePoolTokenAladdin } from "./contracts/zap/aladdin/getCurvePoolToken";
304
+ import { inspectCurvePool as inspectCurvePoolAladdin } from "./contracts/zap/aladdin/inspectCurvePool";
304
305
  import { getPool2Token as getPool2TokenAladdin } from "./contracts/zap/aladdin/getPool2Token";
305
306
  import { getOwner as getOwnerAladdin } from "./contracts/zap/aladdin/getOwner";
306
307
  import { getVersion as getVersionAladdin } from "./contracts/zap/aladdin/getVersion";
@@ -652,6 +653,7 @@ declare class RPCLibrary {
652
653
  aladdin: {
653
654
  getRoutes: typeof getRoutesAladdin;
654
655
  getCurvePoolToken: typeof getCurvePoolTokenAladdin;
656
+ inspectCurvePool: typeof inspectCurvePoolAladdin;
655
657
  getPool2Token: typeof getPool2TokenAladdin;
656
658
  getOwner: typeof getOwnerAladdin;
657
659
  getVersion: typeof getVersionAladdin;
@@ -1,6 +1,6 @@
1
1
  import { ethers, Provider, Signer } from "ethers";
2
2
  import { ChainId } from "../../../configs/chains";
3
- import { CurvePoolEntry, CurvePools } from "../../../configs/chains/chain";
3
+ import { CurvePoolEntry, CurvePoolFlavour, CurvePools } from "../../../configs/chains/chain";
4
4
  /**
5
5
  * Reads every Curve pool flavour shares. Coin indexes differ (uint256 vs int128) only in swap and liquidity
6
6
  * methods, which are not here.
@@ -14,6 +14,12 @@ export declare function getCurvePoolContract(chainId: ChainId, poolAddressOrId:
14
14
  contract: ethers.Contract;
15
15
  provider: ethers.Provider;
16
16
  };
17
+ /**
18
+ * Swap and liquidity methods per flavour. twocrypto-ng and tricrypto-ng index coins with uint256 and take fixed
19
+ * uint256[2] / uint256[3] arrays; stableswap-ng indexes with int128 and takes a dynamic uint256[]. Encoding one
20
+ * against another reverts, so the pool's configured flavour picks the ABI.
21
+ */
22
+ export declare const CURVE_POOL_WRITE_ABI: Record<CurvePoolFlavour, string[]>;
17
23
  /** The pool contract with its flavour's swap and liquidity ABI, bound to a signer or provider. */
18
24
  export declare function getCurvePoolFlavourContract(chainId: ChainId, poolAddressOrId: string, runner?: Signer | Provider): {
19
25
  entry: CurvePoolEntry;
@@ -0,0 +1,12 @@
1
+ import { ethers } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * The pool's swap and liquidity ABI for its flavour, for encoding calls that are sent elsewhere (e.g. queued in a
5
+ * Safe) instead of through `exchange` / `addLiquidity` / `removeLiquidity` / `removeLiquidityOneCoin`. Reads the config
6
+ * only; no RPC call is made.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param poolAddressOrId - The pool's key in the chain config's `curve` section, or its address.
10
+ * @returns The interface (stableswap-ng indexes coins with int128 and takes dynamic arrays, the crypto pools uint256 and fixed arrays).
11
+ */
12
+ export declare const getPoolInterface: (chainId: ChainId, poolAddressOrId: string) => ethers.Interface;
@@ -0,0 +1,43 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ import { ScaledValue, TokenAmount } from "../../../utils/amount";
4
+ import { CurvePool } from "./getPools";
5
+ export interface CurvePoolState {
6
+ pool: CurvePool;
7
+ /** Coin balances in pool index order, each in its own decimals and symbol. */
8
+ balances: TokenAmount[];
9
+ /** LP tokens in circulation (the pool is its own LP token, 18 decimals). */
10
+ totalSupply: TokenAmount;
11
+ /** `get_virtual_price()`: underlying per LP token, only grows with fees. */
12
+ virtualPrice: TokenAmount;
13
+ /** Value of one LP token in coin 0: `lp_price()` on crypto pools, the balances at oracle prices on stableswap pools. */
14
+ lpPrice: TokenAmount;
15
+ /** Price of each coin in coin 0, 18 decimals, from the pool's EMA oracle; `oraclePrices[0]` is 1. */
16
+ oraclePrices: TokenAmount[];
17
+ /** Price of each coin in coin 0 right now: `last_prices` on crypto pools, `get_p` on stableswap pools. */
18
+ spotPrices: TokenAmount[];
19
+ /** Crypto pools only: where liquidity is concentrated (`price_scale`), in coin 0. Null on stableswap pools. */
20
+ priceScale: TokenAmount[] | null;
21
+ /** Each balance valued in coin 0 at the oracle price; their sum is the pool's TVL in coin 0. */
22
+ values: TokenAmount[];
23
+ tvl: TokenAmount;
24
+ /** Current swap fee as a fraction (Curve's 1e10 scale). */
25
+ fee: ScaledValue;
26
+ /** Crypto pools: the fee range the current fee moves in, as fractions. Null on stableswap pools. */
27
+ feeRange: {
28
+ mid: ScaledValue;
29
+ out: ScaledValue;
30
+ } | null;
31
+ /** Amplification, as the pool's `A()` reports it (crypto pools scale it by 10000). */
32
+ A: bigint;
33
+ }
34
+ /**
35
+ * Reads a Curve pool's composition, prices and fees in one go: balances, LP supply, virtual and LP price, the
36
+ * oracle, spot and (crypto) scale price of every coin in coin 0, each balance's value in coin 0, and the fee and A.
37
+ *
38
+ * @param chainId - The chain/network to use.
39
+ * @param poolAddressOrId - The pool's key in the chain config's `curve` section, or its address.
40
+ * @param provider - Optional ethers.js Provider instance.
41
+ * @returns The pool's state; values and TVL are in coin 0's units at the oracle price.
42
+ */
43
+ export declare const getPoolState: (chainId: ChainId, poolAddressOrId: string, provider?: Provider) => Promise<CurvePoolState>;
@@ -4,6 +4,8 @@ export * from "./calcWithdrawOneCoin";
4
4
  export * from "./exchange";
5
5
  export * from "./getDy";
6
6
  export * from "./getPools";
7
+ export * from "./getPoolInterface";
8
+ export * from "./getPoolState";
7
9
  export * from "./getVirtualPrice";
8
10
  export * from "./removeLiquidity";
9
11
  export * from "./removeLiquidityOneCoin";
@@ -0,0 +1,27 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../configs/chains";
3
+ import { TokenAmount } from "../../utils/amount";
4
+ export interface FaucetToken {
5
+ address: string;
6
+ symbol: string;
7
+ decimals: number;
8
+ /** What the faucet holds and can still give out. */
9
+ balance: TokenAmount;
10
+ /** The most one claim may take. */
11
+ cap: TokenAmount;
12
+ approved: boolean;
13
+ }
14
+ export interface FaucetState {
15
+ address: string;
16
+ owner: string;
17
+ paused: boolean;
18
+ tokens: FaucetToken[];
19
+ }
20
+ /**
21
+ * Reads the testnet faucet: its owner, whether it is paused, and every token it gives out with its balance and per-claim cap.
22
+ * The faucet has no deposit function; it is topped up with a plain ERC20 transfer.
23
+ *
24
+ * @param chainId - The chain/network to use; only chains with a `faucet` contract in their config (Sepolia).
25
+ * @param provider - Optional ethers.js Provider instance.
26
+ */
27
+ export declare const getState: (chainId: ChainId, provider?: Provider) => Promise<FaucetState>;
@@ -1 +1,2 @@
1
1
  export * from "./claim";
2
+ export * from "./getState";
@@ -0,0 +1,28 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ import { AladdinPoolType } from "./_types";
4
+ export interface InspectedCoin {
5
+ address: string;
6
+ /** "?" when the token has no readable symbol. */
7
+ symbol: string;
8
+ decimals: number;
9
+ }
10
+ export interface InspectedCurvePool {
11
+ pool: string;
12
+ /** In pool index order: the index a route hop uses. */
13
+ coins: InspectedCoin[];
14
+ /** Zap pool types whose swap call the pool's bytecode has, best match first; empty when none is found. */
15
+ poolTypes: AladdinPoolType[];
16
+ }
17
+ /**
18
+ * Reads a Curve pool that may not be in the chain config, so a zap route can be built through it: its coins in index
19
+ * order with their symbols, and which zap pool types it can swap as. The types come from the swap function selectors in
20
+ * its deployed bytecode, which Vyper and Solidity dispatchers embed; a match means the call exists, not that the pool
21
+ * behaves as that type in every other way.
22
+ *
23
+ * @param chainId - The chain/network to use.
24
+ * @param pool - The pool address.
25
+ * @param provider - Optional ethers.js Provider instance.
26
+ * @throws If the address has no code or no `coins(0)`.
27
+ */
28
+ export declare const inspectCurvePool: (chainId: ChainId, pool: string, provider?: Provider) => Promise<InspectedCurvePool>;
@@ -5,7 +5,7 @@ import { TokenAmount } from "../../../../utils/amount";
5
5
  * @param adapterAddress The ERC721 vault adapter address.
6
6
  * @param tokenId The NFT token id.
7
7
  * @param signer The signer to read with.
8
- * @returns The oracle value in crvUSD base units, 18 decimals.
8
+ * @returns The oracle value in USD, 18 decimals.
9
9
  */
10
10
  declare function getERC721VaultAdapterAssetValue(adapterAddress: string, tokenId: bigint, signer: Signer): Promise<TokenAmount>;
11
11
  export default getERC721VaultAdapterAssetValue;
@@ -4,7 +4,7 @@ import { TokenAmount } from "../../../../utils/amount";
4
4
  * Reads the value of all NFTs held by an ERC721 vault adapter.
5
5
  * @param adapterAddress The ERC721 vault adapter address.
6
6
  * @param signer The signer to read with.
7
- * @returns The summed oracle value in crvUSD base units, 18 decimals.
7
+ * @returns The summed oracle value in USD, 18 decimals.
8
8
  */
9
9
  declare function getERC721VaultAdapterTotalValue(adapterAddress: string, signer: Signer): Promise<TokenAmount>;
10
10
  export default getERC721VaultAdapterTotalValue;
@@ -1,7 +1,7 @@
1
1
  import { Provider } from "ethers";
2
2
  import { ChainId } from "../../configs/chains/index";
3
3
  import { TokenAmount } from "../../utils/amount";
4
- /** RWA vault state. Values are in crvUSD base units with 18 decimals, as priced by the vault adapters. */
4
+ /** RWA vault state. Values are the sum of the adapters' values, 18 decimals: USD for the house NFT adapter (crvUSD for any ERC20 adapter). */
5
5
  export interface RWAVaultInfo {
6
6
  /** Total value of all assets held by the vault. */
7
7
  totalAssets: TokenAmount;
@@ -15,7 +15,7 @@ export interface RegisteredVaultAdapter {
15
15
  depositable: boolean;
16
16
  /** Listed in `redeemableERC721Adapters`. */
17
17
  redeemable: boolean;
18
- /** Oracle value of everything held, in crvUSD with 18 decimals; null when the adapter could not price it. */
18
+ /** Oracle value of everything held, 18 decimals: USD for NFT adapters (RAACNFTVaultAdapterOracle), crvUSD for ERC20 adapters (their price oracle); null when the adapter could not price it. */
19
19
  value: TokenAmount | null;
20
20
  /** Token ids held, for ERC721 adapters. */
21
21
  tokenIds: bigint[];
@@ -4,7 +4,7 @@ import { TokenAmount } from "../../utils/amount";
4
4
  /**
5
5
  * Previews how many vault shares are minted for depositing `assetValue`.
6
6
  * @param chainId The chain id.
7
- * @param assetValue The asset value in vault value base units (crvUSD, 18 decimals, as returned by the vault adapters).
7
+ * @param assetValue The asset value in vault value base units (USD for house NFTs, 18 decimals, as returned by the vault adapters).
8
8
  * @param provider The provider to read with.
9
9
  * @returns The shares (rounded down), in share token (RWA index token) base units.
10
10
  */
@@ -4,7 +4,7 @@ import { TokenAmount } from "../../utils/amount";
4
4
  /**
5
5
  * Previews how many vault shares are burned to withdraw `assetValue`.
6
6
  * @param chainId The chain id.
7
- * @param assetValue The asset value in vault value base units (crvUSD, 18 decimals, as returned by the vault adapters).
7
+ * @param assetValue The asset value in vault value base units (USD for house NFTs, 18 decimals, as returned by the vault adapters).
8
8
  * @param provider The provider to read with.
9
9
  * @returns The shares (rounded up), in share token (RWA index token) base units.
10
10
  */
@@ -2383,6 +2383,32 @@ declare const ABIS: {
2383
2383
  type: string;
2384
2384
  anonymous?: undefined;
2385
2385
  })[];
2386
+ faucet: ({
2387
+ type: string;
2388
+ name: string;
2389
+ constant: boolean;
2390
+ stateMutability: string;
2391
+ payable: boolean;
2392
+ inputs: {
2393
+ type: string;
2394
+ name: string;
2395
+ }[];
2396
+ outputs: {
2397
+ type: string;
2398
+ name: string;
2399
+ }[];
2400
+ } | {
2401
+ type: string;
2402
+ name: string;
2403
+ constant: boolean;
2404
+ payable: boolean;
2405
+ inputs: {
2406
+ type: string;
2407
+ name: string;
2408
+ }[];
2409
+ outputs: any[];
2410
+ stateMutability?: undefined;
2411
+ })[];
2386
2412
  pmmarket: any[];
2387
2413
  pmtreasury: any[];
2388
2414
  pmblender: any[];
@@ -5313,6 +5339,31 @@ declare const getABI: (name: keyof typeof ABIS) => any[] | ({
5313
5339
  inputs?: undefined;
5314
5340
  name?: undefined;
5315
5341
  outputs?: undefined;
5342
+ })[] | ({
5343
+ type: string;
5344
+ name: string;
5345
+ constant: boolean;
5346
+ stateMutability: string;
5347
+ payable: boolean;
5348
+ inputs: {
5349
+ type: string;
5350
+ name: string;
5351
+ }[];
5352
+ outputs: {
5353
+ type: string;
5354
+ name: string;
5355
+ }[];
5356
+ } | {
5357
+ type: string;
5358
+ name: string;
5359
+ constant: boolean;
5360
+ payable: boolean;
5361
+ inputs: {
5362
+ type: string;
5363
+ name: string;
5364
+ }[];
5365
+ outputs: any[];
5366
+ stateMutability?: undefined;
5316
5367
  })[] | ({
5317
5368
  inputs: any[];
5318
5369
  stateMutability: string;
@@ -60,6 +60,8 @@ const LiquidEscrowedRAAC_json_1 = __importDefault(require("../artifacts/core/tok
60
60
  // Zap
61
61
  const AladdinZap_json_1 = __importDefault(require("../artifacts/zap/AladdinZap.sol/AladdinZap.json"));
62
62
  // PSM
63
+ // Testnet faucet (hand-written ABI, Sepolia only)
64
+ const Faucet_json_1 = __importDefault(require("../artifacts/faucet/Faucet.json"));
63
65
  const PSMVault_json_1 = __importDefault(require("../artifacts/core/psm/PSMVault.sol/PSMVault.json"));
64
66
  const RateProvider_json_1 = __importDefault(require("../artifacts/core/psm/RateProvider.sol/RateProvider.json"));
65
67
  const CRVUSD_ABI = crvUSDToken_json_1.default.abi;
@@ -147,6 +149,7 @@ const ABIS = {
147
149
  governance: Governance_json_1.default.abi,
148
150
  timelockcontroller: TimelockController_json_1.default.abi,
149
151
  // PM Market
152
+ faucet: Faucet_json_1.default.abi,
150
153
  pmmarket: PMMARKET_ABI,
151
154
  // PM Treasury
152
155
  pmtreasury: PMTREASURY_ABI,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raac/rpc",
3
- "version": "2.0.0-beta.17",
3
+ "version": "2.0.0-beta.19",
4
4
  "description": "RPC Library for RAAC",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/types/index.d.ts",