@across-protocol/sdk 3.3.19 → 3.3.21
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/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +11 -8
- package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +87 -54
- package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
- package/dist/cjs/contracts/acrossConfigStore.d.ts +5 -5
- package/dist/cjs/interfaces/ConfigStore.d.ts +7 -30
- package/dist/cjs/lpFeeCalculator/rateModel.d.ts +1 -27
- package/dist/cjs/lpFeeCalculator/rateModel.js +1 -77
- package/dist/cjs/lpFeeCalculator/rateModel.js.map +1 -1
- package/dist/cjs/pool/poolClient.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.js +1 -0
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +11 -16
- package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +103 -77
- package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
- package/dist/esm/contracts/acrossConfigStore.d.ts +5 -5
- package/dist/esm/interfaces/ConfigStore.d.ts +7 -106
- package/dist/esm/lpFeeCalculator/rateModel.d.ts +1 -39
- package/dist/esm/lpFeeCalculator/rateModel.js +0 -109
- package/dist/esm/lpFeeCalculator/rateModel.js.map +1 -1
- package/dist/esm/pool/poolClient.js.map +1 -1
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/types/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +11 -16
- package/dist/types/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts.map +1 -1
- package/dist/types/contracts/acrossConfigStore.d.ts +5 -5
- package/dist/types/contracts/acrossConfigStore.d.ts.map +1 -1
- package/dist/types/interfaces/ConfigStore.d.ts +7 -106
- package/dist/types/interfaces/ConfigStore.d.ts.map +1 -1
- package/dist/types/lpFeeCalculator/rateModel.d.ts +1 -39
- package/dist/types/lpFeeCalculator/rateModel.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.ts +126 -96
- package/src/contracts/acrossConfigStore.ts +5 -5
- package/src/interfaces/ConfigStore.ts +8 -112
- package/src/lpFeeCalculator/rateModel.ts +1 -144
- package/src/pool/poolClient.ts +3 -3
- package/src/utils/index.ts +1 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RateModel } from "../lpFeeCalculator";
|
|
2
2
|
import { BigNumber } from "../utils";
|
|
3
3
|
import { SortableEvent } from "./Common";
|
|
4
4
|
export interface ParsedTokenConfig {
|
|
5
|
-
rateModel:
|
|
5
|
+
rateModel: RateModel;
|
|
6
6
|
routeRateModel?: {
|
|
7
|
-
[path: string]:
|
|
7
|
+
[path: string]: RateModel;
|
|
8
8
|
};
|
|
9
|
-
uba?: UBAOnChainConfigType;
|
|
10
9
|
spokeTargetBalances?: {
|
|
11
10
|
[chainId: number]: {
|
|
12
11
|
target: string;
|
|
@@ -40,6 +39,10 @@ export interface RouteRateModelUpdate extends SortableEvent {
|
|
|
40
39
|
};
|
|
41
40
|
l1Token: string;
|
|
42
41
|
}
|
|
42
|
+
export interface RateModelUpdate extends SortableEvent {
|
|
43
|
+
rateModel: string;
|
|
44
|
+
l1Token: string;
|
|
45
|
+
}
|
|
43
46
|
export interface TokenConfig extends SortableEvent {
|
|
44
47
|
key: string;
|
|
45
48
|
value: string;
|
|
@@ -56,106 +59,4 @@ export interface DisabledChainsUpdate extends SortableEvent {
|
|
|
56
59
|
export interface LiteChainsIdListUpdate<ValueStore = number[]> extends GlobalConfigUpdate<ValueStore> {
|
|
57
60
|
timestamp: number;
|
|
58
61
|
}
|
|
59
|
-
/**
|
|
60
|
-
* A generic type of a dictionary that has string keys and values of type T. This
|
|
61
|
-
* record is enforced to have a default entry within the "default" key.
|
|
62
|
-
* @type Value The type of the values in the dictionary.
|
|
63
|
-
*/
|
|
64
|
-
type RecordWithDefaultEntry<Value> = Record<string, Value>;
|
|
65
|
-
/**
|
|
66
|
-
* A generic type for an array of tuples.
|
|
67
|
-
* @type Value The type of the values in the array.
|
|
68
|
-
*/
|
|
69
|
-
type ArrayOfTuples<Value> = [Value, Value][];
|
|
70
|
-
/**
|
|
71
|
-
* A type for the UBA config object stored both on and off chain.
|
|
72
|
-
* @type T The type of the values in the config.
|
|
73
|
-
* @note This is a dictionary of parameters that defines a fee curve for the token.
|
|
74
|
-
* These parameters can be further subindexed by a route (e.g. using the key "1-10" or "42161-1")
|
|
75
|
-
* to create a specific fee curve for a token per route. The subkeys are as followed:
|
|
76
|
-
* - alpha: The alpha parameter of the fee curve.
|
|
77
|
-
* - gamma: The gamma parameter of the fee curve.
|
|
78
|
-
* - omega: The omega parameter of the fee curve.
|
|
79
|
-
* - rebalance: The rebalance parameters of the fee curve.
|
|
80
|
-
*/
|
|
81
|
-
type UBAAgnosticConfigType<T> = {
|
|
82
|
-
/**
|
|
83
|
-
* A DAO controlled variable to track any donations made to the incentivePool liquidity
|
|
84
|
-
*/
|
|
85
|
-
incentivePoolAdjustment?: Record<string, T>;
|
|
86
|
-
/**
|
|
87
|
-
* Used to scale rewards when a fee is larger than the incentive balance
|
|
88
|
-
*/
|
|
89
|
-
ubaRewardMultiplier?: Record<string, T>;
|
|
90
|
-
/**
|
|
91
|
-
* This is a scalar value that is a constant percentage of each transfer that is allocated for LPs.
|
|
92
|
-
* This value can be determined by token and route-by-route.
|
|
93
|
-
*/
|
|
94
|
-
alpha: RecordWithDefaultEntry<T>;
|
|
95
|
-
/**
|
|
96
|
-
* This is a piecewise linear function (defined by a vector of cut-off points and the values at
|
|
97
|
-
* those points) that determine additional LP fees as a function of utilization. This piecewise
|
|
98
|
-
* linear function can be determined by token and chain-by-chain.
|
|
99
|
-
*/
|
|
100
|
-
gamma: RecordWithDefaultEntry<ArrayOfTuples<T>>;
|
|
101
|
-
/**
|
|
102
|
-
* This is a piecewise linear function (defined by a vector of cut-off points and the values at
|
|
103
|
-
* those points) that determine the balancing fees (rewards) that are imposed on (paid to) a user
|
|
104
|
-
* who makes a transfer involving a particular chain. There is a single piecewise linear function for
|
|
105
|
-
* each token/chain combination. A transfer will incur a balancing fee on both the origin and destination
|
|
106
|
-
* chains.
|
|
107
|
-
*/
|
|
108
|
-
omega: RecordWithDefaultEntry<ArrayOfTuples<T>>;
|
|
109
|
-
/**
|
|
110
|
-
* This is a set of parameters that determine when a rebalance is triggered. A rebalance is triggered
|
|
111
|
-
* when the utilization of a pool is outside of the range defined by the lower and upper thresholds.
|
|
112
|
-
*/
|
|
113
|
-
rebalance: RecordWithDefaultEntry<{
|
|
114
|
-
/**
|
|
115
|
-
* For tokens/chains that have a supported bridge, these are the lower and upper threshold that trigger
|
|
116
|
-
* the reallocation of funds. i.e. If the running balance on a chain moves below (above) threshold_lower
|
|
117
|
-
* (threshold_upper) then the bridge moves funds from Ethereum to the chain (from the chain to Ethereum).
|
|
118
|
-
*/
|
|
119
|
-
threshold_lower?: T;
|
|
120
|
-
/**
|
|
121
|
-
* For tokens/chains that have a supported bridge, these are the lower and upper threshold that trigger
|
|
122
|
-
* the reallocation of funds. i.e. If the running balance on a chain moves below (above) threshold_lower
|
|
123
|
-
* (threshold_upper) then the bridge moves funds from Ethereum to the chain (from the chain to Ethereum).
|
|
124
|
-
*/
|
|
125
|
-
threshold_upper?: T;
|
|
126
|
-
/**
|
|
127
|
-
* For tokens/chains that have a supported bridge, these are the values that are targeted whenever funds
|
|
128
|
-
* are reallocated.
|
|
129
|
-
*/
|
|
130
|
-
target_lower?: T;
|
|
131
|
-
/**
|
|
132
|
-
* For tokens/chains that have a supported bridge, these are the values that are targeted whenever funds
|
|
133
|
-
* are reallocated.
|
|
134
|
-
*/
|
|
135
|
-
target_upper?: T;
|
|
136
|
-
}>;
|
|
137
|
-
};
|
|
138
|
-
/**
|
|
139
|
-
* A type for the UBA config object stored on chain.
|
|
140
|
-
*/
|
|
141
|
-
export type UBAOnChainConfigType = UBAAgnosticConfigType<string>;
|
|
142
|
-
/**
|
|
143
|
-
* A type for the UBA config object after it has been parsed.
|
|
144
|
-
*/
|
|
145
|
-
export type UBAParsedConfigType = UBAAgnosticConfigType<BigNumber>;
|
|
146
|
-
/**
|
|
147
|
-
* A type for UBAConfig Update events.
|
|
148
|
-
*/
|
|
149
|
-
export type UBAConfigUpdates = SortableEvent & {
|
|
150
|
-
config: UBAParsedConfigType;
|
|
151
|
-
l1Token: string;
|
|
152
|
-
};
|
|
153
|
-
/**
|
|
154
|
-
* A type for stringified UBAConfig Update events.
|
|
155
|
-
*/
|
|
156
|
-
export type UBASerializedConfigUpdates = SortableEvent & {
|
|
157
|
-
config: UBAOnChainConfigType;
|
|
158
|
-
l1Token: string;
|
|
159
|
-
};
|
|
160
|
-
export {};
|
|
161
62
|
//# sourceMappingURL=ConfigStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigStore.d.ts","sourceRoot":"","sources":["../../../src/interfaces/ConfigStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ConfigStore.d.ts","sourceRoot":"","sources":["../../../src/interfaces/ConfigStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,CAAC,EAAE;QACf,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;KAC3B,CAAC;IACF,mBAAmB,CAAC,EAAE;QACpB,CAAC,OAAO,EAAE,MAAM,GAAG;YACjB,MAAM,EAAE,MAAM,CAAC;YACf,SAAS,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,MAAM,iCAAiC,GAAG,IAAI,CAAC,sBAAsB,EAAE,WAAW,GAAG,QAAQ,CAAC,GAAG;IACrG,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,wBAAyB,SAAQ,aAAa;IAC7D,mBAAmB,CAAC,EAAE;QACpB,CAAC,OAAO,EAAE,MAAM,GAAG,sBAAsB,CAAC;KAC3C,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mCAAoC,SAAQ,aAAa;IACxE,mBAAmB,CAAC,EAAE;QACpB,CAAC,OAAO,EAAE,MAAM,GAAG,iCAAiC,CAAC;KACtD,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,cAAc,EAAE;QACd,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;KACxB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB,CAAC,UAAU,GAAG,MAAM,CAAE,SAAQ,aAAa;IAC5E,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB,CAAC,UAAU,GAAG,MAAM,CAAE,SAAQ,kBAAkB,CAAC,UAAU,CAAC;IACnG,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB,CAAC,UAAU,GAAG,MAAM,EAAE,CAAE,SAAQ,kBAAkB,CAAC,UAAU,CAAC;IACnG,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -1,46 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
[l1TokenAddress: string]: {
|
|
3
|
-
blockNumber: number;
|
|
4
|
-
rateModel: string;
|
|
5
|
-
}[];
|
|
6
|
-
};
|
|
7
|
-
export type RateModelEvent = {
|
|
8
|
-
blockNumber: number;
|
|
9
|
-
transactionIndex: number;
|
|
10
|
-
logIndex: number;
|
|
11
|
-
rateModel: string;
|
|
12
|
-
l1Token: string;
|
|
13
|
-
};
|
|
14
|
-
interface RateModel {
|
|
15
|
-
UBar: string;
|
|
16
|
-
R0: string;
|
|
17
|
-
R1: string;
|
|
18
|
-
R2: string;
|
|
19
|
-
}
|
|
20
|
-
export declare class RateModelDictionary {
|
|
21
|
-
rateModelDictionary: RateModelEventsDictionary;
|
|
22
|
-
private _throwIfNotInitialized;
|
|
23
|
-
updateWithEvents(rateModelEvents: RateModelEvent[]): void;
|
|
24
|
-
/**
|
|
25
|
-
* Return the rate model for L1 token set at the block height.
|
|
26
|
-
* @param l1Token L1 token address to get rate model for.
|
|
27
|
-
* @param blockNumber Block height to get rate model for.
|
|
28
|
-
* @returns Rate model object.
|
|
29
|
-
*/
|
|
30
|
-
getRateModelForBlockNumber(l1Token: string, blockNumber?: number): RateModel;
|
|
31
|
-
/**
|
|
32
|
-
* @notice Return all L1 tokens that had a rate model associated with it at the block number.
|
|
33
|
-
* @param blockNumber Returns l1 tokens that were mapped to a rate model at this block height. If undefined,
|
|
34
|
-
* this function will return all L1 tokens that have a block number as of the latest block height.
|
|
35
|
-
* @returns array of L1 token addresses.
|
|
36
|
-
*/
|
|
37
|
-
getL1TokensFromRateModel(blockNumber?: number | undefined): string[];
|
|
38
|
-
}
|
|
1
|
+
import { RateModel } from "../lpFeeCalculator";
|
|
39
2
|
/**
|
|
40
3
|
* Helper method that returns parsed rate model from string, or throws.
|
|
41
4
|
* @param rateModelString Stringified rate model to parse.
|
|
42
5
|
* @returns Rate model object. Must conform to `expectedRateModelKeys` format.
|
|
43
6
|
*/
|
|
44
7
|
export declare const parseAndReturnRateModelFromString: (rateModelString: string) => RateModel;
|
|
45
|
-
export {};
|
|
46
8
|
//# sourceMappingURL=rateModel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateModel.d.ts","sourceRoot":"","sources":["../../../src/lpFeeCalculator/rateModel.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rateModel.d.ts","sourceRoot":"","sources":["../../../src/lpFeeCalculator/rateModel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI/C;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,oBAAqB,MAAM,KAAG,SA8B3E,CAAC"}
|
|
@@ -20,6 +20,7 @@ export * from "./BlockExplorerUtils";
|
|
|
20
20
|
export * from "./BigNumberUtils";
|
|
21
21
|
export * from "./CachingUtils";
|
|
22
22
|
export * from "./NetworkUtils";
|
|
23
|
+
export * from "./Profiler";
|
|
23
24
|
export * from "./Multicall";
|
|
24
25
|
export * from "./ReviverUtils";
|
|
25
26
|
export * from "./DepositUtils";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { utils
|
|
1
|
+
import { utils } from "@uma/sdk";
|
|
2
2
|
import assert from "assert";
|
|
3
3
|
import { Contract } from "ethers";
|
|
4
4
|
import winston from "winston";
|
|
@@ -6,7 +6,6 @@ import { isError } from "../../typeguards";
|
|
|
6
6
|
import {
|
|
7
7
|
EventSearchConfig,
|
|
8
8
|
MakeOptional,
|
|
9
|
-
findLast,
|
|
10
9
|
isArrayOf,
|
|
11
10
|
isDefined,
|
|
12
11
|
isPositiveInteger,
|
|
@@ -16,6 +15,7 @@ import {
|
|
|
16
15
|
sortEventsDescending,
|
|
17
16
|
spreadEventWithBlockNumber,
|
|
18
17
|
toBN,
|
|
18
|
+
toWei,
|
|
19
19
|
utf8ToHex,
|
|
20
20
|
} from "../../utils";
|
|
21
21
|
import { PROTOCOL_DEFAULT_CHAIN_ID_INDICES } from "../../constants";
|
|
@@ -26,16 +26,17 @@ import {
|
|
|
26
26
|
LiteChainsIdListUpdate,
|
|
27
27
|
Log,
|
|
28
28
|
ParsedTokenConfig,
|
|
29
|
+
RateModelUpdate,
|
|
29
30
|
RouteRateModelUpdate,
|
|
30
31
|
SortableEvent,
|
|
31
32
|
SpokePoolTargetBalance,
|
|
32
33
|
SpokeTargetBalanceUpdate,
|
|
33
34
|
TokenConfig,
|
|
34
|
-
UBAConfigUpdates,
|
|
35
|
-
UBAParsedConfigType,
|
|
36
35
|
} from "../../interfaces";
|
|
37
36
|
import { parseJSONWithNumericString } from "../../utils/JSONUtils";
|
|
38
37
|
import { BaseAbstractClient, isUpdateFailureReason, UpdateFailureReason } from "../BaseAbstractClient";
|
|
38
|
+
import { parseAndReturnRateModelFromString } from "../../lpFeeCalculator/rateModel";
|
|
39
|
+
import { RateModel } from "../../lpFeeCalculator";
|
|
39
40
|
|
|
40
41
|
type ConfigStoreUpdateSuccess = {
|
|
41
42
|
success: true;
|
|
@@ -63,9 +64,26 @@ export enum GLOBAL_CONFIG_STORE_KEYS {
|
|
|
63
64
|
LITE_CHAIN_ID_INDICES = "LITE_CHAIN_ID_INDICES",
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
// Conveniently store known invalid token config update hashes to avoid spamming debug logs.
|
|
68
|
+
const KNOWN_INVALID_TOKEN_CONFIG_UPDATE_HASHES = [
|
|
69
|
+
"0x422abc617c6598e4b91859f99c392939d2034c1a839a342a963a34a2f0390195",
|
|
70
|
+
"0x36c85e388279714b2c98d46e3377dc37a1575665b2cac5e52fe97d8d77efcd2b",
|
|
71
|
+
"0x6f0a93119e538dd84e02adfce821fb4e6dd9baddcceb041977e8ba3c39185ab8",
|
|
72
|
+
"0xc28d8bb445e0b747201e6f98ee62aa03009f4c04b8d6f9fad8f214ec1166463d",
|
|
73
|
+
"0x3b0719ef1e3cae2dc1a854a1012332a288e50ad24adc52861d42bcc30fd3deaf",
|
|
74
|
+
"0xbae5c792f74d9f0b6554acf793df0d6b3610868bd6f6a377371b9dec10038003",
|
|
75
|
+
"0xd983142980ac2451e913b152413e769f7a7007fe7305c2e8a03db432e892f84c",
|
|
76
|
+
"0xf64610347950488503428fd720132f8188aa26dcc48e3fc9a89b7bc24aa7fda2",
|
|
77
|
+
"0x1970fcd1e5d5d6cf3bbb640d30d5e471ce5161d65580cedb388526a32b2f7638",
|
|
78
|
+
"0xf098c547d726be8fda419faaee1850280ded1ea75a1b10f4a1614805fa4207d3",
|
|
79
|
+
"0xbfa181663761a78c66dd2c7012604eb910c4c39bad17089e2cc4a011ccc0e981",
|
|
80
|
+
"0x89830f5e81b9e8b44ac2f8966b2fa4bf8e71d7f546e2bc0e773d8ee8df4bdb36",
|
|
81
|
+
"0xb0ad6270124c925a234d9c4f87b60396f2b52fdc250cd2fc9cac792d0d62e467",
|
|
82
|
+
"0x779bc3bf2dba1128d5dda6be8ae99b503cae23343a7265a86bca3d5572ed4268",
|
|
83
|
+
].map((hash) => hash.toLowerCase());
|
|
84
|
+
|
|
66
85
|
export class AcrossConfigStoreClient extends BaseAbstractClient {
|
|
67
|
-
public cumulativeRateModelUpdates:
|
|
68
|
-
public ubaConfigUpdates: UBAConfigUpdates[] = [];
|
|
86
|
+
public cumulativeRateModelUpdates: RateModelUpdate[] = [];
|
|
69
87
|
public cumulativeRouteRateModelUpdates: RouteRateModelUpdate[] = [];
|
|
70
88
|
public cumulativeMaxRefundCountUpdates: GlobalConfigUpdate[] = [];
|
|
71
89
|
public cumulativeMaxL1TokenCountUpdates: GlobalConfigUpdate[] = [];
|
|
@@ -75,8 +93,6 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
|
|
|
75
93
|
public cumulativeConfigStoreVersionUpdates: ConfigStoreVersionUpdate[] = [];
|
|
76
94
|
public cumulativeDisabledChainUpdates: DisabledChainsUpdate[] = [];
|
|
77
95
|
|
|
78
|
-
protected rateModelDictionary: across.rateModel.RateModelDictionary;
|
|
79
|
-
|
|
80
96
|
public hasLatestConfigStoreVersion = false;
|
|
81
97
|
public chainId: number | undefined;
|
|
82
98
|
|
|
@@ -89,37 +105,43 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
|
|
|
89
105
|
super(eventSearchConfig);
|
|
90
106
|
this.firstBlockToSearch = eventSearchConfig.fromBlock;
|
|
91
107
|
this.latestBlockSearched = 0;
|
|
92
|
-
this.rateModelDictionary = new across.rateModel.RateModelDictionary();
|
|
93
108
|
}
|
|
94
109
|
|
|
95
|
-
// <-- START LEGACY CONFIGURATION OBJECTS -->
|
|
96
|
-
// @dev The following configuration objects are pre-UBA fee model configurations and are deprecated as of version
|
|
97
|
-
// 2 of the ConfigStore. They are kept here for backwards compatibility.
|
|
98
|
-
|
|
99
110
|
getRateModelForBlockNumber(
|
|
100
111
|
l1Token: string,
|
|
101
112
|
originChainId: number | string,
|
|
102
113
|
destinationChainId: number | string,
|
|
103
114
|
blockNumber: number | undefined = undefined
|
|
104
|
-
):
|
|
115
|
+
): RateModel {
|
|
105
116
|
// Use route-rate model if available, otherwise use default rate model for l1Token.
|
|
106
117
|
const route = `${originChainId}-${destinationChainId}`;
|
|
107
118
|
const routeRateModel = this.getRouteRateModelForBlockNumber(l1Token, route, blockNumber);
|
|
108
|
-
|
|
119
|
+
if (routeRateModel) {
|
|
120
|
+
return routeRateModel;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const defaultRateModelUpdate = sortEventsDescending(this.cumulativeRateModelUpdates).find(
|
|
124
|
+
(config) =>
|
|
125
|
+
config.blockNumber <= (blockNumber ?? 0) && config.l1Token === l1Token && config.rateModel !== undefined
|
|
126
|
+
);
|
|
127
|
+
if (!defaultRateModelUpdate) {
|
|
128
|
+
throw new Error(`Could not find TokenConfig update for ${l1Token} at block ${blockNumber}`);
|
|
129
|
+
}
|
|
130
|
+
return parseAndReturnRateModelFromString(defaultRateModelUpdate.rateModel);
|
|
109
131
|
}
|
|
110
132
|
|
|
111
133
|
getRouteRateModelForBlockNumber(
|
|
112
134
|
l1Token: string,
|
|
113
135
|
route: string,
|
|
114
136
|
blockNumber: number | undefined = undefined
|
|
115
|
-
):
|
|
137
|
+
): RateModel | undefined {
|
|
116
138
|
const config = (sortEventsDescending(this.cumulativeRouteRateModelUpdates) as RouteRateModelUpdate[]).find(
|
|
117
139
|
(config) => config.blockNumber <= (blockNumber ?? 0) && config.l1Token === l1Token
|
|
118
140
|
);
|
|
119
141
|
if (config?.routeRateModel[route] === undefined) {
|
|
120
142
|
return undefined;
|
|
121
143
|
}
|
|
122
|
-
return
|
|
144
|
+
return parseAndReturnRateModelFromString(config.routeRateModel[route]);
|
|
123
145
|
}
|
|
124
146
|
|
|
125
147
|
/**
|
|
@@ -357,72 +379,37 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
|
|
|
357
379
|
|
|
358
380
|
// Save new TokenConfig updates.
|
|
359
381
|
for (const event of updatedTokenConfigEvents) {
|
|
382
|
+
// If transaction hash is known to be invalid, skip it immediately to avoid creating extra logs.
|
|
383
|
+
if (KNOWN_INVALID_TOKEN_CONFIG_UPDATE_HASHES.includes(event.transactionHash.toLowerCase())) {
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
|
|
360
387
|
const args = {
|
|
361
388
|
...(spreadEventWithBlockNumber(event) as TokenConfig),
|
|
362
389
|
};
|
|
363
390
|
|
|
364
391
|
try {
|
|
365
|
-
const
|
|
366
|
-
const l1Token = args
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (
|
|
377
|
-
passedArgs.transactionHash.toLowerCase() ===
|
|
378
|
-
"0x422abc617c6598e4b91859f99c392939d2034c1a839a342a963a34a2f0390195".toLowerCase()
|
|
379
|
-
) {
|
|
380
|
-
throw new Error("Known bad config update found");
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Drop value and key before passing args.
|
|
384
|
-
if (parsedValue?.rateModel !== undefined) {
|
|
385
|
-
const rateModelForToken = JSON.stringify(parsedValue.rateModel);
|
|
386
|
-
this.cumulativeRateModelUpdates.push({ ...passedArgs, rateModel: rateModelForToken, l1Token });
|
|
387
|
-
|
|
388
|
-
// Store spokeTargetBalances
|
|
389
|
-
if (parsedValue?.spokeTargetBalances) {
|
|
390
|
-
// Note: cast is required because fromEntries always produces string keys, despite the function returning a
|
|
391
|
-
// numerical key.
|
|
392
|
-
const targetBalances = Object.fromEntries(
|
|
393
|
-
Object.entries(parsedValue.spokeTargetBalances).map(([chainId, targetBalance]) => {
|
|
394
|
-
const target = max(toBN(targetBalance.target), toBN(0));
|
|
395
|
-
const threshold = max(toBN(targetBalance.threshold), toBN(0));
|
|
396
|
-
return [chainId, { target, threshold }];
|
|
397
|
-
})
|
|
398
|
-
) as SpokeTargetBalanceUpdate["spokeTargetBalances"];
|
|
399
|
-
this.cumulativeSpokeTargetBalanceUpdates.push({
|
|
400
|
-
...passedArgs,
|
|
401
|
-
spokeTargetBalances: targetBalances,
|
|
402
|
-
l1Token,
|
|
403
|
-
});
|
|
404
|
-
} else {
|
|
405
|
-
this.cumulativeSpokeTargetBalanceUpdates.push({ ...passedArgs, spokeTargetBalances: {}, l1Token });
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// Store route-specific rate models
|
|
409
|
-
if (parsedValue?.routeRateModel) {
|
|
410
|
-
const routeRateModel = Object.fromEntries(
|
|
411
|
-
Object.entries(parsedValue.routeRateModel).map(([path, routeRateModel]) => {
|
|
412
|
-
return [path, JSON.stringify(routeRateModel)];
|
|
413
|
-
})
|
|
414
|
-
);
|
|
415
|
-
this.cumulativeRouteRateModelUpdates.push({ ...passedArgs, routeRateModel, l1Token });
|
|
416
|
-
} else {
|
|
417
|
-
this.cumulativeRouteRateModelUpdates.push({ ...passedArgs, routeRateModel: {}, l1Token });
|
|
418
|
-
}
|
|
392
|
+
const { rateModel, routeRateModel, spokeTargetBalances } = this.validateTokenConfigUpdate(args);
|
|
393
|
+
const { value, key: l1Token, ...eventData } = args;
|
|
394
|
+
|
|
395
|
+
if (rateModel !== undefined) {
|
|
396
|
+
this.cumulativeRateModelUpdates.push({ ...eventData, rateModel, l1Token });
|
|
397
|
+
this.cumulativeSpokeTargetBalanceUpdates.push({
|
|
398
|
+
...eventData,
|
|
399
|
+
spokeTargetBalances,
|
|
400
|
+
l1Token,
|
|
401
|
+
});
|
|
402
|
+
this.cumulativeRouteRateModelUpdates.push({ ...eventData, routeRateModel, l1Token });
|
|
419
403
|
}
|
|
420
404
|
} catch (err) {
|
|
421
405
|
// @dev averageBlockTimeSeconds does not actually block.
|
|
422
406
|
const maxWarnAge = (24 * 60 * 60) / (await utils.averageBlockTimeSeconds());
|
|
423
407
|
if (result.searchEndBlock - event.blockNumber < maxWarnAge) {
|
|
424
408
|
const errMsg = isError(err) ? err.message : "unknown error";
|
|
425
|
-
|
|
409
|
+
// This will emit warning logs for any invalid historical updates and it will be very noisy, so
|
|
410
|
+
// developer should move over known invalid hashes to KNOWN_INVALID_TOKEN_CONFIG_UPDATE_HASHES to
|
|
411
|
+
// suppress these warnings.
|
|
412
|
+
this.logger.warn({
|
|
426
413
|
at: "ConfigStore::update",
|
|
427
414
|
message: `Caught error during ConfigStore update: ${errMsg}`,
|
|
428
415
|
update: args,
|
|
@@ -431,12 +418,12 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
|
|
|
431
418
|
this.logger.debug({
|
|
432
419
|
at: "ConfigStoreClient::update",
|
|
433
420
|
message: `Skipping invalid historical update at block ${event.blockNumber}`,
|
|
421
|
+
transactionHash: event.transactionHash,
|
|
434
422
|
});
|
|
435
423
|
}
|
|
436
424
|
continue;
|
|
437
425
|
}
|
|
438
426
|
}
|
|
439
|
-
sortEventsAscendingInPlace(this.ubaConfigUpdates);
|
|
440
427
|
|
|
441
428
|
// Save new Global config updates.
|
|
442
429
|
for (let i = 0; i < updatedGlobalConfigEvents.length; i++) {
|
|
@@ -560,8 +547,6 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
|
|
|
560
547
|
}
|
|
561
548
|
}
|
|
562
549
|
|
|
563
|
-
this.rateModelDictionary.updateWithEvents(this.cumulativeRateModelUpdates);
|
|
564
|
-
|
|
565
550
|
this.hasLatestConfigStoreVersion = this.hasValidConfigStoreVersionForTimestamp();
|
|
566
551
|
this.latestBlockSearched = result.searchEndBlock;
|
|
567
552
|
this.firstBlockToSearch = result.searchEndBlock + 1; // Next iteration should start off from where this one ended.
|
|
@@ -572,30 +557,75 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
|
|
|
572
557
|
this.logger.debug({ at: "ConfigStore", message: "ConfigStore client updated!" });
|
|
573
558
|
}
|
|
574
559
|
|
|
560
|
+
validateTokenConfigUpdate(args: TokenConfig): {
|
|
561
|
+
spokeTargetBalances: SpokeTargetBalanceUpdate["spokeTargetBalances"];
|
|
562
|
+
rateModel: string | undefined;
|
|
563
|
+
routeRateModel: RouteRateModelUpdate["routeRateModel"];
|
|
564
|
+
} {
|
|
565
|
+
const { value, key, transactionHash } = args;
|
|
566
|
+
const parsedValue = parseJSONWithNumericString(value) as ParsedTokenConfig;
|
|
567
|
+
const l1Token = key;
|
|
568
|
+
|
|
569
|
+
// Return the following parameters if the TokenConfig update is valid, otherwise throw an error.
|
|
570
|
+
// Remove any config updates with invalid rate models by throwing an error if any part of the TokenConfig
|
|
571
|
+
// is wrong before we push any events into this client's state.
|
|
572
|
+
let rateModelForToken: string | undefined = undefined;
|
|
573
|
+
let spokeTargetBalances: SpokeTargetBalanceUpdate["spokeTargetBalances"] = {};
|
|
574
|
+
let routeRateModel: RouteRateModelUpdate["routeRateModel"] = {};
|
|
575
|
+
|
|
576
|
+
// Drop value and key before passing args.
|
|
577
|
+
if (parsedValue?.rateModel !== undefined) {
|
|
578
|
+
const rateModel = parsedValue.rateModel;
|
|
579
|
+
assert(
|
|
580
|
+
this.isValidRateModel(rateModel),
|
|
581
|
+
`Invalid rateModel UBar for ${l1Token} at transaction ${transactionHash}, ${JSON.stringify(rateModel)}`
|
|
582
|
+
);
|
|
583
|
+
rateModelForToken = JSON.stringify(rateModel);
|
|
584
|
+
|
|
585
|
+
// Store spokeTargetBalances
|
|
586
|
+
if (parsedValue?.spokeTargetBalances) {
|
|
587
|
+
// Note: cast is required because fromEntries always produces string keys, despite the function returning a
|
|
588
|
+
// numerical key.
|
|
589
|
+
spokeTargetBalances = Object.fromEntries(
|
|
590
|
+
Object.entries(parsedValue.spokeTargetBalances).map(([chainId, targetBalance]) => {
|
|
591
|
+
const target = max(toBN(targetBalance.target), toBN(0));
|
|
592
|
+
const threshold = max(toBN(targetBalance.threshold), toBN(0));
|
|
593
|
+
return [chainId, { target, threshold }];
|
|
594
|
+
})
|
|
595
|
+
) as SpokeTargetBalanceUpdate["spokeTargetBalances"];
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// Store route-specific rate models
|
|
599
|
+
if (parsedValue?.routeRateModel) {
|
|
600
|
+
routeRateModel = Object.fromEntries(
|
|
601
|
+
Object.entries(parsedValue.routeRateModel).map(([path, routeRateModel]) => {
|
|
602
|
+
assert(
|
|
603
|
+
this.isValidRateModel(routeRateModel) &&
|
|
604
|
+
`Invalid routeRateModel UBar for ${path} for ${l1Token} at transaction ${transactionHash}, ${JSON.stringify(
|
|
605
|
+
routeRateModel
|
|
606
|
+
)}`
|
|
607
|
+
);
|
|
608
|
+
return [path, JSON.stringify(routeRateModel)];
|
|
609
|
+
})
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
return {
|
|
615
|
+
spokeTargetBalances,
|
|
616
|
+
rateModel: rateModelForToken,
|
|
617
|
+
routeRateModel,
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
isValidRateModel(rateModel: RateModel): boolean {
|
|
622
|
+
// UBar should be between 0% and 100%.
|
|
623
|
+
return toBN(rateModel.UBar).gt(0) && toBN(rateModel.UBar).lt(toWei("1"));
|
|
624
|
+
}
|
|
625
|
+
|
|
575
626
|
filterDisabledChains(disabledChains: number[]): number[] {
|
|
576
627
|
// If any chain ID's are not integers then ignore. UMIP-157 requires that this key cannot include
|
|
577
628
|
// the chain ID 1.
|
|
578
629
|
return disabledChains.filter((chainId: number) => !isNaN(chainId) && Number.isInteger(chainId) && chainId !== 1);
|
|
579
630
|
}
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* Retrieves the most recently set UBA config for a given L1 token address before a block number.
|
|
583
|
-
* @param l1TokenAddress The L1 token address to retrieve the config for
|
|
584
|
-
* @param blockNumber The block number to retrieve the config for. If not specified, sets block to max integer
|
|
585
|
-
* meaning that this function will return the latest config.
|
|
586
|
-
* @returns The UBA config for the given L1 token address and block number, or undefined if no config exists
|
|
587
|
-
* before blockNumber.
|
|
588
|
-
*/
|
|
589
|
-
public getUBAConfig(l1TokenAddress: string, blockNumber = Number.MAX_SAFE_INTEGER): UBAParsedConfigType | undefined {
|
|
590
|
-
// We only care about searching on the block number and not any events that occurred in the same block
|
|
591
|
-
// but with a lower transaction index. In other words, if the UBA config was updated as the absolute
|
|
592
|
-
// last transaction in a block, the update still applies to all preceding UBA events in the same block.
|
|
593
|
-
// This is a simplifying assumption that we can make because the ConfigStore admin role is whitelisted and assumed
|
|
594
|
-
// to be acting in the best interest of the protocol.
|
|
595
|
-
const config = findLast(
|
|
596
|
-
this.ubaConfigUpdates,
|
|
597
|
-
(config) => config.l1Token === l1TokenAddress && config.blockNumber <= blockNumber
|
|
598
|
-
);
|
|
599
|
-
return config?.config;
|
|
600
|
-
}
|
|
601
631
|
}
|
|
@@ -14,21 +14,21 @@ const L1TokenConfigSs = object({
|
|
|
14
14
|
rateModel: RateModelSs,
|
|
15
15
|
routeRateModel: optional(record(string(), RateModelSs)),
|
|
16
16
|
});
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
type RateModelSS = Infer<typeof RateModelSs>;
|
|
18
|
+
type L1TokenConfigSS = Infer<typeof L1TokenConfigSs>;
|
|
19
19
|
|
|
20
20
|
export class Client {
|
|
21
21
|
public readonly contract: AcrossConfigStore;
|
|
22
22
|
constructor(address: string, provider: Provider) {
|
|
23
23
|
this.contract = AcrossConfigStore__factory.connect(address, provider);
|
|
24
24
|
}
|
|
25
|
-
static parseL1TokenConfig(data: string):
|
|
25
|
+
static parseL1TokenConfig(data: string): L1TokenConfigSS {
|
|
26
26
|
const l1TokenConfig = JSON.parse(data);
|
|
27
27
|
const l1TokenConfigMask = filterFalsyKeys(mask(l1TokenConfig, L1TokenConfigSs));
|
|
28
28
|
assert(l1TokenConfigMask, L1TokenConfigSs);
|
|
29
29
|
return l1TokenConfigMask;
|
|
30
30
|
}
|
|
31
|
-
async getL1TokenConfig(l1TokenAddress: string, overrides: CallOverrides = {}): Promise<
|
|
31
|
+
async getL1TokenConfig(l1TokenAddress: string, overrides: CallOverrides = {}): Promise<L1TokenConfigSS> {
|
|
32
32
|
const data = await this.contract.l1TokenConfig(l1TokenAddress, overrides);
|
|
33
33
|
return Client.parseL1TokenConfig(data);
|
|
34
34
|
}
|
|
@@ -37,7 +37,7 @@ export class Client {
|
|
|
37
37
|
overrides: CallOverrides = {},
|
|
38
38
|
originChainId?: number,
|
|
39
39
|
destinationChainId?: number
|
|
40
|
-
): Promise<
|
|
40
|
+
): Promise<RateModelSS> {
|
|
41
41
|
const l1TokenConfig = await this.getL1TokenConfig(l1TokenAddress, overrides);
|
|
42
42
|
if (originChainId === undefined || destinationChainId === undefined) return l1TokenConfig.rateModel;
|
|
43
43
|
const routeRateModelKey = `${originChainId}-${destinationChainId}`;
|