@raac/rpc 2.0.0-beta.12 → 2.0.0-beta.13

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 (82) hide show
  1. package/dist/RPCLibrary.js +53 -22
  2. package/dist/configs/chains/11155111.json +16 -41
  3. package/dist/contracts/complianceRegistry/getStatuses.js +40 -0
  4. package/dist/contracts/crvUSDToUSDOracle/getState.js +58 -0
  5. package/dist/contracts/curve/common/_helpers.js +57 -0
  6. package/dist/contracts/curve/common/addLiquidity.js +30 -0
  7. package/dist/contracts/curve/common/calcTokenAmount.js +23 -0
  8. package/dist/contracts/curve/common/calcWithdrawOneCoin.js +21 -0
  9. package/dist/contracts/curve/common/exchange.js +33 -0
  10. package/dist/contracts/curve/common/getDy.js +22 -0
  11. package/dist/contracts/curve/common/index.js +7 -0
  12. package/dist/contracts/curve/common/removeLiquidity.js +30 -0
  13. package/dist/contracts/curve/common/removeLiquidityOneCoin.js +31 -0
  14. package/dist/contracts/faucet/claim.js +37 -0
  15. package/dist/contracts/faucet/index.js +17 -0
  16. package/dist/contracts/feeCollector/getState.js +100 -0
  17. package/dist/contracts/getRoles.js +35 -0
  18. package/dist/contracts/housePrices/getState.js +41 -0
  19. package/dist/contracts/psm/getVaultSettings.js +60 -0
  20. package/dist/contracts/treasury/getState.js +46 -0
  21. package/dist/minter/emissionSchedule.js +90 -0
  22. package/dist/pools/lendingPool/getAdminState.js +47 -0
  23. package/dist/pools/rwaVault/getRegisteredAdapters.js +78 -0
  24. package/dist/pools/rwaVault/getSeedStatus.js +45 -0
  25. package/dist/pools/stabilityPool/getAdminState.js +42 -0
  26. package/dist/pools/stabilityPool/liquidation.js +297 -0
  27. package/dist/prices/tokenPricesUSD.js +0 -2
  28. package/dist/types/RPCLibrary.d.ts +44 -14
  29. package/dist/types/contracts/complianceRegistry/getStatuses.d.ts +25 -0
  30. package/dist/types/contracts/crvUSDToUSDOracle/getState.d.ts +36 -0
  31. package/dist/types/contracts/curve/common/_helpers.d.ts +10 -1
  32. package/dist/types/contracts/curve/common/addLiquidity.d.ts +14 -0
  33. package/dist/types/contracts/curve/common/calcTokenAmount.d.ts +10 -0
  34. package/dist/types/contracts/curve/common/calcWithdrawOneCoin.d.ts +8 -0
  35. package/dist/types/contracts/curve/common/exchange.d.ts +16 -0
  36. package/dist/types/contracts/curve/common/getDy.d.ts +8 -0
  37. package/dist/types/contracts/curve/common/index.d.ts +7 -0
  38. package/dist/types/contracts/curve/common/removeLiquidity.d.ts +14 -0
  39. package/dist/types/contracts/curve/common/removeLiquidityOneCoin.d.ts +15 -0
  40. package/dist/types/contracts/faucet/claim.d.ts +18 -0
  41. package/dist/types/contracts/faucet/index.d.ts +1 -0
  42. package/dist/types/contracts/feeCollector/getState.d.ts +42 -0
  43. package/dist/types/contracts/getRoles.d.ts +15 -0
  44. package/dist/types/contracts/housePrices/getState.d.ts +24 -0
  45. package/dist/types/contracts/psm/getVaultSettings.d.ts +38 -0
  46. package/dist/types/contracts/treasury/getState.d.ts +24 -0
  47. package/dist/types/minter/emissionSchedule.d.ts +53 -0
  48. package/dist/types/pools/lendingPool/getAdminState.d.ts +26 -0
  49. package/dist/types/pools/rwaVault/getRegisteredAdapters.d.ts +33 -0
  50. package/dist/types/pools/rwaVault/getSeedStatus.d.ts +27 -0
  51. package/dist/types/pools/stabilityPool/getAdminState.d.ts +25 -0
  52. package/dist/types/pools/stabilityPool/liquidation.d.ts +112 -0
  53. package/dist/types/typechain-types/contracts/core/collectors/index.d.ts +0 -2
  54. package/dist/types/typechain-types/contracts/mocks/core/tokens/index.d.ts +0 -1
  55. package/dist/types/typechain-types/factories/contracts/core/collectors/index.d.ts +0 -1
  56. package/dist/types/typechain-types/factories/contracts/mocks/core/tokens/index.d.ts +0 -1
  57. package/dist/types/typechain-types/index.d.ts +0 -4
  58. package/dist/types/utils/artifacts.d.ts +0 -198
  59. package/dist/utils/artifacts.js +0 -4
  60. package/package.json +14 -4
  61. package/dist/artifacts/core/collectors/fee-streamer/RentStreamer.sol/RentStreamer.json +0 -838
  62. package/dist/artifacts/mocks/core/tokens/USDCTokenLimited.sol/USDCTokenLimited.json +0 -558
  63. package/dist/contracts/rentStreamer/_helpers.js +0 -19
  64. package/dist/contracts/rentStreamer/getEpochProjection.js +0 -91
  65. package/dist/contracts/rentStreamer/getScheduled.js +0 -19
  66. package/dist/contracts/rentStreamer/getState.js +0 -40
  67. package/dist/contracts/rentStreamer/previewRelease.js +0 -23
  68. package/dist/contracts/rentStreamer/release.js +0 -22
  69. package/dist/contracts/rentStreamer/sync.js +0 -21
  70. package/dist/types/contracts/rentStreamer/_helpers.d.ts +0 -4
  71. package/dist/types/contracts/rentStreamer/getEpochProjection.d.ts +0 -40
  72. package/dist/types/contracts/rentStreamer/getScheduled.d.ts +0 -12
  73. package/dist/types/contracts/rentStreamer/getState.d.ts +0 -33
  74. package/dist/types/contracts/rentStreamer/previewRelease.d.ts +0 -20
  75. package/dist/types/contracts/rentStreamer/release.d.ts +0 -12
  76. package/dist/types/contracts/rentStreamer/sync.d.ts +0 -11
  77. package/dist/types/typechain-types/contracts/core/collectors/fee-streamer/RentStreamer.d.ts +0 -422
  78. package/dist/types/typechain-types/contracts/core/collectors/fee-streamer/index.d.ts +0 -1
  79. package/dist/types/typechain-types/contracts/mocks/core/tokens/USDCTokenLimited.d.ts +0 -238
  80. package/dist/types/typechain-types/factories/contracts/core/collectors/fee-streamer/RentStreamer__factory.d.ts +0 -665
  81. package/dist/types/typechain-types/factories/contracts/core/collectors/fee-streamer/index.d.ts +0 -1
  82. package/dist/types/typechain-types/factories/contracts/mocks/core/tokens/USDCTokenLimited__factory.d.ts +0 -439
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ethers_1 = require("ethers");
4
+ const contracts_1 = require("../../utils/contracts");
5
+ const artifacts_1 = require("../../utils/artifacts");
6
+ const getWithdrawTimelockConfig_1 = require("./getWithdrawTimelockConfig");
7
+ /**
8
+ * Owner, pause state, managers, linked contracts, liquidation split and withdraw timelock.
9
+ * @param chainId The chain id.
10
+ * @param provider The provider to read with.
11
+ * @throws When the configured address has no contract, which the generic decode error would hide.
12
+ */
13
+ async function getAdminState(chainId, provider) {
14
+ const address = (0, contracts_1.getContractAddress)(chainId, "stabilitypool");
15
+ if ((await provider.getCode(address)) === "0x")
16
+ throw new Error(`There is no contract at the configured stability pool address ${address}.`);
17
+ const sp = new ethers_1.ethers.Contract(address, (0, artifacts_1.getABI)("stabilitypool"), provider);
18
+ const [owner, paused, managers, rwaVault, liquidationStrategyProxy, liquidationSwap, feeCollector, split, timelock] = await Promise.all([
19
+ sp.owner(),
20
+ sp.paused(),
21
+ sp.getManagerList(),
22
+ sp.rwaVault(),
23
+ sp.liquidationStrategyProxy(),
24
+ sp.liquidationSwap(),
25
+ sp.feeCollector(),
26
+ sp.liquidationSplit(),
27
+ (0, getWithdrawTimelockConfig_1.getWithdrawTimelockConfig)(chainId, provider),
28
+ ]);
29
+ return {
30
+ owner,
31
+ paused,
32
+ managers: [...managers].map((m) => ethers_1.ethers.getAddress(m)),
33
+ rwaVault,
34
+ liquidationStrategyProxy,
35
+ liquidationSwap,
36
+ feeCollector,
37
+ split: { mintBps: split[0], burnBps: split[1], swapBps: split[2], liquidityBps: split[3] },
38
+ withdrawTimelockDuration: timelock.duration,
39
+ withdrawTimelockDelay: timelock.delay,
40
+ };
41
+ }
42
+ exports.default = getAdminState;
@@ -0,0 +1,297 @@
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.minSharesOut = exports.sameSplit = exports.splitTotal = exports.SPLIT_KEYS = void 0;
7
+ exports.readLiquidationContext = readLiquidationContext;
8
+ exports.readLiquidationTarget = readLiquidationTarget;
9
+ exports.quoteLiquidation = quoteLiquidation;
10
+ exports.suggestSplit = suggestSplit;
11
+ exports.simulateWithSplit = simulateWithSplit;
12
+ /**
13
+ * Liquidation simulation for StabilityPool.liquidateBorrower, mirroring LiquidationStrategyProxy:
14
+ * 1. the seized collateral is deposited into the RWAVault for vault-token shares, unless it already is the vault token;
15
+ * 2. the stability pool's whole vault-token balance (the proxy runs under delegatecall) is split by BPS into
16
+ * mint (treasury fee), burn, swap and liquidity (fee collector);
17
+ * 3. only the swap slice becomes crvUSD, through LiquidationSwap and its Curve pool;
18
+ * 3b. LiquidationSwap reverts when slippage protection is on and get_dy falls below pricePerShare / oracle price
19
+ * less its tolerance, which is the case when Curve trades below the vault's value;
20
+ * 4. the crvUSD must cover the position's debt; any shortfall is withdrawn from the LendingPool with the pool's
21
+ * rTokens, so stability pool depositors pay it, and the call reverts (InsufficientBalance) if they hold too few.
22
+ */
23
+ const ethers_1 = require("ethers");
24
+ const contracts_1 = require("../../utils/contracts");
25
+ const artifacts_1 = require("../../utils/artifacts");
26
+ const getAdapters_1 = __importDefault(require("../rwaVault/getAdapters"));
27
+ const getParameters_1 = __importDefault(require("../lendingPool/getParameters"));
28
+ const BPS = BigInt(10_000);
29
+ const WAD = BigInt(10) ** BigInt(18);
30
+ const ZERO = BigInt(0);
31
+ const SWAP_ABI = [
32
+ "function liquidityPool() view returns (address)",
33
+ "function swapToken() view returns (address)",
34
+ "function iIn() view returns (uint256)",
35
+ "function iOut() view returns (uint256)",
36
+ "function enableSlippageProtection() view returns (bool)",
37
+ "function slippageProtectionBps() view returns (uint256)",
38
+ "function crvusdToUSDOracle() view returns (address)",
39
+ ];
40
+ const CURVE_ABI = ["function get_dy(uint256 i, uint256 j, uint256 dx) view returns (uint256)", "function balances(uint256 i) view returns (uint256)"];
41
+ const VAULT_ABI = ["function underlyingVaultToken() view returns (address)", "function previewDeposit(uint256 assetAmount) view returns (uint256)", "function pricePerShare() view returns (uint256)"];
42
+ const VAULT_ADAPTER_ABI = ["function getAssetToken() view returns (address)", "function getAssetValue(bytes data) view returns (uint256)"];
43
+ const ADAPTER_ABI = [
44
+ "function getAssetToken() view returns (address)",
45
+ "function getAssetType() view returns (string)",
46
+ "function getAssetValue(address user, bytes data) view returns (uint256)",
47
+ "function balanceOf(address user) view returns (uint256)",
48
+ "function getDepositedTokens(address user) view returns (uint256[])",
49
+ ];
50
+ const ERC20_ABI = ["function balanceOf(address) view returns (uint256)"];
51
+ exports.SPLIT_KEYS = ["mintBps", "burnBps", "swapBps", "liquidityBps"];
52
+ const splitTotal = (s) => s.mintBps + s.burnBps + s.swapBps + s.liquidityBps;
53
+ exports.splitTotal = splitTotal;
54
+ const sameSplit = (a, b) => exports.SPLIT_KEYS.every((k) => a[k] === b[k]);
55
+ exports.sameSplit = sameSplit;
56
+ const contract = (address, abi, provider) => new ethers_1.ethers.Contract(address, abi, provider);
57
+ const decodeAmount = (data) => ethers_1.ethers.AbiCoder.defaultAbiCoder().decode(["uint256"], data)[0];
58
+ /** Reads the stability pool's liquidation route, split, balances and the LendingPool grace period. */
59
+ async function readLiquidationContext(chainId, provider) {
60
+ const stabilityPool = (0, contracts_1.getContractAddress)(chainId, "stabilitypool");
61
+ const sp = contract(stabilityPool, (0, artifacts_1.getABI)("stabilitypool"), provider);
62
+ const [liquidationSwap, rwaVault, split, rToken, params] = await Promise.all([
63
+ sp.liquidationSwap(),
64
+ sp.rwaVault(),
65
+ sp.liquidationSplit(),
66
+ sp.rToken(),
67
+ (0, getParameters_1.default)(chainId, provider),
68
+ ]);
69
+ if (liquidationSwap === ethers_1.ethers.ZeroAddress)
70
+ throw new Error("The stability pool has no LiquidationSwap set, so the swap leg reverts.");
71
+ const swap = contract(liquidationSwap, SWAP_ABI, provider);
72
+ const vault = contract(rwaVault, VAULT_ABI, provider);
73
+ const [liquidityPool, iIn, iOut, vaultToken, protect] = await Promise.all([
74
+ swap.liquidityPool(),
75
+ swap.iIn(),
76
+ swap.iOut(),
77
+ vault.underlyingVaultToken(),
78
+ swap.enableSlippageProtection(),
79
+ ]);
80
+ const slippage = protect
81
+ ? await Promise.all([
82
+ swap.slippageProtectionBps(),
83
+ vault.pricePerShare(),
84
+ swap.crvusdToUSDOracle().then((o) => contract(o, ["function getPrice() view returns (uint256)"], provider).getPrice()),
85
+ ]).then(([bps, pricePerShare, oraclePrice]) => ({ bps, pricePerShare, oraclePrice }))
86
+ : null;
87
+ if (liquidityPool === ethers_1.ethers.ZeroAddress)
88
+ throw new Error("LiquidationSwap has no Curve pool set, so the swap leg reverts.");
89
+ const [vaultSymbol, poolVaultTokens, rTokens] = await Promise.all([
90
+ contract(vaultToken, ["function symbol() view returns (string)"], provider).symbol().catch(() => "vault token"),
91
+ contract(vaultToken, ERC20_ABI, provider).balanceOf(stabilityPool),
92
+ contract(rToken, ERC20_ABI, provider).balanceOf(stabilityPool),
93
+ ]);
94
+ return {
95
+ stabilityPool,
96
+ liquidationSwap,
97
+ liquidityPool,
98
+ rwaVault,
99
+ vaultToken,
100
+ vaultSymbol,
101
+ iIn,
102
+ iOut,
103
+ split: { mintBps: split[0], burnBps: split[1], swapBps: split[2], liquidityBps: split[3] },
104
+ poolVaultTokens,
105
+ rTokens,
106
+ gracePeriod: Number(params.liquidationGracePeriod),
107
+ slippage,
108
+ };
109
+ }
110
+ /**
111
+ * Rebuilds the `data` the pool adapter expects. Position ids are "user:adapter:key" with `key` a hash, so the
112
+ * adapter's deposits are enumerated and matched against it (ERC721AssetAdapter keys are
113
+ * keccak256(abi.encodePacked(token, tokenId))). ERC20 adapters only accept the full deposited balance.
114
+ */
115
+ async function readLiquidationData(provider, poolAdapter, user, positionKey) {
116
+ const adapter = contract(poolAdapter, ADAPTER_ABI, provider);
117
+ const [assetType, assetToken] = await Promise.all([adapter.getAssetType(), adapter.getAssetToken()]);
118
+ const coder = ethers_1.ethers.AbiCoder.defaultAbiCoder();
119
+ if (assetType === "ERC721") {
120
+ const ids = [...(await adapter.getDepositedTokens(user))];
121
+ if (!ids.length)
122
+ throw new Error("The adapter holds no NFT collateral for this borrower anymore.");
123
+ const tokenId = positionKey ? ids.find((id) => ethers_1.ethers.solidityPackedKeccak256(["address", "uint256"], [assetToken, id]) === positionKey.toLowerCase()) : ids[0];
124
+ if (tokenId === undefined)
125
+ throw new Error("None of the borrower's deposited NFTs matches this position.");
126
+ return { data: coder.encode(["uint256"], [tokenId]), assetType, assetToken };
127
+ }
128
+ const balance = await adapter.balanceOf(user);
129
+ if (balance === ZERO)
130
+ throw new Error("The adapter holds no collateral for this borrower anymore.");
131
+ return { data: coder.encode(["uint256"], [balance]), assetType, assetToken };
132
+ }
133
+ /** The RWAVault adapter for the collateral's token; LiquidationStrategyProxy reverts (AdaptersAssetMismatch) otherwise. */
134
+ async function findVaultAdapter(chainId, provider, assetToken, vaultToken) {
135
+ const { adapters } = await (0, getAdapters_1.default)(chainId, provider);
136
+ for (const candidate of adapters) {
137
+ const token = await contract(candidate, VAULT_ADAPTER_ABI, provider).getAssetToken().catch(() => null);
138
+ if (token?.toLowerCase() === assetToken.toLowerCase())
139
+ return ethers_1.ethers.getAddress(candidate);
140
+ }
141
+ // Vault-token collateral skips the deposit, so any adapter passes the proxy's check.
142
+ if (assetToken.toLowerCase() === vaultToken.toLowerCase() && adapters.length)
143
+ return ethers_1.ethers.getAddress(adapters[0]);
144
+ throw new Error("No RWAVault adapter accepts this collateral's token, so the deposit would revert.");
145
+ }
146
+ /** Assembles liquidateBorrower's arguments and the position's state for one position id ("user:adapter:key"). */
147
+ async function readLiquidationTarget(chainId, provider, ctx, positionId) {
148
+ const [user, poolAdapter, positionKey] = positionId.split(":");
149
+ const { data, assetType, assetToken } = await readLiquidationData(provider, poolAdapter, user, positionKey);
150
+ const pool = contract((0, contracts_1.getContractAddress)(chainId, "lendingpool"), (0, artifacts_1.getABI)("lendingpool"), provider);
151
+ const [vaultAdapter, collateralValue, debt, position] = await Promise.all([
152
+ findVaultAdapter(chainId, provider, assetToken, ctx.vaultToken),
153
+ contract(poolAdapter, ADAPTER_ABI, provider).getAssetValue(user, data),
154
+ pool.getPositionScaledDebt(poolAdapter, user, data),
155
+ pool.getPosition(poolAdapter, user, data),
156
+ ]);
157
+ return {
158
+ poolAdapter: ethers_1.ethers.getAddress(poolAdapter),
159
+ vaultAdapter,
160
+ user: ethers_1.ethers.getAddress(user),
161
+ data,
162
+ assetType,
163
+ assetToken,
164
+ isVaultToken: assetToken.toLowerCase() === ctx.vaultToken.toLowerCase(),
165
+ collateralValue,
166
+ debt,
167
+ isUnderLiquidation: position.isUnderLiquidation,
168
+ isInsured: position.isInsured,
169
+ liquidationStartTime: Number(position.liquidationStartTime),
170
+ };
171
+ }
172
+ async function quoteDy(provider, ctx, amount) {
173
+ if (amount <= ZERO)
174
+ return ZERO;
175
+ return contract(ctx.liquidityPool, CURVE_ABI, provider).get_dy(ctx.iIn, ctx.iOut, amount).catch(() => null);
176
+ }
177
+ /** Prices the liquidation with `split`, using the deployed Curve pool's get_dy rather than the vault's oracle price. */
178
+ async function quoteLiquidation(provider, ctx, target, split) {
179
+ // poolDepositAsset mints from the vault adapter's own valuation, which may use a different oracle than the pool's.
180
+ const sharesFromCollateral = target.isVaultToken
181
+ ? decodeAmount(target.data)
182
+ : await contract(ctx.rwaVault, VAULT_ABI, provider).previewDeposit(await contract(target.vaultAdapter, VAULT_ADAPTER_ABI, provider).getAssetValue(target.data));
183
+ const totalVaultTokens = sharesFromCollateral + ctx.poolVaultTokens;
184
+ const swapAmount = (totalVaultTokens * split.swapBps) / BPS;
185
+ const [swapOut, maxSwapOut, spotOut, poolReserveOut] = await Promise.all([
186
+ quoteDy(provider, ctx, swapAmount),
187
+ quoteDy(provider, ctx, totalVaultTokens),
188
+ quoteDy(provider, ctx, WAD),
189
+ contract(ctx.liquidityPool, CURVE_ABI, provider).balances(ctx.iOut).catch(() => null),
190
+ ]);
191
+ let priceImpactBps = null;
192
+ if (swapOut !== null && spotOut && swapAmount > ZERO) {
193
+ const realised = (swapOut * WAD) / swapAmount;
194
+ priceImpactBps = realised >= spotOut ? ZERO : ((spotOut - realised) * BPS) / spotOut;
195
+ }
196
+ return {
197
+ split,
198
+ sharesFromCollateral,
199
+ totalVaultTokens,
200
+ swapAmount,
201
+ swapOut,
202
+ minSwapOut: ctx.slippage && swapAmount > ZERO ? ((ctx.slippage.pricePerShare * swapAmount) / ctx.slippage.oraclePrice) * (BPS - ctx.slippage.bps) / BPS : null,
203
+ shortfall: swapOut === null ? target.debt : swapOut >= target.debt ? ZERO : target.debt - swapOut,
204
+ coversDebt: swapOut !== null && swapOut >= target.debt,
205
+ badDebt: target.collateralValue < target.debt ? target.debt - target.collateralValue : ZERO,
206
+ maxSwapOut,
207
+ priceImpactBps,
208
+ poolReserveOut,
209
+ };
210
+ }
211
+ /**
212
+ * The smallest swap share whose get_dy still covers the debt plus `bufferBps`, with the rest given back to mint,
213
+ * burn and liquidity in their current proportion. get_dy grows with dx, so a binary search over BPS is sound.
214
+ */
215
+ async function suggestSplit(provider, ctx, target, quote, bufferBps = BigInt(100)) {
216
+ if (quote.totalVaultTokens <= ZERO)
217
+ return null;
218
+ const required = (target.debt * (BPS + bufferBps)) / BPS;
219
+ const spread = (swapBps, projectedOut, bestEffort) => {
220
+ const rest = BPS - swapBps;
221
+ const others = ctx.split.mintBps + ctx.split.burnBps + ctx.split.liquidityBps;
222
+ const mintBps = others === ZERO ? ZERO : (rest * ctx.split.mintBps) / others;
223
+ const burnBps = others === ZERO ? ZERO : (rest * ctx.split.burnBps) / others;
224
+ return { mintBps, burnBps, swapBps, liquidityBps: rest - mintBps - burnBps, projectedOut, bestEffort };
225
+ };
226
+ const full = quote.maxSwapOut ?? (await quoteDy(provider, ctx, quote.totalVaultTokens));
227
+ if (full === null)
228
+ return null;
229
+ if (full < required)
230
+ return spread(BPS, full, true);
231
+ let low = ZERO;
232
+ let high = BPS;
233
+ let best = full;
234
+ while (low < high) {
235
+ const mid = (low + high) / BigInt(2);
236
+ const out = await quoteDy(provider, ctx, (quote.totalVaultTokens * mid) / BPS);
237
+ if (out !== null && out >= required) {
238
+ high = mid;
239
+ best = out;
240
+ }
241
+ else {
242
+ low = mid + BigInt(1);
243
+ }
244
+ }
245
+ return spread(low, best, false);
246
+ }
247
+ /** minSharesOut for the RWAVault deposit: previewDeposit less `slippageBps`. Zero when nothing is deposited. */
248
+ const minSharesOut = (target, quote, slippageBps) => (target.isVaultToken ? ZERO : (quote.sharesFromCollateral * (BPS - slippageBps)) / BPS);
249
+ exports.minSharesOut = minSharesOut;
250
+ // StabilityPoolStorage is inherited first and the OpenZeppelin parents use namespaced storage, so liquidationSplit
251
+ // takes slots 10 to 13. Checked against the live split before it is relied on.
252
+ const SPLIT_SLOT = 10;
253
+ /**
254
+ * Simulates liquidateBorrower from `sender` with the split overridden in storage (an eth_call state override), so a
255
+ * split change in the same batch is simulated rather than only checked. Returns null when the RPC or the storage
256
+ * layout cannot be used; otherwise the revert reason, or "" when it succeeds.
257
+ */
258
+ async function simulateWithSplit(provider, ctx, sender, data, split) {
259
+ const send = provider.send?.bind(provider);
260
+ if (!send)
261
+ return null;
262
+ const slot = (i) => ethers_1.ethers.toBeHex(SPLIT_SLOT + i, 32);
263
+ try {
264
+ const live = await Promise.all(exports.SPLIT_KEYS.map((_, i) => provider.getStorage(ctx.stabilityPool, SPLIT_SLOT + i)));
265
+ if (exports.SPLIT_KEYS.some((k, i) => BigInt(live[i]) !== ctx.split[k]))
266
+ return null;
267
+ }
268
+ catch {
269
+ return null;
270
+ }
271
+ const stateDiff = Object.fromEntries(exports.SPLIT_KEYS.map((k, i) => [slot(i), ethers_1.ethers.toBeHex(split[k], 32)]));
272
+ try {
273
+ await send("eth_call", [{ from: sender, to: ctx.stabilityPool, data }, "latest", { [ctx.stabilityPool]: { stateDiff } }]);
274
+ return "";
275
+ }
276
+ catch (error) {
277
+ if (!ethers_1.ethers.isError(error, "CALL_EXCEPTION"))
278
+ return null;
279
+ return (error.data && attemptParse(error.data)) || error.reason || error.shortMessage;
280
+ }
281
+ }
282
+ function attemptParse(data) {
283
+ for (const key of ["stabilitypool", "lendingpool"]) {
284
+ try {
285
+ const e = new ethers_1.ethers.Interface((0, artifacts_1.getABI)(key)).parseError(data);
286
+ if (e)
287
+ return e.name === "Error" ? String(e.args[0]) : e.name;
288
+ }
289
+ catch { }
290
+ }
291
+ try {
292
+ return ethers_1.ethers.AbiCoder.defaultAbiCoder().decode(["string"], ethers_1.ethers.dataSlice(data, 4))[0];
293
+ }
294
+ catch {
295
+ return null;
296
+ }
297
+ }
@@ -11,8 +11,6 @@ exports.TOKEN_PRICES_USD = {
11
11
  pmusd: 1,
12
12
  crvusd: 1, // same token the chain config's asset registry displays as pmUSD
13
13
  ireet: 1, // RWA index token (NAV ~ 0.995, rounded to 1 for display)
14
- usdc: 1,
15
- leraac: 5,
16
14
  };
