@augustdigital/sdk 9.10.1 → 9.11.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/README.md +8 -6
- package/lib/adapters/evm/index.d.ts +11 -3
- package/lib/adapters/evm/index.js +11 -3
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/helpers/swap-router.d.ts +17 -0
- package/lib/core/helpers/swap-router.js +44 -0
- package/lib/modules/vaults/write.actions.d.ts +27 -17
- package/lib/modules/vaults/write.actions.js +45 -16
- package/lib/sdk.d.ts +40 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,19 +109,21 @@ const { registered, originFeeBps, collector } = await sdk.getOriginInfo({
|
|
|
109
109
|
- **Where it applies.** `vaultDeposit` sends a deposit through `SwapRouter.deposit` with the code when
|
|
110
110
|
`sdk.evm.getDepositRoute()` returns `via: 'router'`: the vault is registered on the router, the vault accepts
|
|
111
111
|
the asset as-is (its reference asset, or a Tokenized Vault V2 whitelisted asset — never swapped), the router
|
|
112
|
-
whitelists the asset, the deposit is not a permit, native-token or adapter deposit,
|
|
113
|
-
registered. `swapRouterDeposit`, `swapAndDeposit`, `depositViaSwapRouter` and `depositNativeViaSwapRouter`
|
|
112
|
+
whitelists the asset, the router is not paused, the deposit is not a permit, native-token or adapter deposit,
|
|
113
|
+
and the code is registered. `swapRouterDeposit`, `swapAndDeposit`, `depositViaSwapRouter` and `depositNativeViaSwapRouter`
|
|
114
114
|
send it too.
|
|
115
115
|
- **Precedence.** An `originCode` passed to a router method wins, then the instance code, then the all-zero
|
|
116
116
|
sentinel (no origin fee). Pass the zero sentinel to opt one call out.
|
|
117
117
|
- **Fallback.** When the code cannot be applied — it is not registered, the chain is not mainnet, the router
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
is paused (`router-paused`, checked with a 15-second cache) or does not whitelist the asset, the vault does
|
|
119
|
+
not accept it or is not registered on the router, or it is a permit, native-token or adapter deposit —
|
|
120
|
+
`vaultDeposit` takes the vault's native path and logs
|
|
120
121
|
`vaultDeposit:attribution-skipped` with the reason (Sentry tag `sdk.attribution.origin=skipped`). The router
|
|
121
122
|
methods send the zero sentinel for an unregistered instance code and log `<method>:attribution-skipped`.
|
|
122
123
|
With `strictOrigin: true` an unregistered instance code throws `AugustValidationError` before any approval
|
|
123
|
-
instead. An `originCode` passed to a router method that is
|
|
124
|
-
`AugustValidationError` before any approval.
|
|
124
|
+
instead; a paused router falls back to native even then. An `originCode` passed to a router method that is
|
|
125
|
+
not registered always throws `AugustValidationError` before any approval. While the router is paused, the
|
|
126
|
+
router methods throw `AugustSDKError` (`context.reason: 'router-paused'`) before any approval.
|
|
125
127
|
- **Approve `route.spender`, not the vault.** A routed deposit is pulled by the SwapRouter. `vaultDeposit` and
|
|
126
128
|
`approve` handle this; if you send approvals yourself, read the spender first:
|
|
127
129
|
|
|
@@ -106,9 +106,10 @@ declare class EVMAdapter {
|
|
|
106
106
|
* (`route.spender`, not necessarily the vault). See {@link getDepositRoute}.
|
|
107
107
|
*
|
|
108
108
|
* @param options - {@link IGetDepositRouteOptions}.
|
|
109
|
-
* @returns `{ via, spender, reason? }` — `reason` explains a native route
|
|
109
|
+
* @returns `{ via, spender, reason? }` — `reason` explains a native route
|
|
110
|
+
* (`router-paused` while the SwapRouter is paused).
|
|
110
111
|
* @throws AugustValidationError on an invalid target, or an unregistered
|
|
111
|
-
* code under `attribution.strictOrigin
|
|
112
|
+
* code under `attribution.strictOrigin` while the router is not paused.
|
|
112
113
|
* @throws AugustSDKError when a backend, vault or router read fails.
|
|
113
114
|
* @example
|
|
114
115
|
* ```ts
|
|
@@ -174,7 +175,8 @@ declare class EVMAdapter {
|
|
|
174
175
|
* @param options - {@link ISwapAndDepositOptions}.
|
|
175
176
|
* @returns The transaction hash of the `swapAndDeposit` call.
|
|
176
177
|
* @throws AugustValidationError on invalid inputs (bad chain, empty swaps).
|
|
177
|
-
* @throws AugustSDKError
|
|
178
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
179
|
+
* approval), or on RPC / contract revert.
|
|
178
180
|
*
|
|
179
181
|
* @example
|
|
180
182
|
* ```ts
|
|
@@ -198,6 +200,8 @@ declare class EVMAdapter {
|
|
|
198
200
|
*
|
|
199
201
|
* @param options - {@link ISwapRouterDirectDepositOptions}.
|
|
200
202
|
* @returns The transaction hash of the `deposit` call.
|
|
203
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
204
|
+
* approval), or on RPC / contract revert.
|
|
201
205
|
*/
|
|
202
206
|
depositViaSwapRouter(options: ISwapRouterDirectDepositOptions): Promise<string>;
|
|
203
207
|
/**
|
|
@@ -207,6 +211,8 @@ declare class EVMAdapter {
|
|
|
207
211
|
*
|
|
208
212
|
* @param options - {@link ISwapRouterNativeDepositOptions}.
|
|
209
213
|
* @returns The transaction hash of the `depositNativeToken` call.
|
|
214
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
215
|
+
* approval), or on RPC / contract revert.
|
|
210
216
|
*/
|
|
211
217
|
depositNativeViaSwapRouter(options: ISwapRouterNativeDepositOptions): Promise<string>;
|
|
212
218
|
/**
|
|
@@ -224,6 +230,8 @@ declare class EVMAdapter {
|
|
|
224
230
|
* @returns The transaction hash of the router deposit call.
|
|
225
231
|
* @throws AugustValidationError on unsupported chain, invalid address, zero
|
|
226
232
|
* amount, a native deposit into a non-wrapped-native vault, or quote drift.
|
|
233
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
234
|
+
* approval), or on RPC / contract revert.
|
|
227
235
|
* @example
|
|
228
236
|
* ```ts
|
|
229
237
|
* const hash = await augustSdk.evm.swapRouterDeposit({
|
|
@@ -154,9 +154,10 @@ class EVMAdapter {
|
|
|
154
154
|
* (`route.spender`, not necessarily the vault). See {@link getDepositRoute}.
|
|
155
155
|
*
|
|
156
156
|
* @param options - {@link IGetDepositRouteOptions}.
|
|
157
|
-
* @returns `{ via, spender, reason? }` — `reason` explains a native route
|
|
157
|
+
* @returns `{ via, spender, reason? }` — `reason` explains a native route
|
|
158
|
+
* (`router-paused` while the SwapRouter is paused).
|
|
158
159
|
* @throws AugustValidationError on an invalid target, or an unregistered
|
|
159
|
-
* code under `attribution.strictOrigin
|
|
160
|
+
* code under `attribution.strictOrigin` while the router is not paused.
|
|
160
161
|
* @throws AugustSDKError when a backend, vault or router read fails.
|
|
161
162
|
* @example
|
|
162
163
|
* ```ts
|
|
@@ -231,7 +232,8 @@ class EVMAdapter {
|
|
|
231
232
|
* @param options - {@link ISwapAndDepositOptions}.
|
|
232
233
|
* @returns The transaction hash of the `swapAndDeposit` call.
|
|
233
234
|
* @throws AugustValidationError on invalid inputs (bad chain, empty swaps).
|
|
234
|
-
* @throws AugustSDKError
|
|
235
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
236
|
+
* approval), or on RPC / contract revert.
|
|
235
237
|
*
|
|
236
238
|
* @example
|
|
237
239
|
* ```ts
|
|
@@ -258,6 +260,8 @@ class EVMAdapter {
|
|
|
258
260
|
*
|
|
259
261
|
* @param options - {@link ISwapRouterDirectDepositOptions}.
|
|
260
262
|
* @returns The transaction hash of the `deposit` call.
|
|
263
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
264
|
+
* approval), or on RPC / contract revert.
|
|
261
265
|
*/
|
|
262
266
|
async depositViaSwapRouter(options) {
|
|
263
267
|
const signer = await this._getSigner();
|
|
@@ -270,6 +274,8 @@ class EVMAdapter {
|
|
|
270
274
|
*
|
|
271
275
|
* @param options - {@link ISwapRouterNativeDepositOptions}.
|
|
272
276
|
* @returns The transaction hash of the `depositNativeToken` call.
|
|
277
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
278
|
+
* approval), or on RPC / contract revert.
|
|
273
279
|
*/
|
|
274
280
|
async depositNativeViaSwapRouter(options) {
|
|
275
281
|
const signer = await this._getSigner();
|
|
@@ -290,6 +296,8 @@ class EVMAdapter {
|
|
|
290
296
|
* @returns The transaction hash of the router deposit call.
|
|
291
297
|
* @throws AugustValidationError on unsupported chain, invalid address, zero
|
|
292
298
|
* amount, a native deposit into a non-wrapped-native vault, or quote drift.
|
|
299
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
300
|
+
* approval), or on RPC / contract revert.
|
|
293
301
|
* @example
|
|
294
302
|
* ```ts
|
|
295
303
|
* const hash = await augustSdk.evm.swapRouterDeposit({
|
|
@@ -169,6 +169,23 @@ export declare function readSwapRouterVaultInfo(runner: IContractRunner, chainId
|
|
|
169
169
|
* @internal
|
|
170
170
|
*/
|
|
171
171
|
export declare function readSwapRouterTokenWhitelisted(runner: IContractRunner, chainId: number, token: IAddress): Promise<boolean>;
|
|
172
|
+
/**
|
|
173
|
+
* Read whether a chain's `SwapRouter` is paused (`isPaused()`), cached for 15
|
|
174
|
+
* seconds. Every router entry point (`deposit`, `swapAndDeposit`,
|
|
175
|
+
* `depositNativeToken`) reverts with `ContractIsPaused` while the router is
|
|
176
|
+
* paused, so callers check this before routing a deposit or sending an
|
|
177
|
+
* approval to the router.
|
|
178
|
+
*
|
|
179
|
+
* @param runner - Contract runner (provider or signer) used for the read.
|
|
180
|
+
* @param chainId - EVM chain ID.
|
|
181
|
+
* @returns `true` while the router is paused; `false` when it is not, or on a
|
|
182
|
+
* chain with no SwapRouter (no RPC).
|
|
183
|
+
* @throws When the `isPaused()` read fails. Callers wrap it in
|
|
184
|
+
* {@link AugustSDKError}.
|
|
185
|
+
* @worstCaseRpcCalls 1 — one `isPaused()` call; none on a cache hit.
|
|
186
|
+
* @internal
|
|
187
|
+
*/
|
|
188
|
+
export declare function readSwapRouterPaused(runner: IContractRunner, chainId: number): Promise<boolean>;
|
|
172
189
|
/**
|
|
173
190
|
* Resolve the ERC-20 tokens currently whitelisted for the `SwapRouter` on a
|
|
174
191
|
* chain — the any-token set a UI can offer as swap-and-deposit inputs.
|
|
@@ -10,6 +10,7 @@ exports.getOriginInfo = getOriginInfo;
|
|
|
10
10
|
exports.readOriginInfo = readOriginInfo;
|
|
11
11
|
exports.readSwapRouterVaultInfo = readSwapRouterVaultInfo;
|
|
12
12
|
exports.readSwapRouterTokenWhitelisted = readSwapRouterTokenWhitelisted;
|
|
13
|
+
exports.readSwapRouterPaused = readSwapRouterPaused;
|
|
13
14
|
exports.getSwapRouterWhitelistedTokens = getSwapRouterWhitelistedTokens;
|
|
14
15
|
exports.getSwapRouterEligibleVaults = getSwapRouterEligibleVaults;
|
|
15
16
|
const ethers_1 = require("ethers");
|
|
@@ -332,6 +333,49 @@ async function readSwapRouterTokenWhitelisted(runner, chainId, token) {
|
|
|
332
333
|
cache_1.CACHE.set(cacheKey, whitelisted, { ttl: SWAP_ROUTER_ORIGIN_INFO_TTL_MS });
|
|
333
334
|
return whitelisted;
|
|
334
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Cache TTL for a SwapRouter's pause state (15 seconds). Far shorter than the
|
|
338
|
+
* 5-minute TTL of the other router reads: the owner pauses the router to stop
|
|
339
|
+
* deposits during an incident, so a pause must reach the deposit-route
|
|
340
|
+
* resolver within seconds. Long enough that the resolver and the router write
|
|
341
|
+
* it hands off to share one `isPaused()` read.
|
|
342
|
+
*/
|
|
343
|
+
const SWAP_ROUTER_PAUSED_TTL_MS = 15 * 1000;
|
|
344
|
+
/**
|
|
345
|
+
* Read whether a chain's `SwapRouter` is paused (`isPaused()`), cached for 15
|
|
346
|
+
* seconds. Every router entry point (`deposit`, `swapAndDeposit`,
|
|
347
|
+
* `depositNativeToken`) reverts with `ContractIsPaused` while the router is
|
|
348
|
+
* paused, so callers check this before routing a deposit or sending an
|
|
349
|
+
* approval to the router.
|
|
350
|
+
*
|
|
351
|
+
* @param runner - Contract runner (provider or signer) used for the read.
|
|
352
|
+
* @param chainId - EVM chain ID.
|
|
353
|
+
* @returns `true` while the router is paused; `false` when it is not, or on a
|
|
354
|
+
* chain with no SwapRouter (no RPC).
|
|
355
|
+
* @throws When the `isPaused()` read fails. Callers wrap it in
|
|
356
|
+
* {@link AugustSDKError}.
|
|
357
|
+
* @worstCaseRpcCalls 1 — one `isPaused()` call; none on a cache hit.
|
|
358
|
+
* @internal
|
|
359
|
+
*/
|
|
360
|
+
async function readSwapRouterPaused(runner, chainId) {
|
|
361
|
+
const router = getSwapRouterAddress(chainId);
|
|
362
|
+
if (!router)
|
|
363
|
+
return false;
|
|
364
|
+
const cacheKey = `swap-router-paused-${chainId}-${router.toLowerCase()}`;
|
|
365
|
+
const cached = await (0, cache_1.getSafeCache)(cacheKey);
|
|
366
|
+
if (cached !== null)
|
|
367
|
+
return cached;
|
|
368
|
+
const contract = (0, web3_1.createContract)({
|
|
369
|
+
address: router,
|
|
370
|
+
provider: runner,
|
|
371
|
+
abi: abis_1.ABI_SWAP_ROUTER,
|
|
372
|
+
});
|
|
373
|
+
if (!contract)
|
|
374
|
+
return false;
|
|
375
|
+
const paused = (await contract.isPaused()) === true;
|
|
376
|
+
cache_1.CACHE.set(cacheKey, paused, { ttl: SWAP_ROUTER_PAUSED_TTL_MS });
|
|
377
|
+
return paused;
|
|
378
|
+
}
|
|
335
379
|
/** Cache TTL for a chain's resolved SwapRouter token allowlist (5 minutes). */
|
|
336
380
|
const SWAP_ROUTER_WHITELIST_TTL_MS = 5 * 60 * 1000;
|
|
337
381
|
/**
|
|
@@ -172,8 +172,11 @@ export type ApproveResult =
|
|
|
172
172
|
/**
|
|
173
173
|
* Why {@link getDepositRoute} kept a deposit on the vault's native path.
|
|
174
174
|
* `no-origin-code` is what every SDK without `attribution.originCode` gets.
|
|
175
|
+
* `router-paused` means the SwapRouter's owner paused it: the deposit goes
|
|
176
|
+
* straight to the vault, even under `attribution.strictOrigin`, until the
|
|
177
|
+
* router is unpaused.
|
|
175
178
|
*/
|
|
176
|
-
export type DepositRouteReason = 'no-origin-code' | 'no-router' | 'chain-not-supported' | 'permit' | 'native-token' | 'adapter' | 'vault-not-registered' | 'asset-not-accepted' | 'router-token-not-whitelisted' | 'origin-not-registered';
|
|
179
|
+
export type DepositRouteReason = 'no-origin-code' | 'no-router' | 'chain-not-supported' | 'permit' | 'native-token' | 'adapter' | 'vault-not-registered' | 'asset-not-accepted' | 'router-token-not-whitelisted' | 'router-paused' | 'origin-not-registered';
|
|
177
180
|
/** A deposit's route — the SwapRouter or the vault's native path — and the address to approve. */
|
|
178
181
|
export type IDepositRoute = {
|
|
179
182
|
/**
|
|
@@ -199,23 +202,25 @@ export type IGetDepositRouteOptions = Pick<IContractWriteOptions, 'target' | 'de
|
|
|
199
202
|
* Ethereum mainnet ({@link ORIGIN_ATTRIBUTION_CHAINS}) and has a SwapRouter,
|
|
200
203
|
* the vault is registered on it, the vault accepts the asset directly (its
|
|
201
204
|
* reference asset, or a Tokenized Vault V2 whitelisted asset — deposited
|
|
202
|
-
* as-is, never swapped), the router whitelists the asset, the
|
|
203
|
-
* permit, native-token or adapter deposit, and
|
|
204
|
-
* Otherwise it is `native` with a `reason`.
|
|
205
|
+
* as-is, never swapped), the router whitelists the asset, the router is not
|
|
206
|
+
* paused, the deposit is not a permit, native-token or adapter deposit, and
|
|
207
|
+
* the code is registered. Otherwise it is `native` with a `reason`. A paused
|
|
208
|
+
* router gives `router-paused` even under `attribution.strictOrigin`.
|
|
205
209
|
*
|
|
206
210
|
* @param signer - ethers `Signer` / `Wallet` used for the reads.
|
|
207
211
|
* @param options - {@link IGetDepositRouteOptions}; `depositAsset` defaults
|
|
208
212
|
* to the vault's underlying.
|
|
209
213
|
* @returns {@link IDepositRoute}.
|
|
210
214
|
* @throws AugustValidationError on an invalid `target`, or an unregistered
|
|
211
|
-
* code under `attribution.strictOrigin
|
|
215
|
+
* code under `attribution.strictOrigin` while the router is not paused.
|
|
212
216
|
* @throws AugustSDKError when a backend, vault or router read fails.
|
|
213
|
-
* @worstCaseRpcCalls
|
|
217
|
+
* @worstCaseRpcCalls 8 — the backend vault row, `asset()`, the router's
|
|
214
218
|
* `vaultInfo`, the vault's `assetsWhitelistAddress()` and
|
|
215
219
|
* `getWhitelistedAssets()` (Tokenized Vault V2 non-reference asset only),
|
|
216
|
-
* the router's `whitelistedTokens(asset)`, and
|
|
217
|
-
* router reads and `getWhitelistedAssets()` are cached for 5 minutes
|
|
218
|
-
* router read without a code or off Ethereum
|
|
220
|
+
* the router's `whitelistedTokens(asset)`, `isPaused()` and `origins`. The
|
|
221
|
+
* router reads and `getWhitelistedAssets()` are cached for 5 minutes, except
|
|
222
|
+
* `isPaused()` (15 seconds). No router read without a code or off Ethereum
|
|
223
|
+
* mainnet.
|
|
219
224
|
* @example
|
|
220
225
|
* ```ts
|
|
221
226
|
* const route = await augustSdk.evm.getDepositRoute({ target: vault, depositAsset: usdt });
|
|
@@ -555,7 +560,8 @@ export declare function rwaRedeemAsset(signer: Signer | Wallet, options: IRwaRed
|
|
|
555
560
|
* addresses, empty/oversized swap arrays, or an origin code not registered on
|
|
556
561
|
* the router (a per-call code, or the instance code under
|
|
557
562
|
* `attribution.strictOrigin`), before any approval.
|
|
558
|
-
* @throws {@link AugustSDKError}
|
|
563
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
564
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
559
565
|
*
|
|
560
566
|
* @example
|
|
561
567
|
* ```ts
|
|
@@ -598,7 +604,8 @@ export declare function swapAndDeposit(signer: Signer | Wallet, options: ISwapAn
|
|
|
598
604
|
* per-call code, or the instance code under `attribution.strictOrigin`),
|
|
599
605
|
* before any approval; with code `ACCOUNT_NOT_FUNDED` when the account cannot
|
|
600
606
|
* cover gas.
|
|
601
|
-
* @throws {@link AugustSDKError}
|
|
607
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
608
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
602
609
|
*/
|
|
603
610
|
export declare function depositViaSwapRouter(signer: Signer | Wallet, options: ISwapRouterDirectDepositOptions): Promise<string>;
|
|
604
611
|
/**
|
|
@@ -626,7 +633,8 @@ export declare function depositViaSwapRouter(signer: Signer | Wallet, options: I
|
|
|
626
633
|
* per-call code, or the instance code under `attribution.strictOrigin`),
|
|
627
634
|
* before any approval; with code `ACCOUNT_NOT_FUNDED` when the account cannot
|
|
628
635
|
* cover gas.
|
|
629
|
-
* @throws {@link AugustSDKError}
|
|
636
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
637
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
630
638
|
*/
|
|
631
639
|
export declare function depositNativeViaSwapRouter(signer: Signer | Wallet, options: ISwapRouterNativeDepositOptions): Promise<string>;
|
|
632
640
|
/**
|
|
@@ -724,14 +732,16 @@ export declare function isNativeSwapRouterDepositSupported(chainId: number, vaul
|
|
|
724
732
|
* not registered on the router (a per-call code, or the instance code under
|
|
725
733
|
* `attribution.strictOrigin`), before any approval; with code
|
|
726
734
|
* `ACCOUNT_NOT_FUNDED` when the account cannot cover gas.
|
|
727
|
-
* @throws {@link AugustSDKError}
|
|
728
|
-
*
|
|
735
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
736
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
737
|
+
* @worstCaseRpcCalls 11 on the swap path into a Tokenized Vault V2 —
|
|
729
738
|
* tokenized-vault metadata, reference asset + decimals, deposit-token
|
|
730
739
|
* decimals, the router's `vaultInfo` and `whitelistedTokens`, the vault's
|
|
731
740
|
* `assetsWhitelistAddress()` and `getWhitelistedAssets()`, the quote, the
|
|
732
|
-
* origin code's `origins` (none for the zero
|
|
733
|
-
* read. The router reads and
|
|
734
|
-
* minutes
|
|
741
|
+
* router's `isPaused()`, the origin code's `origins` (none for the zero
|
|
742
|
+
* sentinel), and the allowance read. The router reads and
|
|
743
|
+
* `getWhitelistedAssets()` are cached for 5 minutes, except `isPaused()`
|
|
744
|
+
* (15 seconds).
|
|
735
745
|
* @example
|
|
736
746
|
* ```ts
|
|
737
747
|
* // USDT deposited into a USDC-reference vault → swapped to USDC en route.
|
|
@@ -515,6 +515,12 @@ async function resolveDepositRoute(signer, args) {
|
|
|
515
515
|
if (!(await (0, core_1.readSwapRouterTokenWhitelisted)(signer, chainId, actualDepositAsset))) {
|
|
516
516
|
return native('router-token-not-whitelisted');
|
|
517
517
|
}
|
|
518
|
+
// After the cached registration gates, so only a deposit that would
|
|
519
|
+
// otherwise route pays the short-TTL read; before the origin check, so a
|
|
520
|
+
// paused router falls back to native instead of throwing under strictOrigin.
|
|
521
|
+
if (await (0, core_1.readSwapRouterPaused)(signer, chainId)) {
|
|
522
|
+
return native('router-paused');
|
|
523
|
+
}
|
|
518
524
|
if (!(await (0, core_1.readOriginInfo)(chainId, originCode, () => signer)).registered) {
|
|
519
525
|
if ((0, core_1.isStrictOrigin)()) {
|
|
520
526
|
throw new core_1.AugustValidationError('INVALID_INPUT', `attribution.originCode is not registered on the SwapRouter for chain ${chainId} and attribution.strictOrigin is set. Register it with addOrigin, or unset strictOrigin to fall back to a native deposit.`, { context: { chainId, target } });
|
|
@@ -534,23 +540,25 @@ async function resolveDepositRoute(signer, args) {
|
|
|
534
540
|
* Ethereum mainnet ({@link ORIGIN_ATTRIBUTION_CHAINS}) and has a SwapRouter,
|
|
535
541
|
* the vault is registered on it, the vault accepts the asset directly (its
|
|
536
542
|
* reference asset, or a Tokenized Vault V2 whitelisted asset — deposited
|
|
537
|
-
* as-is, never swapped), the router whitelists the asset, the
|
|
538
|
-
* permit, native-token or adapter deposit, and
|
|
539
|
-
* Otherwise it is `native` with a `reason`.
|
|
543
|
+
* as-is, never swapped), the router whitelists the asset, the router is not
|
|
544
|
+
* paused, the deposit is not a permit, native-token or adapter deposit, and
|
|
545
|
+
* the code is registered. Otherwise it is `native` with a `reason`. A paused
|
|
546
|
+
* router gives `router-paused` even under `attribution.strictOrigin`.
|
|
540
547
|
*
|
|
541
548
|
* @param signer - ethers `Signer` / `Wallet` used for the reads.
|
|
542
549
|
* @param options - {@link IGetDepositRouteOptions}; `depositAsset` defaults
|
|
543
550
|
* to the vault's underlying.
|
|
544
551
|
* @returns {@link IDepositRoute}.
|
|
545
552
|
* @throws AugustValidationError on an invalid `target`, or an unregistered
|
|
546
|
-
* code under `attribution.strictOrigin
|
|
553
|
+
* code under `attribution.strictOrigin` while the router is not paused.
|
|
547
554
|
* @throws AugustSDKError when a backend, vault or router read fails.
|
|
548
|
-
* @worstCaseRpcCalls
|
|
555
|
+
* @worstCaseRpcCalls 8 — the backend vault row, `asset()`, the router's
|
|
549
556
|
* `vaultInfo`, the vault's `assetsWhitelistAddress()` and
|
|
550
557
|
* `getWhitelistedAssets()` (Tokenized Vault V2 non-reference asset only),
|
|
551
|
-
* the router's `whitelistedTokens(asset)`, and
|
|
552
|
-
* router reads and `getWhitelistedAssets()` are cached for 5 minutes
|
|
553
|
-
* router read without a code or off Ethereum
|
|
558
|
+
* the router's `whitelistedTokens(asset)`, `isPaused()` and `origins`. The
|
|
559
|
+
* router reads and `getWhitelistedAssets()` are cached for 5 minutes, except
|
|
560
|
+
* `isPaused()` (15 seconds). No router read without a code or off Ethereum
|
|
561
|
+
* mainnet.
|
|
554
562
|
* @example
|
|
555
563
|
* ```ts
|
|
556
564
|
* const route = await augustSdk.evm.getDepositRoute({ target: vault, depositAsset: usdt });
|
|
@@ -1752,6 +1760,19 @@ async function resolveRouterOriginCode(signer, operation, chainId, vault, provid
|
|
|
1752
1760
|
trackOriginAttribution({ via: 'native', spender: null, reason: 'origin-not-registered' }, { chainId, target: vault }, operation);
|
|
1753
1761
|
return core_1.ORIGIN_CODES.default;
|
|
1754
1762
|
}
|
|
1763
|
+
/**
|
|
1764
|
+
* Throw before any approval when the chain's SwapRouter is paused. Every
|
|
1765
|
+
* router entry point reverts with `ContractIsPaused` while it is paused, so an
|
|
1766
|
+
* approval sent first would only cost the user gas. Unlike `vaultDeposit`,
|
|
1767
|
+
* these methods have no native path to fall back to: the caller asked for the
|
|
1768
|
+
* router.
|
|
1769
|
+
* @internal
|
|
1770
|
+
*/
|
|
1771
|
+
async function assertSwapRouterNotPaused(signer, operation, chainId, vault) {
|
|
1772
|
+
if (!(await (0, core_1.readSwapRouterPaused)(signer, chainId)))
|
|
1773
|
+
return;
|
|
1774
|
+
throw new core_1.AugustSDKError('UNKNOWN', `${operation}: the SwapRouter on chain ${chainId} is paused and rejects every deposit. Deposit into the vault directly with vaultDeposit, or retry once the router is unpaused.`, { context: { chainId, vault, reason: 'router-paused' } });
|
|
1775
|
+
}
|
|
1755
1776
|
/** @internal */
|
|
1756
1777
|
function resolveSwapRouterOrThrow(chainId) {
|
|
1757
1778
|
const router = (0, core_1.getSwapRouterAddress)(chainId);
|
|
@@ -1848,7 +1869,8 @@ async function resolveSignerEOA(signer, callerContext) {
|
|
|
1848
1869
|
* addresses, empty/oversized swap arrays, or an origin code not registered on
|
|
1849
1870
|
* the router (a per-call code, or the instance code under
|
|
1850
1871
|
* `attribution.strictOrigin`), before any approval.
|
|
1851
|
-
* @throws {@link AugustSDKError}
|
|
1872
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
1873
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
1852
1874
|
*
|
|
1853
1875
|
* @example
|
|
1854
1876
|
* ```ts
|
|
@@ -1887,6 +1909,7 @@ async function swapAndDeposit(signer, options) {
|
|
|
1887
1909
|
const routerAddress = resolveSwapRouterOrThrow(chainId);
|
|
1888
1910
|
let tx;
|
|
1889
1911
|
try {
|
|
1912
|
+
await assertSwapRouterNotPaused(signer, 'swapAndDeposit', chainId, vault);
|
|
1890
1913
|
const origin = await resolveRouterOriginCode(signer, 'swapAndDeposit', chainId, vault, originCode);
|
|
1891
1914
|
const eoa = await resolveSignerEOA(signer, 'swapAndDeposit');
|
|
1892
1915
|
for (const [tokenIn, totalIn] of totalInputPerToken(swaps)) {
|
|
@@ -1923,7 +1946,8 @@ async function swapAndDeposit(signer, options) {
|
|
|
1923
1946
|
* per-call code, or the instance code under `attribution.strictOrigin`),
|
|
1924
1947
|
* before any approval; with code `ACCOUNT_NOT_FUNDED` when the account cannot
|
|
1925
1948
|
* cover gas.
|
|
1926
|
-
* @throws {@link AugustSDKError}
|
|
1949
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
1950
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
1927
1951
|
*/
|
|
1928
1952
|
async function depositViaSwapRouter(signer, options) {
|
|
1929
1953
|
const { chainId, vault, receiver, asset, amount, originCode, wait } = options;
|
|
@@ -1939,6 +1963,7 @@ async function depositViaSwapRouter(signer, options) {
|
|
|
1939
1963
|
const routerAddress = resolveSwapRouterOrThrow(chainId);
|
|
1940
1964
|
let tx;
|
|
1941
1965
|
try {
|
|
1966
|
+
await assertSwapRouterNotPaused(signer, 'depositViaSwapRouter', chainId, vault);
|
|
1942
1967
|
const origin = await resolveRouterOriginCode(signer, 'depositViaSwapRouter', chainId, vault, originCode);
|
|
1943
1968
|
const eoa = await resolveSignerEOA(signer, 'depositViaSwapRouter');
|
|
1944
1969
|
await ensureAllowance(signer, asset, eoa, routerAddress, amount);
|
|
@@ -1984,7 +2009,8 @@ async function depositViaSwapRouter(signer, options) {
|
|
|
1984
2009
|
* per-call code, or the instance code under `attribution.strictOrigin`),
|
|
1985
2010
|
* before any approval; with code `ACCOUNT_NOT_FUNDED` when the account cannot
|
|
1986
2011
|
* cover gas.
|
|
1987
|
-
* @throws {@link AugustSDKError}
|
|
2012
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
2013
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
1988
2014
|
*/
|
|
1989
2015
|
async function depositNativeViaSwapRouter(signer, options) {
|
|
1990
2016
|
const { chainId, vault, receiver, amount, originCode, wait } = options;
|
|
@@ -1999,6 +2025,7 @@ async function depositNativeViaSwapRouter(signer, options) {
|
|
|
1999
2025
|
const routerAddress = resolveSwapRouterOrThrow(chainId);
|
|
2000
2026
|
let tx;
|
|
2001
2027
|
try {
|
|
2028
|
+
await assertSwapRouterNotPaused(signer, 'depositNativeViaSwapRouter', chainId, vault);
|
|
2002
2029
|
const origin = await resolveRouterOriginCode(signer, 'depositNativeViaSwapRouter', chainId, vault, originCode);
|
|
2003
2030
|
const routerContract = (0, core_1.createContract)({
|
|
2004
2031
|
address: routerAddress,
|
|
@@ -2141,14 +2168,16 @@ async function isNativeSwapRouterDepositSupported(chainId, vault, options) {
|
|
|
2141
2168
|
* not registered on the router (a per-call code, or the instance code under
|
|
2142
2169
|
* `attribution.strictOrigin`), before any approval; with code
|
|
2143
2170
|
* `ACCOUNT_NOT_FUNDED` when the account cannot cover gas.
|
|
2144
|
-
* @throws {@link AugustSDKError}
|
|
2145
|
-
*
|
|
2171
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
2172
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
2173
|
+
* @worstCaseRpcCalls 11 on the swap path into a Tokenized Vault V2 —
|
|
2146
2174
|
* tokenized-vault metadata, reference asset + decimals, deposit-token
|
|
2147
2175
|
* decimals, the router's `vaultInfo` and `whitelistedTokens`, the vault's
|
|
2148
2176
|
* `assetsWhitelistAddress()` and `getWhitelistedAssets()`, the quote, the
|
|
2149
|
-
* origin code's `origins` (none for the zero
|
|
2150
|
-
* read. The router reads and
|
|
2151
|
-
* minutes
|
|
2177
|
+
* router's `isPaused()`, the origin code's `origins` (none for the zero
|
|
2178
|
+
* sentinel), and the allowance read. The router reads and
|
|
2179
|
+
* `getWhitelistedAssets()` are cached for 5 minutes, except `isPaused()`
|
|
2180
|
+
* (15 seconds).
|
|
2152
2181
|
* @example
|
|
2153
2182
|
* ```ts
|
|
2154
2183
|
* // USDT deposited into a USDC-reference vault → swapped to USDC en route.
|
package/lib/sdk.d.ts
CHANGED
|
@@ -18062,15 +18062,19 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
18062
18062
|
* per-call code, or the instance code under `attribution.strictOrigin`),
|
|
18063
18063
|
* before any approval; with code `ACCOUNT_NOT_FUNDED` when the account cannot
|
|
18064
18064
|
* cover gas.
|
|
18065
|
-
* @throws {@link AugustSDKError}
|
|
18065
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
18066
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
18066
18067
|
*/
|
|
18067
18068
|
export declare function depositNativeViaSwapRouter(signer: Signer | Wallet, options: ISwapRouterNativeDepositOptions): Promise<string>;
|
|
18068
18069
|
|
|
18069
18070
|
/**
|
|
18070
18071
|
* Why {@link getDepositRoute} kept a deposit on the vault's native path.
|
|
18071
18072
|
* `no-origin-code` is what every SDK without `attribution.originCode` gets.
|
|
18073
|
+
* `router-paused` means the SwapRouter's owner paused it: the deposit goes
|
|
18074
|
+
* straight to the vault, even under `attribution.strictOrigin`, until the
|
|
18075
|
+
* router is unpaused.
|
|
18072
18076
|
*/
|
|
18073
|
-
export declare type DepositRouteReason = 'no-origin-code' | 'no-router' | 'chain-not-supported' | 'permit' | 'native-token' | 'adapter' | 'vault-not-registered' | 'asset-not-accepted' | 'router-token-not-whitelisted' | 'origin-not-registered';
|
|
18077
|
+
export declare type DepositRouteReason = 'no-origin-code' | 'no-router' | 'chain-not-supported' | 'permit' | 'native-token' | 'adapter' | 'vault-not-registered' | 'asset-not-accepted' | 'router-token-not-whitelisted' | 'router-paused' | 'origin-not-registered';
|
|
18074
18078
|
|
|
18075
18079
|
/**
|
|
18076
18080
|
* Deposit a vault's reference asset directly through the SwapRouter — no
|
|
@@ -18086,7 +18090,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
18086
18090
|
* per-call code, or the instance code under `attribution.strictOrigin`),
|
|
18087
18091
|
* before any approval; with code `ACCOUNT_NOT_FUNDED` when the account cannot
|
|
18088
18092
|
* cover gas.
|
|
18089
|
-
* @throws {@link AugustSDKError}
|
|
18093
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
18094
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
18090
18095
|
*/
|
|
18091
18096
|
export declare function depositViaSwapRouter(signer: Signer | Wallet, options: ISwapRouterDirectDepositOptions): Promise<string>;
|
|
18092
18097
|
|
|
@@ -18292,9 +18297,10 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
18292
18297
|
* (`route.spender`, not necessarily the vault). See {@link getDepositRoute}.
|
|
18293
18298
|
*
|
|
18294
18299
|
* @param options - {@link IGetDepositRouteOptions}.
|
|
18295
|
-
* @returns `{ via, spender, reason? }` — `reason` explains a native route
|
|
18300
|
+
* @returns `{ via, spender, reason? }` — `reason` explains a native route
|
|
18301
|
+
* (`router-paused` while the SwapRouter is paused).
|
|
18296
18302
|
* @throws AugustValidationError on an invalid target, or an unregistered
|
|
18297
|
-
* code under `attribution.strictOrigin
|
|
18303
|
+
* code under `attribution.strictOrigin` while the router is not paused.
|
|
18298
18304
|
* @throws AugustSDKError when a backend, vault or router read fails.
|
|
18299
18305
|
* @example
|
|
18300
18306
|
* ```ts
|
|
@@ -18360,7 +18366,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
18360
18366
|
* @param options - {@link ISwapAndDepositOptions}.
|
|
18361
18367
|
* @returns The transaction hash of the `swapAndDeposit` call.
|
|
18362
18368
|
* @throws AugustValidationError on invalid inputs (bad chain, empty swaps).
|
|
18363
|
-
* @throws AugustSDKError
|
|
18369
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
18370
|
+
* approval), or on RPC / contract revert.
|
|
18364
18371
|
*
|
|
18365
18372
|
* @example
|
|
18366
18373
|
* ```ts
|
|
@@ -18384,6 +18391,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
18384
18391
|
*
|
|
18385
18392
|
* @param options - {@link ISwapRouterDirectDepositOptions}.
|
|
18386
18393
|
* @returns The transaction hash of the `deposit` call.
|
|
18394
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
18395
|
+
* approval), or on RPC / contract revert.
|
|
18387
18396
|
*/
|
|
18388
18397
|
depositViaSwapRouter(options: ISwapRouterDirectDepositOptions): Promise<string>;
|
|
18389
18398
|
/**
|
|
@@ -18393,6 +18402,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
18393
18402
|
*
|
|
18394
18403
|
* @param options - {@link ISwapRouterNativeDepositOptions}.
|
|
18395
18404
|
* @returns The transaction hash of the `depositNativeToken` call.
|
|
18405
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
18406
|
+
* approval), or on RPC / contract revert.
|
|
18396
18407
|
*/
|
|
18397
18408
|
depositNativeViaSwapRouter(options: ISwapRouterNativeDepositOptions): Promise<string>;
|
|
18398
18409
|
/**
|
|
@@ -18410,6 +18421,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
18410
18421
|
* @returns The transaction hash of the router deposit call.
|
|
18411
18422
|
* @throws AugustValidationError on unsupported chain, invalid address, zero
|
|
18412
18423
|
* amount, a native deposit into a non-wrapped-native vault, or quote drift.
|
|
18424
|
+
* @throws AugustSDKError while the SwapRouter is paused (checked before any
|
|
18425
|
+
* approval), or on RPC / contract revert.
|
|
18413
18426
|
* @example
|
|
18414
18427
|
* ```ts
|
|
18415
18428
|
* const hash = await augustSdk.evm.swapRouterDeposit({
|
|
@@ -19226,23 +19239,25 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
19226
19239
|
* Ethereum mainnet ({@link ORIGIN_ATTRIBUTION_CHAINS}) and has a SwapRouter,
|
|
19227
19240
|
* the vault is registered on it, the vault accepts the asset directly (its
|
|
19228
19241
|
* reference asset, or a Tokenized Vault V2 whitelisted asset — deposited
|
|
19229
|
-
* as-is, never swapped), the router whitelists the asset, the
|
|
19230
|
-
* permit, native-token or adapter deposit, and
|
|
19231
|
-
* Otherwise it is `native` with a `reason`.
|
|
19242
|
+
* as-is, never swapped), the router whitelists the asset, the router is not
|
|
19243
|
+
* paused, the deposit is not a permit, native-token or adapter deposit, and
|
|
19244
|
+
* the code is registered. Otherwise it is `native` with a `reason`. A paused
|
|
19245
|
+
* router gives `router-paused` even under `attribution.strictOrigin`.
|
|
19232
19246
|
*
|
|
19233
19247
|
* @param signer - ethers `Signer` / `Wallet` used for the reads.
|
|
19234
19248
|
* @param options - {@link IGetDepositRouteOptions}; `depositAsset` defaults
|
|
19235
19249
|
* to the vault's underlying.
|
|
19236
19250
|
* @returns {@link IDepositRoute}.
|
|
19237
19251
|
* @throws AugustValidationError on an invalid `target`, or an unregistered
|
|
19238
|
-
* code under `attribution.strictOrigin
|
|
19252
|
+
* code under `attribution.strictOrigin` while the router is not paused.
|
|
19239
19253
|
* @throws AugustSDKError when a backend, vault or router read fails.
|
|
19240
|
-
* @worstCaseRpcCalls
|
|
19254
|
+
* @worstCaseRpcCalls 8 — the backend vault row, `asset()`, the router's
|
|
19241
19255
|
* `vaultInfo`, the vault's `assetsWhitelistAddress()` and
|
|
19242
19256
|
* `getWhitelistedAssets()` (Tokenized Vault V2 non-reference asset only),
|
|
19243
|
-
* the router's `whitelistedTokens(asset)`, and
|
|
19244
|
-
* router reads and `getWhitelistedAssets()` are cached for 5 minutes
|
|
19245
|
-
* router read without a code or off Ethereum
|
|
19257
|
+
* the router's `whitelistedTokens(asset)`, `isPaused()` and `origins`. The
|
|
19258
|
+
* router reads and `getWhitelistedAssets()` are cached for 5 minutes, except
|
|
19259
|
+
* `isPaused()` (15 seconds). No router read without a code or off Ethereum
|
|
19260
|
+
* mainnet.
|
|
19246
19261
|
* @example
|
|
19247
19262
|
* ```ts
|
|
19248
19263
|
* const route = await augustSdk.evm.getDepositRoute({ target: vault, depositAsset: usdt });
|
|
@@ -25832,6 +25847,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
25832
25847
|
|
|
25833
25848
|
/* Excluded from this release type: readOriginInfo */
|
|
25834
25849
|
|
|
25850
|
+
/* Excluded from this release type: readSwapRouterPaused */
|
|
25851
|
+
|
|
25835
25852
|
/* Excluded from this release type: readSwapRouterTokenWhitelisted */
|
|
25836
25853
|
|
|
25837
25854
|
/* Excluded from this release type: readSwapRouterVaultInfo */
|
|
@@ -28006,7 +28023,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
28006
28023
|
* addresses, empty/oversized swap arrays, or an origin code not registered on
|
|
28007
28024
|
* the router (a per-call code, or the instance code under
|
|
28008
28025
|
* `attribution.strictOrigin`), before any approval.
|
|
28009
|
-
* @throws {@link AugustSDKError}
|
|
28026
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
28027
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
28010
28028
|
*
|
|
28011
28029
|
* @example
|
|
28012
28030
|
* ```ts
|
|
@@ -28086,14 +28104,16 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
28086
28104
|
* not registered on the router (a per-call code, or the instance code under
|
|
28087
28105
|
* `attribution.strictOrigin`), before any approval; with code
|
|
28088
28106
|
* `ACCOUNT_NOT_FUNDED` when the account cannot cover gas.
|
|
28089
|
-
* @throws {@link AugustSDKError}
|
|
28090
|
-
*
|
|
28107
|
+
* @throws {@link AugustSDKError} while the SwapRouter is paused (checked before
|
|
28108
|
+
* any approval), or on unrecoverable contract or RPC failure.
|
|
28109
|
+
* @worstCaseRpcCalls 11 on the swap path into a Tokenized Vault V2 —
|
|
28091
28110
|
* tokenized-vault metadata, reference asset + decimals, deposit-token
|
|
28092
28111
|
* decimals, the router's `vaultInfo` and `whitelistedTokens`, the vault's
|
|
28093
28112
|
* `assetsWhitelistAddress()` and `getWhitelistedAssets()`, the quote, the
|
|
28094
|
-
* origin code's `origins` (none for the zero
|
|
28095
|
-
* read. The router reads and
|
|
28096
|
-
* minutes
|
|
28113
|
+
* router's `isPaused()`, the origin code's `origins` (none for the zero
|
|
28114
|
+
* sentinel), and the allowance read. The router reads and
|
|
28115
|
+
* `getWhitelistedAssets()` are cached for 5 minutes, except `isPaused()`
|
|
28116
|
+
* (15 seconds).
|
|
28097
28117
|
* @example
|
|
28098
28118
|
* ```ts
|
|
28099
28119
|
* // USDT deposited into a USDC-reference vault → swapped to USDC en route.
|