@gearbox-protocol/sdk 18.3.0 → 18.4.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/dist/cjs/abi/310/iKillSwitchProxy.js +130 -0
- package/dist/cjs/onchain/accounts/intents/maxBorrowAndWithdraw.js +3 -1
- package/dist/cjs/onchain/index.js +18 -0
- package/dist/cjs/onchain/market/adapters/abi/adapters/iTreehouseFastlaneAdapter.js +113 -0
- package/dist/cjs/onchain/market/adapters/abi/adapters/iTreehouseRedemptionGatewayAdapter.js +258 -0
- package/dist/cjs/onchain/market/adapters/abi/adapters/iTreehouseRouterAdapter.js +161 -0
- package/dist/cjs/onchain/market/adapters/abi/adapters/index.js +6 -0
- package/dist/cjs/onchain/market/adapters/abi/index.js +13 -0
- package/dist/cjs/onchain/market/adapters/abi/treehouse/iTreehouseFastlane.js +39 -0
- package/dist/cjs/onchain/market/adapters/abi/treehouse/iTreehouseRedemptionGateway.js +230 -0
- package/dist/cjs/onchain/market/adapters/abi/treehouse/iTreehouseRouter.js +29 -0
- package/dist/cjs/onchain/market/adapters/abi/treehouse/index.js +7 -0
- package/dist/cjs/onchain/market/adapters/contracts/TreehouseFastlaneAdapterContract.js +72 -0
- package/dist/cjs/onchain/market/adapters/contracts/TreehouseRedemptionGatewayAdapterContract.js +117 -0
- package/dist/cjs/onchain/market/adapters/contracts/TreehouseRouterAdapterContract.js +61 -0
- package/dist/cjs/onchain/market/adapters/contracts/index.js +6 -0
- package/dist/cjs/onchain/market/adapters/createAdapter.js +6 -0
- package/dist/cjs/onchain/market/adapters/index.js +18 -0
- package/dist/cjs/onchain/market/index.js +18 -0
- package/dist/cjs/permissionless/api/index.js +31 -0
- package/dist/cjs/permissionless/api/oracles/PermissionlessOracles.js +637 -65
- package/dist/cjs/permissionless/api/oracles/enrich.js +99 -0
- package/dist/cjs/permissionless/api/oracles/index.js +33 -0
- package/dist/cjs/permissionless/api/oracles/onchain-feed.js +25 -0
- package/dist/cjs/permissionless/api/oracles/schemas.js +84 -59
- package/dist/cjs/permissionless/api/oracles/score/formula.js +56 -0
- package/dist/cjs/permissionless/api/oracles/score/index.js +11 -0
- package/dist/cjs/permissionless/api/oracles/score/run.js +252 -0
- package/dist/cjs/permissionless/api/oracles/score/types.js +1 -0
- package/dist/cjs/permissionless/api/oracles/stress/classify.js +258 -0
- package/dist/cjs/permissionless/api/oracles/stress/index.js +24 -0
- package/dist/cjs/permissionless/api/oracles/stress/override.js +125 -0
- package/dist/cjs/permissionless/api/oracles/stress/run.js +485 -0
- package/dist/cjs/permissionless/api/oracles/stress/score.js +98 -0
- package/dist/cjs/permissionless/api/oracles/stress/types.js +1 -0
- package/dist/cjs/permissionless/api/schemas.js +0 -3
- package/dist/cjs/permissionless/api/transactions/InstanceOwnerTransactions.js +14 -3
- package/dist/cjs/permissionless/api/transactions/lp-price-feeds.js +10 -4
- package/dist/cjs/permissionless/bindings/bytecode-repository.js +8 -0
- package/dist/cjs/permissionless/bindings/governance/governor.js +1 -1
- package/dist/cjs/permissionless/bindings/index.js +8 -3
- package/dist/cjs/permissionless/bindings/kill-switch-proxy.js +188 -0
- package/dist/cjs/permissionless/bindings/market-configurator-factory.js +39 -1
- package/dist/cjs/permissionless/bindings/market-configurator.js +142 -0
- package/dist/cjs/permissionless/index.js +42 -3
- package/dist/cjs/permissionless/utils/index.js +3 -0
- package/dist/cjs/permissionless/utils/literals.js +2 -0
- package/dist/cjs/permissionless/utils/price-update/get-prices.js +64 -0
- package/dist/cjs/permissionless/utils/price-update/index.js +2 -0
- package/dist/cjs/testnets/TestnetsAPI.js +179 -0
- package/dist/cjs/testnets/errors/TestnetNotFoundError.js +15 -0
- package/dist/cjs/testnets/errors/TestnetRequestFailedError.js +24 -0
- package/dist/cjs/testnets/errors/TestnetStatusError.js +19 -0
- package/dist/cjs/testnets/errors/TestnetValidationError.js +24 -0
- package/dist/cjs/testnets/errors/TestnetWaitTimeoutError.js +30 -0
- package/dist/cjs/testnets/errors/TestnetsError.js +34 -0
- package/dist/cjs/testnets/errors/index.js +13 -0
- package/dist/cjs/testnets/index.js +32 -0
- package/dist/cjs/testnets/package.json +1 -0
- package/dist/cjs/testnets/schemas.js +242 -0
- package/dist/cjs/testnets/types.js +1 -0
- package/dist/esm/abi/310/iKillSwitchProxy.js +129 -0
- package/dist/esm/onchain/accounts/intents/maxBorrowAndWithdraw.js +3 -1
- package/dist/esm/onchain/index.js +10 -1
- package/dist/esm/onchain/market/adapters/abi/adapters/iTreehouseFastlaneAdapter.js +112 -0
- package/dist/esm/onchain/market/adapters/abi/adapters/iTreehouseRedemptionGatewayAdapter.js +257 -0
- package/dist/esm/onchain/market/adapters/abi/adapters/iTreehouseRouterAdapter.js +160 -0
- package/dist/esm/onchain/market/adapters/abi/adapters/index.js +4 -1
- package/dist/esm/onchain/market/adapters/abi/index.js +8 -1
- package/dist/esm/onchain/market/adapters/abi/treehouse/iTreehouseFastlane.js +38 -0
- package/dist/esm/onchain/market/adapters/abi/treehouse/iTreehouseRedemptionGateway.js +229 -0
- package/dist/esm/onchain/market/adapters/abi/treehouse/iTreehouseRouter.js +28 -0
- package/dist/esm/onchain/market/adapters/abi/treehouse/index.js +4 -0
- package/dist/esm/onchain/market/adapters/contracts/TreehouseFastlaneAdapterContract.js +71 -0
- package/dist/esm/onchain/market/adapters/contracts/TreehouseRedemptionGatewayAdapterContract.js +116 -0
- package/dist/esm/onchain/market/adapters/contracts/TreehouseRouterAdapterContract.js +60 -0
- package/dist/esm/onchain/market/adapters/contracts/index.js +4 -1
- package/dist/esm/onchain/market/adapters/createAdapter.js +6 -0
- package/dist/esm/onchain/market/adapters/index.js +10 -1
- package/dist/esm/onchain/market/index.js +10 -1
- package/dist/esm/permissionless/api/index.js +7 -1
- package/dist/esm/permissionless/api/oracles/PermissionlessOracles.js +639 -67
- package/dist/esm/permissionless/api/oracles/enrich.js +94 -0
- package/dist/esm/permissionless/api/oracles/index.js +10 -1
- package/dist/esm/permissionless/api/oracles/onchain-feed.js +24 -0
- package/dist/esm/permissionless/api/oracles/schemas.js +80 -58
- package/dist/esm/permissionless/api/oracles/score/formula.js +51 -0
- package/dist/esm/permissionless/api/oracles/score/index.js +4 -0
- package/dist/esm/permissionless/api/oracles/score/run.js +250 -0
- package/dist/esm/permissionless/api/oracles/score/types.js +1 -0
- package/dist/esm/permissionless/api/oracles/stress/classify.js +256 -0
- package/dist/esm/permissionless/api/oracles/stress/index.js +6 -0
- package/dist/esm/permissionless/api/oracles/stress/override.js +119 -0
- package/dist/esm/permissionless/api/oracles/stress/run.js +478 -0
- package/dist/esm/permissionless/api/oracles/stress/score.js +95 -0
- package/dist/esm/permissionless/api/oracles/stress/types.js +1 -0
- package/dist/esm/permissionless/api/schemas.js +2 -4
- package/dist/esm/permissionless/api/transactions/InstanceOwnerTransactions.js +14 -3
- package/dist/esm/permissionless/api/transactions/lp-price-feeds.js +10 -4
- package/dist/esm/permissionless/bindings/bytecode-repository.js +8 -0
- package/dist/esm/permissionless/bindings/governance/governor.js +1 -1
- package/dist/esm/permissionless/bindings/index.js +5 -4
- package/dist/esm/permissionless/bindings/kill-switch-proxy.js +184 -0
- package/dist/esm/permissionless/bindings/market-configurator-factory.js +37 -0
- package/dist/esm/permissionless/bindings/market-configurator.js +143 -1
- package/dist/esm/permissionless/index.js +13 -6
- package/dist/esm/permissionless/utils/index.js +3 -3
- package/dist/esm/permissionless/utils/literals.js +2 -1
- package/dist/esm/permissionless/utils/price-update/get-prices.js +63 -1
- package/dist/esm/permissionless/utils/price-update/index.js +2 -2
- package/dist/esm/testnets/TestnetsAPI.js +178 -0
- package/dist/esm/testnets/errors/TestnetNotFoundError.js +14 -0
- package/dist/esm/testnets/errors/TestnetRequestFailedError.js +23 -0
- package/dist/esm/testnets/errors/TestnetStatusError.js +18 -0
- package/dist/esm/testnets/errors/TestnetValidationError.js +23 -0
- package/dist/esm/testnets/errors/TestnetWaitTimeoutError.js +29 -0
- package/dist/esm/testnets/errors/TestnetsError.js +33 -0
- package/dist/esm/testnets/errors/index.js +7 -0
- package/dist/esm/testnets/index.js +11 -0
- package/dist/esm/testnets/package.json +1 -0
- package/dist/esm/testnets/schemas.js +228 -0
- package/dist/esm/testnets/types.js +1 -0
- package/dist/types/abi/310/iKillSwitchProxy.d.ts +114 -0
- package/dist/types/onchain/index.d.ts +10 -1
- package/dist/types/onchain/market/adapters/abi/adapters/iTreehouseFastlaneAdapter.d.ts +101 -0
- package/dist/types/onchain/market/adapters/abi/adapters/iTreehouseRedemptionGatewayAdapter.d.ts +237 -0
- package/dist/types/onchain/market/adapters/abi/adapters/iTreehouseRouterAdapter.d.ts +146 -0
- package/dist/types/onchain/market/adapters/abi/adapters/index.d.ts +4 -1
- package/dist/types/onchain/market/adapters/abi/index.d.ts +8 -1
- package/dist/types/onchain/market/adapters/abi/treehouse/iTreehouseFastlane.d.ts +33 -0
- package/dist/types/onchain/market/adapters/abi/treehouse/iTreehouseRedemptionGateway.d.ts +207 -0
- package/dist/types/onchain/market/adapters/abi/treehouse/iTreehouseRouter.d.ts +27 -0
- package/dist/types/onchain/market/adapters/abi/treehouse/index.d.ts +4 -0
- package/dist/types/onchain/market/adapters/contracts/TreehouseFastlaneAdapterContract.d.ts +156 -0
- package/dist/types/onchain/market/adapters/contracts/TreehouseRedemptionGatewayAdapterContract.d.ts +481 -0
- package/dist/types/onchain/market/adapters/contracts/TreehouseRouterAdapterContract.d.ts +193 -0
- package/dist/types/onchain/market/adapters/contracts/index.d.ts +4 -1
- package/dist/types/onchain/market/adapters/index.d.ts +10 -1
- package/dist/types/onchain/market/index.d.ts +10 -1
- package/dist/types/permissionless/api/index.d.ts +10 -2
- package/dist/types/permissionless/api/oracles/PermissionlessOracles.d.ts +237 -47
- package/dist/types/permissionless/api/oracles/enrich.d.ts +59 -0
- package/dist/types/permissionless/api/oracles/index.d.ts +12 -2
- package/dist/types/permissionless/api/oracles/onchain-feed.d.ts +15 -0
- package/dist/types/permissionless/api/oracles/schemas.d.ts +147 -41
- package/dist/types/permissionless/api/oracles/score/formula.d.ts +36 -0
- package/dist/types/permissionless/api/oracles/score/index.d.ts +4 -0
- package/dist/types/permissionless/api/oracles/score/run.d.ts +42 -0
- package/dist/types/permissionless/api/oracles/score/types.d.ts +118 -0
- package/dist/types/permissionless/api/oracles/stress/classify.d.ts +57 -0
- package/dist/types/permissionless/api/oracles/stress/index.d.ts +6 -0
- package/dist/types/permissionless/api/oracles/stress/override.d.ts +59 -0
- package/dist/types/permissionless/api/oracles/stress/run.d.ts +100 -0
- package/dist/types/permissionless/api/oracles/stress/score.d.ts +57 -0
- package/dist/types/permissionless/api/oracles/stress/types.d.ts +272 -0
- package/dist/types/permissionless/api/oracles/types.d.ts +320 -125
- package/dist/types/permissionless/api/schemas.d.ts +0 -2
- package/dist/types/permissionless/api/transactions/lp-price-feeds.d.ts +9 -1
- package/dist/types/permissionless/bindings/bytecode-repository.d.ts +10 -1
- package/dist/types/permissionless/bindings/index.d.ts +4 -3
- package/dist/types/permissionless/bindings/kill-switch-proxy.d.ts +205 -0
- package/dist/types/permissionless/bindings/market-configurator-factory.d.ts +30 -0
- package/dist/types/permissionless/bindings/market-configurator.d.ts +30 -1
- package/dist/types/permissionless/bindings/types.d.ts +27 -0
- package/dist/types/permissionless/index.d.ts +15 -6
- package/dist/types/permissionless/utils/index.d.ts +3 -3
- package/dist/types/permissionless/utils/literals.d.ts +1 -0
- package/dist/types/permissionless/utils/price-update/get-prices.d.ts +33 -0
- package/dist/types/permissionless/utils/price-update/index.d.ts +2 -2
- package/dist/types/testnets/TestnetsAPI.d.ts +108 -0
- package/dist/types/testnets/errors/TestnetNotFoundError.d.ts +12 -0
- package/dist/types/testnets/errors/TestnetRequestFailedError.d.ts +11 -0
- package/dist/types/testnets/errors/TestnetStatusError.d.ts +15 -0
- package/dist/types/testnets/errors/TestnetValidationError.d.ts +16 -0
- package/dist/types/testnets/errors/TestnetWaitTimeoutError.d.ts +21 -0
- package/dist/types/testnets/errors/TestnetsError.d.ts +47 -0
- package/dist/types/testnets/errors/index.d.ts +7 -0
- package/dist/types/testnets/index.d.ts +11 -0
- package/dist/types/testnets/schemas.d.ts +554 -0
- package/dist/types/testnets/types.d.ts +717 -0
- package/package.json +6 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PriceFeed } from "../../core/pricefeed.js";
|
|
2
|
+
import { TreeNode } from "./stress/classify.js";
|
|
3
|
+
//#region src/permissionless/api/oracles/onchain-feed.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* What the store would say about a feed, from what the chain says instead.
|
|
6
|
+
*
|
|
7
|
+
* Two fields are the store's alone and are answered as unknown rather than
|
|
8
|
+
* guessed: who deployed it is a store row, so it is the zero address, and the
|
|
9
|
+
* staleness period is a store setting a feed that was never added does not
|
|
10
|
+
* have, so it is 0. The compressor reports `PRICE_FEED::EXTERNAL` for a
|
|
11
|
+
* contract it cannot otherwise place; an empty type is the same thing said
|
|
12
|
+
* less clearly.
|
|
13
|
+
*/
|
|
14
|
+
export declare function onchainPriceFeed(node: TreeNode): PriceFeed;
|
|
15
|
+
//#endregion
|
|
@@ -17,7 +17,18 @@ export declare const priceFeedSchema: z.ZodObject<{
|
|
|
17
17
|
stalenessPeriod: z.ZodNumber;
|
|
18
18
|
name: z.ZodString;
|
|
19
19
|
}, z.core.$loose>;
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* {@link PermissionlessPriceFeedAsset}
|
|
22
|
+
*
|
|
23
|
+
* What identifies an asset, which is all a feed's own listing of one says.
|
|
24
|
+
**/
|
|
25
|
+
export declare const priceFeedAssetSchema: z.ZodObject<{
|
|
26
|
+
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
27
|
+
symbol: z.ZodString;
|
|
28
|
+
name: z.ZodString;
|
|
29
|
+
decimals: z.ZodNumber;
|
|
30
|
+
}, z.core.$loose>;
|
|
31
|
+
/** {@link PermissionlessAsset} — identified as above, plus what prices it. */
|
|
21
32
|
export declare const assetSchema: z.ZodObject<{
|
|
22
33
|
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
23
34
|
symbol: z.ZodString;
|
|
@@ -33,7 +44,12 @@ export declare const assetSchema: z.ZodObject<{
|
|
|
33
44
|
name: z.ZodString;
|
|
34
45
|
}, z.core.$loose>>;
|
|
35
46
|
}, z.core.$loose>;
|
|
36
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* {@link PermissionlessPriceFeedStore}
|
|
49
|
+
*
|
|
50
|
+
* A store is a chain's, and is described by the same five fields the chain
|
|
51
|
+
* list answers with, so those are extended rather than restated.
|
|
52
|
+
**/
|
|
37
53
|
export declare const priceFeedStoreSchema: z.ZodObject<{
|
|
38
54
|
chainId: z.ZodNumber;
|
|
39
55
|
name: z.ZodString;
|
|
@@ -64,35 +80,103 @@ export declare const priceFeedStoreSchema: z.ZodObject<{
|
|
|
64
80
|
name: z.ZodString;
|
|
65
81
|
}, z.core.$loose>>;
|
|
66
82
|
}, z.core.$loose>;
|
|
67
|
-
/** {@link
|
|
68
|
-
export declare const
|
|
69
|
-
|
|
70
|
-
marketCaps: z.ZodType<Record<`0x${string}`, Record<`0x${string}`, string | null>>, unknown, z.core.$ZodTypeInternals<Record<`0x${string}`, Record<`0x${string}`, string | null>>, unknown>>;
|
|
71
|
-
time: z.ZodNumber;
|
|
72
|
-
}, z.core.$loose>;
|
|
73
|
-
/** {@link PermissionlessPriceFeedAsset} */
|
|
74
|
-
export declare const priceFeedAssetSchema: z.ZodObject<{
|
|
75
|
-
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
76
|
-
symbol: z.ZodString;
|
|
83
|
+
/** Every chain's {@link PermissionlessPriceFeedStore}, one per chain. */
|
|
84
|
+
export declare const priceFeedStoresSchema: z.ZodArray<z.ZodObject<{
|
|
85
|
+
chainId: z.ZodNumber;
|
|
77
86
|
name: z.ZodString;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
isPublic: z.ZodBoolean;
|
|
88
|
+
isActivated: z.ZodBoolean;
|
|
89
|
+
explorerUrl: z.ZodString;
|
|
90
|
+
assets: z.ZodArray<z.ZodObject<{
|
|
91
|
+
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
92
|
+
symbol: z.ZodString;
|
|
93
|
+
name: z.ZodString;
|
|
94
|
+
decimals: z.ZodNumber;
|
|
95
|
+
owner: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
96
|
+
priceFeeds: z.ZodArray<z.ZodObject<{
|
|
97
|
+
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
98
|
+
contractType: z.ZodString;
|
|
99
|
+
version: z.ZodNumber;
|
|
100
|
+
deployedBy: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
101
|
+
stalenessPeriod: z.ZodNumber;
|
|
102
|
+
name: z.ZodString;
|
|
103
|
+
}, z.core.$loose>>;
|
|
104
|
+
}, z.core.$loose>>;
|
|
105
|
+
priceFeeds: z.ZodArray<z.ZodObject<{
|
|
106
|
+
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
107
|
+
contractType: z.ZodString;
|
|
108
|
+
version: z.ZodNumber;
|
|
109
|
+
deployedBy: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
110
|
+
stalenessPeriod: z.ZodNumber;
|
|
111
|
+
name: z.ZodString;
|
|
112
|
+
}, z.core.$loose>>;
|
|
113
|
+
}, z.core.$loose>>;
|
|
114
|
+
/**
|
|
115
|
+
* {@link PermissionlessIndexedPriceFeedMarket} — the market as the feed's slot
|
|
116
|
+
* in it, before the oracle is asked what period it holds for the slot.
|
|
117
|
+
**/
|
|
81
118
|
export declare const priceFeedMarketSchema: z.ZodObject<{
|
|
82
119
|
market: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
83
120
|
marketConfigurator: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
84
121
|
curatorName: z.ZodNullable<z.ZodString>;
|
|
85
122
|
marketName: z.ZodNullable<z.ZodString>;
|
|
123
|
+
underlyingSymbol: z.ZodNullable<z.ZodString>;
|
|
124
|
+
isUnderlying: z.ZodBoolean;
|
|
125
|
+
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
126
|
+
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
86
127
|
token: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
87
128
|
tokenSymbol: z.ZodNullable<z.ZodString>;
|
|
88
|
-
underlyingSymbol: z.ZodNullable<z.ZodString>;
|
|
89
129
|
reserve: z.ZodBoolean;
|
|
130
|
+
priceOracle: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
131
|
+
}, z.core.$loose>;
|
|
132
|
+
/**
|
|
133
|
+
* {@link PermissionlessMarketSlot} — the same slot read from the chain's end,
|
|
134
|
+
* so the feed is a column rather than what was asked for.
|
|
135
|
+
**/
|
|
136
|
+
export declare const marketSlotSchema: z.ZodObject<{
|
|
137
|
+
market: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
138
|
+
marketConfigurator: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
139
|
+
curatorName: z.ZodNullable<z.ZodString>;
|
|
140
|
+
marketName: z.ZodNullable<z.ZodString>;
|
|
141
|
+
underlyingSymbol: z.ZodNullable<z.ZodString>;
|
|
90
142
|
isUnderlying: z.ZodBoolean;
|
|
91
143
|
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
92
144
|
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
93
|
-
|
|
145
|
+
token: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
146
|
+
tokenSymbol: z.ZodNullable<z.ZodString>;
|
|
147
|
+
reserve: z.ZodBoolean;
|
|
148
|
+
priceOracle: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
149
|
+
chainId: z.ZodNumber;
|
|
150
|
+
underlyingToken: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
151
|
+
isShutdown: z.ZodBoolean;
|
|
152
|
+
priceFeed: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
153
|
+
priceFeedName: z.ZodNullable<z.ZodString>;
|
|
154
|
+
priceFeedInStore: z.ZodBoolean;
|
|
155
|
+
underlyingPriceFeed: z.ZodNullable<z.ZodCustom<`0x${string}`, `0x${string}`>>;
|
|
94
156
|
}, z.core.$loose>;
|
|
95
|
-
/**
|
|
157
|
+
/** Every slot in scope, across whichever chains the read covered. */
|
|
158
|
+
export declare const marketSlotsSchema: z.ZodArray<z.ZodObject<{
|
|
159
|
+
market: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
160
|
+
marketConfigurator: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
161
|
+
curatorName: z.ZodNullable<z.ZodString>;
|
|
162
|
+
marketName: z.ZodNullable<z.ZodString>;
|
|
163
|
+
underlyingSymbol: z.ZodNullable<z.ZodString>;
|
|
164
|
+
isUnderlying: z.ZodBoolean;
|
|
165
|
+
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
166
|
+
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
167
|
+
token: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
168
|
+
tokenSymbol: z.ZodNullable<z.ZodString>;
|
|
169
|
+
reserve: z.ZodBoolean;
|
|
170
|
+
priceOracle: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
171
|
+
chainId: z.ZodNumber;
|
|
172
|
+
underlyingToken: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
173
|
+
isShutdown: z.ZodBoolean;
|
|
174
|
+
priceFeed: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
175
|
+
priceFeedName: z.ZodNullable<z.ZodString>;
|
|
176
|
+
priceFeedInStore: z.ZodBoolean;
|
|
177
|
+
underlyingPriceFeed: z.ZodNullable<z.ZodCustom<`0x${string}`, `0x${string}`>>;
|
|
178
|
+
}, z.core.$loose>>;
|
|
179
|
+
/** {@link PermissionlessIndexedPriceFeedDetails} */
|
|
96
180
|
export declare const priceFeedDetailsSchema: z.ZodObject<{
|
|
97
181
|
chainId: z.ZodNumber;
|
|
98
182
|
priceFeed: z.ZodObject<{
|
|
@@ -114,36 +198,34 @@ export declare const priceFeedDetailsSchema: z.ZodObject<{
|
|
|
114
198
|
marketConfigurator: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
115
199
|
curatorName: z.ZodNullable<z.ZodString>;
|
|
116
200
|
marketName: z.ZodNullable<z.ZodString>;
|
|
117
|
-
token: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
118
|
-
tokenSymbol: z.ZodNullable<z.ZodString>;
|
|
119
201
|
underlyingSymbol: z.ZodNullable<z.ZodString>;
|
|
120
|
-
reserve: z.ZodBoolean;
|
|
121
202
|
isUnderlying: z.ZodBoolean;
|
|
122
203
|
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
123
204
|
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
124
|
-
|
|
205
|
+
token: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
206
|
+
tokenSymbol: z.ZodNullable<z.ZodString>;
|
|
207
|
+
reserve: z.ZodBoolean;
|
|
208
|
+
priceOracle: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
125
209
|
}, z.core.$loose>>;
|
|
126
210
|
}, z.core.$loose>;
|
|
127
|
-
/** {@link PermissionlessPriceFeedMarketCaps} */
|
|
128
|
-
export declare const priceFeedMarketCapsSchema: z.ZodObject<{
|
|
129
|
-
marketCaps: z.ZodType<Record<`0x${string}`, string | null>, unknown, z.core.$ZodTypeInternals<Record<`0x${string}`, string | null>, unknown>>;
|
|
130
|
-
time: z.ZodNumber;
|
|
131
|
-
}, z.core.$loose>;
|
|
132
211
|
/** {@link PermissionlessAssetMarketFeed} */
|
|
133
212
|
export declare const assetMarketFeedSchema: z.ZodObject<{
|
|
134
213
|
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
135
214
|
name: z.ZodNullable<z.ZodString>;
|
|
136
215
|
inStore: z.ZodBoolean;
|
|
137
216
|
}, z.core.$loose>;
|
|
138
|
-
/** {@link PermissionlessAssetMarket} */
|
|
217
|
+
/** {@link PermissionlessAssetMarket} — the market as what prices the asset in it. */
|
|
139
218
|
export declare const assetMarketSchema: z.ZodObject<{
|
|
140
219
|
market: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
141
220
|
marketConfigurator: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
142
221
|
curatorName: z.ZodNullable<z.ZodString>;
|
|
143
222
|
marketName: z.ZodNullable<z.ZodString>;
|
|
144
|
-
underlyingToken: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
145
223
|
underlyingSymbol: z.ZodNullable<z.ZodString>;
|
|
146
224
|
isUnderlying: z.ZodBoolean;
|
|
225
|
+
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
226
|
+
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
227
|
+
underlyingToken: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
228
|
+
underlyingPriceFeed: z.ZodNullable<z.ZodCustom<`0x${string}`, `0x${string}`>>;
|
|
147
229
|
isShutdown: z.ZodBoolean;
|
|
148
230
|
mainFeed: z.ZodNullable<z.ZodObject<{
|
|
149
231
|
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
@@ -155,10 +237,8 @@ export declare const assetMarketSchema: z.ZodObject<{
|
|
|
155
237
|
name: z.ZodNullable<z.ZodString>;
|
|
156
238
|
inStore: z.ZodBoolean;
|
|
157
239
|
}, z.core.$loose>>;
|
|
158
|
-
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
159
|
-
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
160
240
|
}, z.core.$loose>;
|
|
161
|
-
/** {@link
|
|
241
|
+
/** {@link PermissionlessIndexedAssetDetails} */
|
|
162
242
|
export declare const assetDetailsSchema: z.ZodObject<{
|
|
163
243
|
chainId: z.ZodNumber;
|
|
164
244
|
asset: z.ZodObject<{
|
|
@@ -180,9 +260,12 @@ export declare const assetDetailsSchema: z.ZodObject<{
|
|
|
180
260
|
marketConfigurator: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
181
261
|
curatorName: z.ZodNullable<z.ZodString>;
|
|
182
262
|
marketName: z.ZodNullable<z.ZodString>;
|
|
183
|
-
underlyingToken: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
184
263
|
underlyingSymbol: z.ZodNullable<z.ZodString>;
|
|
185
264
|
isUnderlying: z.ZodBoolean;
|
|
265
|
+
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
266
|
+
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
267
|
+
underlyingToken: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
268
|
+
underlyingPriceFeed: z.ZodNullable<z.ZodCustom<`0x${string}`, `0x${string}`>>;
|
|
186
269
|
isShutdown: z.ZodBoolean;
|
|
187
270
|
mainFeed: z.ZodNullable<z.ZodObject<{
|
|
188
271
|
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
@@ -194,16 +277,39 @@ export declare const assetDetailsSchema: z.ZodObject<{
|
|
|
194
277
|
name: z.ZodNullable<z.ZodString>;
|
|
195
278
|
inStore: z.ZodBoolean;
|
|
196
279
|
}, z.core.$loose>>;
|
|
280
|
+
}, z.core.$loose>>;
|
|
281
|
+
}, z.core.$loose>;
|
|
282
|
+
/** {@link PermissionlessAssetQuota} */
|
|
283
|
+
export declare const assetQuotaSchema: z.ZodObject<{
|
|
284
|
+
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
285
|
+
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
286
|
+
isShutdown: z.ZodBoolean;
|
|
287
|
+
underlyingPriceFeed: z.ZodNullable<z.ZodCustom<`0x${string}`, `0x${string}`>>;
|
|
288
|
+
}, z.core.$loose>;
|
|
289
|
+
/** {@link PermissionlessIndexedAssetSummary} */
|
|
290
|
+
export declare const assetSummarySchema: z.ZodObject<{
|
|
291
|
+
chainId: z.ZodNumber;
|
|
292
|
+
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
293
|
+
symbol: z.ZodString;
|
|
294
|
+
underlyingMarketCount: z.ZodNumber;
|
|
295
|
+
marketQuotas: z.ZodArray<z.ZodObject<{
|
|
197
296
|
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
198
297
|
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
298
|
+
isShutdown: z.ZodBoolean;
|
|
299
|
+
underlyingPriceFeed: z.ZodNullable<z.ZodCustom<`0x${string}`, `0x${string}`>>;
|
|
199
300
|
}, z.core.$loose>>;
|
|
200
|
-
quotaLimitUsd: z.ZodNullable<z.ZodNumber>;
|
|
201
|
-
quotaUsedUsd: z.ZodNullable<z.ZodNumber>;
|
|
202
|
-
}, z.core.$loose>;
|
|
203
|
-
/** {@link PermissionlessAssetPrices} */
|
|
204
|
-
export declare const assetPricesSchema: z.ZodObject<{
|
|
205
|
-
prices: z.ZodType<Record<`0x${string}`, string | null>, unknown, z.core.$ZodTypeInternals<Record<`0x${string}`, string | null>, unknown>>;
|
|
206
|
-
marketCaps: z.ZodType<Record<`0x${string}`, string | null>, unknown, z.core.$ZodTypeInternals<Record<`0x${string}`, string | null>, unknown>>;
|
|
207
|
-
time: z.ZodNumber;
|
|
208
301
|
}, z.core.$loose>;
|
|
302
|
+
/** The list of {@link PermissionlessAssetSummary}, already ordered. */
|
|
303
|
+
export declare const assetSummariesSchema: z.ZodArray<z.ZodObject<{
|
|
304
|
+
chainId: z.ZodNumber;
|
|
305
|
+
address: z.ZodCustom<`0x${string}`, `0x${string}`>;
|
|
306
|
+
symbol: z.ZodString;
|
|
307
|
+
underlyingMarketCount: z.ZodNumber;
|
|
308
|
+
marketQuotas: z.ZodArray<z.ZodObject<{
|
|
309
|
+
quotaLimit: z.ZodNullable<z.ZodNumber>;
|
|
310
|
+
quotaUsed: z.ZodNullable<z.ZodNumber>;
|
|
311
|
+
isShutdown: z.ZodBoolean;
|
|
312
|
+
underlyingPriceFeed: z.ZodNullable<z.ZodCustom<`0x${string}`, `0x${string}`>>;
|
|
313
|
+
}, z.core.$loose>>;
|
|
314
|
+
}, z.core.$loose>>;
|
|
209
315
|
//#endregion
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { GroupImpact } from "./types.js";
|
|
2
|
+
//#region src/permissionless/api/oracles/score/formula.d.ts
|
|
3
|
+
/** What every source of a group is made to answer, as a multiple of now. */
|
|
4
|
+
export declare const SCORE_MULTIPLIER = 10;
|
|
5
|
+
/**
|
|
6
|
+
* How far the final price moved, as a multiple of where it was, either way:
|
|
7
|
+
* 1 for a price that did not move, 1.04 for one 4% off, and
|
|
8
|
+
* {@link SCORE_MULTIPLIER} for one that took the whole lie — the most it can
|
|
9
|
+
* take from one leg, and where a price over two legs of one group, moved
|
|
10
|
+
* further, is held too.
|
|
11
|
+
*
|
|
12
|
+
* `null` for a price that stopped answering, which is not a move.
|
|
13
|
+
*/
|
|
14
|
+
export declare function scoreOfFactor(factor: number | null): number | null;
|
|
15
|
+
/**
|
|
16
|
+
* The price a market settles on: the lower of main and reserve, or the main
|
|
17
|
+
* feed's alone where there is no reserve to compare it with. `null` where a
|
|
18
|
+
* feed it needs does not answer.
|
|
19
|
+
*/
|
|
20
|
+
export declare function finalPrice(main: bigint | null, reserve: bigint | null | undefined): bigint | null;
|
|
21
|
+
/** `stressed / base` as a float, `null` where the stressed price is gone. */
|
|
22
|
+
export declare function factorOf(base: bigint, stressed: bigint | null): number | null;
|
|
23
|
+
/**
|
|
24
|
+
* The market's score and the group it comes from: the furthest any group
|
|
25
|
+
* moved its price. 1 where nothing moved it — no group did, or no source
|
|
26
|
+
* feeds the price at all.
|
|
27
|
+
*
|
|
28
|
+
* A group under which the price stops answering moves nothing and does not
|
|
29
|
+
* set the score; it is listed after those that do, for a reader to see.
|
|
30
|
+
*/
|
|
31
|
+
export declare function worstOf(impacts: GroupImpact[]): {
|
|
32
|
+
score: number;
|
|
33
|
+
impacts: GroupImpact[];
|
|
34
|
+
worst: GroupImpact | null;
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AssetScore, AssetScoresArgs, FeedPairScore, FeedPairScoreArgs, GroupImpact, MarketScore, ScoredFeed } from "./types.js";
|
|
2
|
+
import { SCORE_MULTIPLIER, factorOf, finalPrice, scoreOfFactor, worstOf } from "./formula.js";
|
|
3
|
+
import { runAssetScores, runFeedPairScore } from "./run.js";
|
|
4
|
+
export { AssetScore, AssetScoresArgs, FeedPairScore, FeedPairScoreArgs, GroupImpact, MarketScore, SCORE_MULTIPLIER, ScoredFeed, factorOf, finalPrice, runAssetScores, runFeedPairScore, scoreOfFactor, worstOf };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AssetScore, FeedPairScore } from "./types.js";
|
|
2
|
+
import { PermissionlessMarketSlot } from "../types.js";
|
|
3
|
+
import { Address, Chain, PublicClient, Transport } from "viem";
|
|
4
|
+
//#region src/permissionless/api/oracles/score/run.d.ts
|
|
5
|
+
type Logger = {
|
|
6
|
+
warn(message: string): void;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Every asset of one chain, scored by what each of its source groups can do
|
|
10
|
+
* to the price its running markets hold for it.
|
|
11
|
+
*
|
|
12
|
+
* One read of the oracles' feed trees, then the simulation of every market's
|
|
13
|
+
* main and reserve pair at once — see {@link simulatePairs}.
|
|
14
|
+
**/
|
|
15
|
+
export declare function runAssetScores({ client, chainId, slots, compressor, logger }: {
|
|
16
|
+
client: PublicClient<Transport, Chain>;
|
|
17
|
+
chainId: number;
|
|
18
|
+
slots: PermissionlessMarketSlot[];
|
|
19
|
+
compressor: Address;
|
|
20
|
+
logger?: Logger;
|
|
21
|
+
}): Promise<AssetScore[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Any main feed and reserve on a chain, scored the way a market holding them
|
|
24
|
+
* would be — whether or not any market does yet.
|
|
25
|
+
*
|
|
26
|
+
* The two trees are read off the compressor by feed rather than by oracle,
|
|
27
|
+
* so a feed the curator has only just deployed scores as well as one in use.
|
|
28
|
+
*
|
|
29
|
+
* @throws Where there is nothing to score: the compressor cannot read a
|
|
30
|
+
* feed, the main feed is a `ZeroPriceFeed`, or the final price does not
|
|
31
|
+
* answer even with every pull feed under it freshened.
|
|
32
|
+
**/
|
|
33
|
+
export declare function runFeedPairScore({ client, chainId, compressor, main, reserve, logger }: {
|
|
34
|
+
client: PublicClient<Transport, Chain>;
|
|
35
|
+
chainId: number;
|
|
36
|
+
compressor: Address;
|
|
37
|
+
main: Address;
|
|
38
|
+
reserve?: Address;
|
|
39
|
+
logger?: Logger;
|
|
40
|
+
}): Promise<FeedPairScore>;
|
|
41
|
+
//#endregion
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Address } from "viem";
|
|
2
|
+
//#region src/permissionless/api/oracles/score/types.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* One of a market's two feeds for a token, as the score reads it.
|
|
5
|
+
**/
|
|
6
|
+
export interface ScoredFeed {
|
|
7
|
+
feed: Address;
|
|
8
|
+
/**
|
|
9
|
+
* The store's name for the feed, `null` where it has none or where the
|
|
10
|
+
* feed was named by address alone, as a pair to score is.
|
|
11
|
+
*/
|
|
12
|
+
name: string | null;
|
|
13
|
+
/** Gearbox contract type of the feed itself, `""` for one it never deployed. */
|
|
14
|
+
contractType: string;
|
|
15
|
+
/**
|
|
16
|
+
* Every source group beneath the feed: `"Chainlink"`, `"Lido"`, or the
|
|
17
|
+
* description of a source nothing could name.
|
|
18
|
+
*/
|
|
19
|
+
sources: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* What one source group, lying, does to the price a market holds for an
|
|
23
|
+
* asset.
|
|
24
|
+
**/
|
|
25
|
+
export interface GroupImpact {
|
|
26
|
+
group: string;
|
|
27
|
+
/** The group was recognised rather than inferred from one feed's name. */
|
|
28
|
+
identified: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* The group's sources this market's feeds read, by what they say they are:
|
|
31
|
+
* `"stETH / ETH"`, `"ETH / USD"`.
|
|
32
|
+
*/
|
|
33
|
+
feeds: string[];
|
|
34
|
+
/** Which of the market's feeds read the group. */
|
|
35
|
+
reaches: "main" | "reserve" | "both";
|
|
36
|
+
/**
|
|
37
|
+
* The final price under the lie over the final price now, in USD. `null` is
|
|
38
|
+
* a price that stopped answering.
|
|
39
|
+
*/
|
|
40
|
+
factor: number | null;
|
|
41
|
+
/** 1 to 10, by {@link scoreOfFactor}; `null` where the price stopped answering. */
|
|
42
|
+
score: number | null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* How far the price a main and a reserve feed give together can be pushed:
|
|
46
|
+
* their manipulation resistance, from 1 (does not move) to 10 (takes the
|
|
47
|
+
* whole lie).
|
|
48
|
+
*
|
|
49
|
+
* Every source group behind the two feeds is made, one group at a time, to
|
|
50
|
+
* answer {@link SCORE_MULTIPLIER} times what it answers now. The pair scores
|
|
51
|
+
* by the group that moves its final price — `min(main, reserve)` — the
|
|
52
|
+
* furthest, as a multiple either way.
|
|
53
|
+
**/
|
|
54
|
+
export interface FeedPairScore {
|
|
55
|
+
main: ScoredFeed;
|
|
56
|
+
/** `null` where there is no reserve at all. */
|
|
57
|
+
reserve: ScoredFeed | null;
|
|
58
|
+
/**
|
|
59
|
+
* The final price is `min(main, reserve)`: a reserve is present, is not a
|
|
60
|
+
* `ZeroPriceFeed`, and answers. Where it is not, the final price is the
|
|
61
|
+
* main feed's alone.
|
|
62
|
+
*/
|
|
63
|
+
hasReserve: boolean;
|
|
64
|
+
/** The final price now, in USD. */
|
|
65
|
+
price: number;
|
|
66
|
+
/** Every group behind the two feeds, the most damaging first. */
|
|
67
|
+
impacts: GroupImpact[];
|
|
68
|
+
/** The group the score comes from; `null` where no group moves the price. */
|
|
69
|
+
worst: GroupImpact | null;
|
|
70
|
+
/**
|
|
71
|
+
* The score rests on a source nothing could name.
|
|
72
|
+
*
|
|
73
|
+
* Such a source is a group of its own and is perturbed alone, so where one
|
|
74
|
+
* feed reads it and the other does not, the other is taken to hold — which
|
|
75
|
+
* it would not if one operator stood behind both.
|
|
76
|
+
*/
|
|
77
|
+
unverified: boolean;
|
|
78
|
+
score: number;
|
|
79
|
+
/** How the pair is set up, where that explains its score. */
|
|
80
|
+
notes: string[];
|
|
81
|
+
}
|
|
82
|
+
/** One market's price for one asset, scored as the pair of feeds it holds. */
|
|
83
|
+
export interface MarketScore extends FeedPairScore {
|
|
84
|
+
market: Address;
|
|
85
|
+
marketName: string | null;
|
|
86
|
+
marketConfigurator: Address;
|
|
87
|
+
curatorName: string | null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* One asset's score: its worst market's.
|
|
91
|
+
*
|
|
92
|
+
* The maximum, not an average, because the asset is only as well guarded as
|
|
93
|
+
* the most exposed market that prices it.
|
|
94
|
+
**/
|
|
95
|
+
export interface AssetScore {
|
|
96
|
+
chainId: number;
|
|
97
|
+
asset: Address;
|
|
98
|
+
symbol: string | null;
|
|
99
|
+
/** `null` for an asset no running market prices: it is switched off in all. */
|
|
100
|
+
score: number | null;
|
|
101
|
+
/** Some market's score rests on a source nothing could name. */
|
|
102
|
+
unverified: boolean;
|
|
103
|
+
/** The market the score comes from. */
|
|
104
|
+
worst: MarketScore | null;
|
|
105
|
+
/** Every running market pricing the asset, worst first. */
|
|
106
|
+
markets: MarketScore[];
|
|
107
|
+
}
|
|
108
|
+
export interface AssetScoresArgs {
|
|
109
|
+
/** Omitted scores every chain the backend serves markets for. */
|
|
110
|
+
chainId?: number;
|
|
111
|
+
}
|
|
112
|
+
export interface FeedPairScoreArgs {
|
|
113
|
+
chainId: number;
|
|
114
|
+
main: Address;
|
|
115
|
+
/** Omitted scores the main feed alone, as a market with no reserve. */
|
|
116
|
+
reserve?: Address;
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { StressSource } from "./types.js";
|
|
2
|
+
import { Address } from "viem";
|
|
3
|
+
//#region src/permissionless/api/oracles/stress/classify.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Who a price ultimately comes from, worked out from what the chain says
|
|
6
|
+
* about the feed reporting it.
|
|
7
|
+
*
|
|
8
|
+
* There is no registry on chain of which aggregator belongs to whom, so this
|
|
9
|
+
* is a reading of three things the chain does carry: the Gearbox contract
|
|
10
|
+
* type, which names the provider outright for the feeds Gearbox deploys; the
|
|
11
|
+
* `description()` every Chainlink-shaped feed returns; and the interface
|
|
12
|
+
* version, which separates Chainlink's own proxies from the many contracts
|
|
13
|
+
* that imitate them.
|
|
14
|
+
*
|
|
15
|
+
* Every rule is open to inspection and every unmatched feed is reported as
|
|
16
|
+
* unmatched, because the alternative — guessing from a symbol, or sweeping
|
|
17
|
+
* the remainder into one bucket — would understate exactly the part of the
|
|
18
|
+
* answer a reader should distrust.
|
|
19
|
+
**/
|
|
20
|
+
/** One node of an oracle's feed tree, as the compressor reports it. */
|
|
21
|
+
export interface TreeNode {
|
|
22
|
+
address: Address;
|
|
23
|
+
/** Gearbox contract type, `""` for a contract it never deployed. */
|
|
24
|
+
contractType: string;
|
|
25
|
+
/** `AggregatorV3Interface.version()`, or 0 where there is none. */
|
|
26
|
+
version: number;
|
|
27
|
+
description: string;
|
|
28
|
+
/** The feeds it reads, lowercased. Empty makes it a leaf. */
|
|
29
|
+
underlyingFeeds: Address[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Every source behind a chain's feed trees.
|
|
33
|
+
*
|
|
34
|
+
* A source per contract, not per feed: two of an oracle's trees carrying the
|
|
35
|
+
* same aggregator is one source read twice, and the test varies it once.
|
|
36
|
+
*
|
|
37
|
+
* `rateTargets` says which contract each rate-bearing feed reads its rate
|
|
38
|
+
* from — the feed's own `lpContract`, read separately because the compressor
|
|
39
|
+
* does not report it. A feed missing from it is left out with a reason, since
|
|
40
|
+
* perturbing the whole feed instead would charge its protocol with a failure
|
|
41
|
+
* of whatever prices the thing the rate is denominated in.
|
|
42
|
+
**/
|
|
43
|
+
export declare function classifySources(chainId: number, nodes: TreeNode[], rateTargets: Map<Address, Address>, baselineOf: (target: Address) => bigint | null): {
|
|
44
|
+
sources: StressSource[];
|
|
45
|
+
unresolved: TreeNode[];
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The sources each of the given feeds is priced through, following the trees
|
|
49
|
+
* down from every one of them.
|
|
50
|
+
*
|
|
51
|
+
* A feed is reached by a source when the source sits anywhere beneath it, at
|
|
52
|
+
* any depth: a market reading a composite of a composite of a Chainlink
|
|
53
|
+
* aggregator is a market Chainlink can move. Memoised over the whole forest,
|
|
54
|
+
* so a node shared by twenty trees is walked once.
|
|
55
|
+
**/
|
|
56
|
+
export declare function sourcesByFeed(roots: Address[], nodes: Map<Address, TreeNode>, sources: StressSource[]): Map<Address, Set<Address>>;
|
|
57
|
+
//#endregion
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BreakingPoint, FeedOutcome, GroupReport, GroupScenarioOutcome, SlotOutcome, StressReport, StressScenario, StressSource, StressSourceKind, StressTestArgs } from "./types.js";
|
|
2
|
+
import { TreeNode, classifySources, sourcesByFeed } from "./classify.js";
|
|
3
|
+
import { UNBOUNDED_DOWN, UNBOUNDED_UP, groupOverride, perturb, rateStub, roundDataStub } from "./override.js";
|
|
4
|
+
import { DEFAULT_SCENARIOS, RATE_FEED_TYPE, readFeedTrees, readForest, readRateTargets, readUnder, runStressTest } from "./run.js";
|
|
5
|
+
import { scoreGroup, slotHarm, verdictOf } from "./score.js";
|
|
6
|
+
export { BreakingPoint, DEFAULT_SCENARIOS, FeedOutcome, GroupReport, GroupScenarioOutcome, RATE_FEED_TYPE, SlotOutcome, StressReport, StressScenario, StressSource, StressSourceKind, StressTestArgs, TreeNode, UNBOUNDED_DOWN, UNBOUNDED_UP, classifySources, groupOverride, perturb, rateStub, readFeedTrees, readForest, readRateTargets, readUnder, roundDataStub, runStressTest, scoreGroup, slotHarm, sourcesByFeed, verdictOf };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { StressSource } from "./types.js";
|
|
2
|
+
import { Hex, StateOverride } from "viem";
|
|
3
|
+
//#region src/permissionless/api/oracles/stress/override.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Runtime code answering every call with the same five words.
|
|
6
|
+
*
|
|
7
|
+
* Deliberately selector-blind. A price feed is read through more than
|
|
8
|
+
* `latestRoundData` — `decimals`, `version`, sometimes `latestAnswer` — and
|
|
9
|
+
* dispatching on each would mean knowing which of them every caller in a tree
|
|
10
|
+
* reaches for. Five words decode as the round data; a caller expecting one
|
|
11
|
+
* word reads the first, which is why `roundId` is set to the 8 decimals every
|
|
12
|
+
* Gearbox feed reports rather than to a round number.
|
|
13
|
+
*
|
|
14
|
+
* `answeredInRound` is the same 8, so the `answeredInRound >= roundId` check
|
|
15
|
+
* the older consumers make passes.
|
|
16
|
+
**/
|
|
17
|
+
export declare function roundDataStub(answer: bigint, updatedAt: bigint): Hex;
|
|
18
|
+
/**
|
|
19
|
+
* Runtime code answering every call with one word.
|
|
20
|
+
*
|
|
21
|
+
* What an exchange rate getter returns, whichever of them the feed calls:
|
|
22
|
+
* `stEthPerToken`, `convertToAssets`, `get_virtual_price`, `pricePerShare`
|
|
23
|
+
* and `getRate` all answer a single `uint256`, so the stub does not need to
|
|
24
|
+
* know which.
|
|
25
|
+
**/
|
|
26
|
+
export declare function rateStub(rate: bigint): Hex;
|
|
27
|
+
/**
|
|
28
|
+
* The two unbounded ends, as far as the types involved can carry them.
|
|
29
|
+
*
|
|
30
|
+
* "Infinitely large" has to stop somewhere: a price is an `int256` and the
|
|
31
|
+
* arithmetic above it multiplies, so a genuinely enormous answer overflows
|
|
32
|
+
* inside the composite feed and reverts — which would be scored as the
|
|
33
|
+
* oracle resisting, when all that happened is that the test asked something
|
|
34
|
+
* the type cannot hold. `1e12` times the current answer is past any bound,
|
|
35
|
+
* any sanity check and any collateral ratio, and still multiplies.
|
|
36
|
+
*/
|
|
37
|
+
export declare const UNBOUNDED_UP = 1000000000000;
|
|
38
|
+
/** The other end: a thousandth of a trillionth, which is as near zero. */
|
|
39
|
+
export declare const UNBOUNDED_DOWN = 1e-12;
|
|
40
|
+
/**
|
|
41
|
+
* What a source should answer under a multiplier, given what it answers now.
|
|
42
|
+
*
|
|
43
|
+
* Floored at one rather than at zero: a multiplier small enough to round the
|
|
44
|
+
* baseline away would be testing a feed reporting nothing, which is the revert
|
|
45
|
+
* case and is a different scenario with a different meaning.
|
|
46
|
+
*/
|
|
47
|
+
export declare function perturb(baseline: bigint, multiplier: number): bigint;
|
|
48
|
+
/**
|
|
49
|
+
* The state override that makes every source of a group answer a multiple of
|
|
50
|
+
* what it answers now.
|
|
51
|
+
*
|
|
52
|
+
* One override per contract, so a group whose sources share an aggregator
|
|
53
|
+
* perturbs it once. Sources with nothing behind them and sources that are not
|
|
54
|
+
* answering are both left out, for the reasons on
|
|
55
|
+
* {@link StressSource.perturbable} and {@link StressSource.baseline} — an
|
|
56
|
+
* empty result is a group there is nothing to simulate about.
|
|
57
|
+
**/
|
|
58
|
+
export declare function groupOverride(sources: StressSource[], multiplier: number, updatedAt: bigint): StateOverride;
|
|
59
|
+
//#endregion
|