17
15
  /** Static USD price for a token symbol (0 if unknown). */
18
16
  function getTokenPriceUSD(symbol) {
@@ -88,12 +88,7 @@ import { quoteBuy } from "./contracts/zeno/quoteBuy";
88
88
  import { ChainId } from "./configs/chains";
89
89
  import getBaseUri from "./nfts/getBaseUri";
90
90
  import claimRewardFromPool from "./contracts/feeCollector/claimRewardFromPool";
91
- import { getState as getStateRentStreamer } from "./contracts/rentStreamer/getState";
92
- import { previewRelease as previewReleaseRentStreamer } from "./contracts/rentStreamer/previewRelease";
93
- import { getScheduled as getScheduledRentStreamer } from "./contracts/rentStreamer/getScheduled";
94
- import { getEpochProjection as getEpochProjectionRentStreamer } from "./contracts/rentStreamer/getEpochProjection";
95
- import { sync as syncRentStreamer } from "./contracts/rentStreamer/sync";
96
- import { release as releaseRentStreamer } from "./contracts/rentStreamer/release";
91
+ import getFeeCollectorState from "./contracts/feeCollector/getState";
97
92
  import getRawUserDepositsInLendingPool from "./pools/lendingPool/getRawUserDepositsInLendingPool";
98
93
  import getRawUserDepositInStabilityPool from "./pools/stabilityPool/getRawUserDepositsInStabilityPool";
99
94
  import getEligibleUserDeposits from "./pools/lendingPool/getEligibleUserDeposits";
@@ -130,6 +125,18 @@ import { getWithdrawRequestInfo as getStabilityPoolWithdrawRequestInfo } from ".
130
125
  import { getWithdrawTimelockConfig as getStabilityPoolWithdrawTimelockConfig } from "./pools/stabilityPool/getWithdrawTimelockConfig";
131
126
  import { requestWithdraw as requestStabilityPoolWithdraw } from "./pools/stabilityPool/requestWithdraw";
132
127
  import { getVaultInfo as getPsmVaultInfo } from "./contracts/psm/getVaultInfo";
128
+ import { getVaultSettings as getPsmVaultSettings } from "./contracts/psm/getVaultSettings";
129
+ import getHousePricesState from "./contracts/housePrices/getState";
130
+ import getCrvUSDToUSDOracleState from "./contracts/crvUSDToUSDOracle/getState";
131
+ import getRoles from "./contracts/getRoles";
132
+ import getTreasuryState from "./contracts/treasury/getState";
133
+ import getComplianceStatuses from "./contracts/complianceRegistry/getStatuses";
134
+ import getStabilityPoolAdminState from "./pools/stabilityPool/getAdminState";
135
+ import { readLiquidationContext, readLiquidationTarget, quoteLiquidation, suggestSplit, simulateWithSplit, minSharesOut } from "./pools/stabilityPool/liquidation";
136
+ import { getEmissionSchedule, getSchedulePosition, getEmissionPerSecondForWeek, getMintingWeekForTimestamp } from "./minter/emissionSchedule";
137
+ import getRWAVaultRegisteredAdapters from "./pools/rwaVault/getRegisteredAdapters";
138
+ import getRWAVaultSeedStatus from "./pools/rwaVault/getSeedStatus";
139
+ import getLendingPoolAdminState from "./pools/lendingPool/getAdminState";
133
140
  import { previewDeposit as previewDepositPsm } from "./contracts/psm/previewDeposit";
134
141
  import { previewRedeem as previewRedeemPsm } from "./contracts/psm/previewRedeem";
135
142
  import { previewSwap as previewSwapPsm } from "./contracts/psm/previewSwap";
@@ -146,6 +153,7 @@ import * as gaugeMethods from "./contracts/governance/gauge";
146
153
  import * as controllerMethods from "./contracts/governance/gaugeController";
147
154
  import * as gaugeSystemMethods from "./contracts/governance/gaugeSystems";
148
155
  import * as curveCommonMethods from "./contracts/curve/common";
156
+ import * as faucetMethods from "./contracts/faucet";
149
157
  import * as userMethods from "./user";
150
158
  import { cancel as cancelProposals } from "./contracts/governance/proposals/cancel";
151
159
  import { getQuorumNumerator as getQuorumNumeratorProposals } from "./contracts/governance/proposals/getQuorumNumerator";
@@ -327,6 +335,7 @@ declare class RPCLibrary {
327
335
  curve: {
328
336
  common: typeof curveCommonMethods;
329
337
  };
338
+ faucet: typeof faucetMethods;
330
339
  user: typeof userMethods;
331
340
  prices: {
332
341
  getPrices: typeof getPrices;
@@ -377,8 +386,19 @@ declare class RPCLibrary {
377
386
  contracts: {
378
387
  housePrices: {
379
388
  getLatestPrice: typeof getLatestPrice;
389
+ getState: typeof getHousePricesState;
380
390
  setOracle: typeof setOracle;
381
391
  };
392
+ crvUSDToUSDOracle: {
393
+ getState: typeof getCrvUSDToUSDOracleState;
394
+ };
395
+ treasury: {
396
+ getState: typeof getTreasuryState;
397
+ };
398
+ complianceRegistry: {
399
+ getStatuses: typeof getComplianceStatuses;
400
+ };
401
+ getRoles: typeof getRoles;
382
402
  minter: {
383
403
  tick: typeof tick;
384
404
  get: typeof get;
@@ -394,6 +414,10 @@ declare class RPCLibrary {
394
414
  calculateScheduledMintableAmount: typeof calculateScheduledMintableAmountMinter;
395
415
  getEmissionPerSecond: typeof getEmissionPerSecondMinter;
396
416
  isPaused: typeof isPausedMinter;
417
+ getEmissionSchedule: typeof getEmissionSchedule;
418
+ getSchedulePosition: typeof getSchedulePosition;
419
+ getEmissionPerSecondForWeek: typeof getEmissionPerSecondForWeek;
420
+ getMintingWeekForTimestamp: typeof getMintingWeekForTimestamp;
397
421
  };
398
422
  getContractAddress: typeof getContractAddress;
399
423
  getContract: typeof getContract;
@@ -404,14 +428,7 @@ declare class RPCLibrary {
404
428
  getTokenMetadata: typeof getTokenMetadata;
405
429
  feeCollector: {
406
430
  claimRewardFromPool: typeof claimRewardFromPool;
407
- };
408
- rentStreamer: {
409
- getState: typeof getStateRentStreamer;
410
- previewRelease: typeof previewReleaseRentStreamer;
411
- getScheduled: typeof getScheduledRentStreamer;
412
- getEpochProjection: typeof getEpochProjectionRentStreamer;
413
- sync: typeof syncRentStreamer;
414
- release: typeof releaseRentStreamer;
431
+ getState: typeof getFeeCollectorState;
415
432
  };
416
433
  getABI: typeof getABI;
417
434
  pmTreasury: {
@@ -639,6 +656,7 @@ declare class RPCLibrary {
639
656
  };
640
657
  psm: {
641
658
  getVaultInfo: typeof getPsmVaultInfo;
659
+ getVaultSettings: typeof getPsmVaultSettings;
642
660
  previewDeposit: typeof previewDepositPsm;
643
661
  previewRedeem: typeof previewRedeemPsm;
644
662
  previewSwap: typeof previewSwapPsm;
@@ -658,6 +676,15 @@ declare class RPCLibrary {
658
676
  getWithdrawRequestInfo: typeof getStabilityPoolWithdrawRequestInfo;
659
677
  getWithdrawTimelockConfig: typeof getStabilityPoolWithdrawTimelockConfig;
660
678
  requestWithdraw: typeof requestStabilityPoolWithdraw;
679
+ getAdminState: typeof getStabilityPoolAdminState;
680
+ liquidation: {
681
+ getContext: typeof readLiquidationContext;
682
+ getTarget: typeof readLiquidationTarget;
683
+ quote: typeof quoteLiquidation;
684
+ suggestSplit: typeof suggestSplit;
685
+ simulateWithSplit: typeof simulateWithSplit;
686
+ minSharesOut: typeof minSharesOut;
687
+ };
661
688
  };
662
689
  lendingPool: {
663
690
  getAdapters: typeof getAdapters;
@@ -668,6 +695,7 @@ declare class RPCLibrary {
668
695
  depositAssetToLendingPool: typeof depositAssetToLendingPool;
669
696
  withdrawAssetFromLendingPool: typeof withdrawAssetFromLendingPool;
670
697
  getLendingPoolInfo: typeof getLendingPoolInfo;
698
+ getAdminState: typeof getLendingPoolAdminState;
671
699
  getRawUserDepositsInLendingPool: typeof getRawUserDepositsInLendingPool;
672
700
  getEligibleUserDeposits: typeof getEligibleUserDeposits;
673
701
  getHealthFactor: typeof getHealthFactor;
@@ -695,6 +723,8 @@ declare class RPCLibrary {
695
723
  depositToRWAVault: typeof depositToRWAVault;
696
724
  redeemNFTFromRWAVault: typeof redeemNFTFromRWAVault;
697
725
  getRWAVaultInfo: typeof getRWAVaultInfo;
726
+ getRegisteredAdapters: typeof getRWAVaultRegisteredAdapters;
727
+ getSeedStatus: typeof getRWAVaultSeedStatus;
698
728
  getNextRandomNFT: typeof getNextRandomNFT;
699
729
  checkRedeemEligibility: typeof checkRWAVaultRedeemEligibility;
700
730
  requestRandomSeed: typeof requestRandomSeed;
@@ -0,0 +1,25 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../configs/chains/index";
3
+ /** Whether an address is blocked by the ComplianceRegistry, and why. */
4
+ export interface ComplianceStatus {
5
+ address: string;
6
+ /** `isBlacklisted`: on the registry's own list, or sanctioned. */
7
+ blocked: boolean;
8
+ /** On the registry's own list; null when its storage layout could not be confirmed. */
9
+ listed: boolean | null;
10
+ /** On the external sanctions list; unblacklisting does not clear this. */
11
+ sanctioned: boolean;
12
+ }
13
+ /**
14
+ * Reads the sanctions list and each address's compliance status. `_blacklisted` is private, so the own-list flag is
15
+ * read from storage, trusted only when slot 2 matches `sanctionsList()`; otherwise `listed` is null where it cannot
16
+ * be told apart from a sanction.
17
+ * @param chainId The chain id.
18
+ * @param addresses The addresses to check.
19
+ * @param provider The provider to read with.
20
+ */
21
+ declare function getStatuses(chainId: ChainId, addresses: readonly string[], provider: Provider): Promise<{
22
+ sanctionsList: string;
23
+ statuses: ComplianceStatus[];
24
+ }>;
25
+ export default getStatuses;
@@ -0,0 +1,36 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../configs/chains/index";
3
+ /** Which route the crvUSD/USD price came from, as `getLatestPrice`'s third value reports it. */
4
+ export declare const CRVUSD_PRICE_SOURCES: readonly ["chainlink", "curve", "fallback"];
5
+ export type CrvUSDPriceSource = (typeof CRVUSD_PRICE_SOURCES)[number];
6
+ /** CrvUSDToUSDOracle state. Prices are 18-decimal USD; times are seconds. */
7
+ export interface CrvUSDToUSDOracleState {
8
+ owner: string;
9
+ /** Null when every route reverts. */
10
+ price: bigint | null;
11
+ priceTimestamp: number | null;
12
+ source: CrvUSDPriceSource | null;
13
+ circuitBreakerEnabled: boolean;
14
+ minPriceThreshold: bigint;
15
+ maxPriceThreshold: bigint;
16
+ fallbackPriceInUSD: bigint;
17
+ lastFallbackUpdateTimestamp: number;
18
+ /** How stale the Chainlink crvUSD/USD feed may be before the Curve route is tried. */
19
+ maxStableStaleTime: bigint;
20
+ /** How stale the ETH/USD feed may be before the fallback price is used. */
21
+ maxUnstableStaleTime: bigint;
22
+ crvUSDDataFeed: string;
23
+ ethDataFeed: string;
24
+ curveOracle: string;
25
+ /** Coin index the Curve oracle prices ETH in. */
26
+ K: bigint;
27
+ }
28
+ /**
29
+ * Reads the crvUSD/USD oracle's current price and route and every setting behind them. A reverting price read gives
30
+ * `price: null` instead of failing, since that is exactly when the settings matter.
31
+ * @param chainId The chain id.
32
+ * @param provider The provider to read with.
33
+ * @param oracleAddress Optional address, e.g. from `housePrices.getState`; defaults to the registry's `crvusdtousdoracle`.
34
+ */
35
+ declare function getState(chainId: ChainId, provider: Provider, oracleAddress?: string): Promise<CrvUSDToUSDOracleState>;
36
+ export default getState;
@@ -1,4 +1,4 @@
1
- import { ethers, Provider } from "ethers";
1
+ import { ethers, Provider, Signer } from "ethers";
2
2
  import { ChainId } from "../../../configs/chains";
3
3
  import { CurvePoolEntry, CurvePools } from "../../../configs/chains/chain";
4
4
  /**
@@ -14,3 +14,12 @@ export declare function getCurvePoolContract(chainId: ChainId, poolAddressOrId:
14
14
  contract: ethers.Contract;
15
15
  provider: ethers.Provider;
16
16
  };
17
+ /** The pool contract with its flavour's swap and liquidity ABI, bound to a signer or provider. */
18
+ export declare function getCurvePoolFlavourContract(chainId: ChainId, poolAddressOrId: string, runner?: Signer | Provider): {
19
+ entry: CurvePoolEntry;
20
+ contract: ethers.Contract;
21
+ };
22
+ /** Checks an amounts array matches the pool's coin count before it reaches the encoder. */
23
+ export declare function assertCoinCount(entry: CurvePoolEntry, amounts: readonly bigint[], what: string): void;
24
+ /** Checks a coin index is inside the pool. */
25
+ export declare function assertCoinIndex(entry: CurvePoolEntry, index: number): void;
@@ -0,0 +1,14 @@
1
+ import { Signer } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * Deposits coins into a Curve pool for LP tokens. The caller approves each non-zero coin to the pool first.
5
+ *
6
+ * @param chainId - The chain/network to use.
7
+ * @param poolAddressOrId - The pool's key in the chain config's `curve` section, or its address.
8
+ * @param amounts - One amount per coin, in pool order and each coin's base units; 0 for a coin not deposited.
9
+ * @param minMintAmount - The least LP to accept (18 decimals); the deposit reverts below it. See `calcTokenAmount`.
10
+ * @param receiver - Who receives the LP tokens.
11
+ * @param signer - The signer sending the transaction.
12
+ * @returns The mined transaction receipt.
13
+ */
14
+ export declare const addLiquidity: (chainId: ChainId, poolAddressOrId: string, amounts: bigint[], minMintAmount: bigint, receiver: string, signer: Signer) => Promise<any>;
@@ -0,0 +1,10 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * LP tokens a deposit (or, with `isDeposit` false, a proportional withdrawal) of `amounts` mints or burns at the
5
+ * pool's current state. Fees are not included, so apply a slippage margin before using it as a minimum.
6
+ *
7
+ * @param amounts - One amount per coin, in pool order and each coin's base units.
8
+ * @returns LP tokens (18 decimals).
9
+ */
10
+ export declare const calcTokenAmount: (chainId: ChainId, poolAddressOrId: string, amounts: bigint[], isDeposit: boolean, provider?: Provider) => Promise<bigint>;
@@ -0,0 +1,8 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * How much of coin `i` burning `lpAmount` LP tokens returns at the pool's current state.
5
+ *
6
+ * @returns The output amount in coin `i`'s base units.
7
+ */
8
+ export declare const calcWithdrawOneCoin: (chainId: ChainId, poolAddressOrId: string, lpAmount: bigint, i: number, provider?: Provider) => Promise<bigint>;
@@ -0,0 +1,16 @@
1
+ import { Signer } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * Swaps `amountIn` of coin `i` for coin `j` in a Curve pool. The caller approves coin `i` to the pool first.
5
+ *
6
+ * @param chainId - The chain/network to use.
7
+ * @param poolAddressOrId - The pool's key in the chain config's `curve` section, or its address.
8
+ * @param i - Index of the coin sold, in pool order.
9
+ * @param j - Index of the coin bought, in pool order.
10
+ * @param amountIn - Amount of coin `i`, in its base units.
11
+ * @param minAmountOut - The least of coin `j` to accept, in its base units; the swap reverts below it.
12
+ * @param receiver - Who receives coin `j`.
13
+ * @param signer - The signer sending the transaction.
14
+ * @returns The mined transaction receipt.
15
+ */
16
+ export declare const exchange: (chainId: ChainId, poolAddressOrId: string, i: number, j: number, amountIn: bigint, minAmountOut: bigint, receiver: string, signer: Signer) => Promise<any>;
@@ -0,0 +1,8 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * How much of coin `j` a swap of `amountIn` of coin `i` returns at the pool's current state, before slippage.
5
+ *
6
+ * @returns The output amount in coin `j`'s base units.
7
+ */
8
+ export declare const getDy: (chainId: ChainId, poolAddressOrId: string, i: number, j: number, amountIn: bigint, provider?: Provider) => Promise<bigint>;
@@ -1,2 +1,9 @@
1
+ export * from "./addLiquidity";
2
+ export * from "./calcTokenAmount";
3
+ export * from "./calcWithdrawOneCoin";
4
+ export * from "./exchange";
5
+ export * from "./getDy";
1
6
  export * from "./getPools";
2
7
  export * from "./getVirtualPrice";
8
+ export * from "./removeLiquidity";
9
+ export * from "./removeLiquidityOneCoin";
@@ -0,0 +1,14 @@
1
+ import { Signer } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * Burns LP tokens for every coin of a Curve pool in proportion to its balances.
5
+ *
6
+ * @param chainId - The chain/network to use.
7
+ * @param poolAddressOrId - The pool's key in the chain config's `curve` section, or its address.
8
+ * @param lpAmount - LP tokens to burn (18 decimals).
9
+ * @param minAmounts - The least of each coin to accept, in pool order and each coin's base units.
10
+ * @param receiver - Who receives the coins.
11
+ * @param signer - The signer sending the transaction.
12
+ * @returns The mined transaction receipt.
13
+ */
14
+ export declare const removeLiquidity: (chainId: ChainId, poolAddressOrId: string, lpAmount: bigint, minAmounts: bigint[], receiver: string, signer: Signer) => Promise<any>;