@gearbox-protocol/sdk 17.10.1 → 17.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/dist/cjs/offchain/AbstractOffchainNamespace.js +31 -8
- package/dist/cjs/permissionless/api/GearboxPermissionless.js +79 -0
- package/dist/cjs/permissionless/api/chains/ChainsNamespace.js +180 -0
- package/dist/cjs/permissionless/api/chains/index.js +4 -0
- package/dist/cjs/permissionless/api/chains/schemas.js +34 -0
- package/dist/cjs/permissionless/api/chains/types.js +1 -0
- package/dist/cjs/permissionless/api/deploy/PermissionlessDeploy.js +152 -0
- package/dist/cjs/permissionless/api/deploy/effective-staleness.js +46 -0
- package/dist/cjs/permissionless/api/deploy/index.js +8 -0
- package/dist/cjs/permissionless/api/deploy/types.js +1 -0
- package/dist/cjs/permissionless/api/errors.js +82 -0
- package/dist/cjs/permissionless/api/index.js +28 -0
- package/dist/cjs/permissionless/api/oracles/PermissionlessOracles.js +84 -0
- package/dist/cjs/permissionless/api/oracles/index.js +6 -0
- package/dist/cjs/permissionless/api/oracles/schemas.js +64 -0
- package/dist/cjs/permissionless/api/oracles/types.js +1 -0
- package/dist/cjs/permissionless/api/schemas.js +28 -0
- package/dist/cjs/permissionless/api/transactions/InstanceOwnerTransactions.js +230 -0
- package/dist/cjs/permissionless/api/transactions/index.js +4 -0
- package/dist/cjs/permissionless/api/transactions/lp-price-feeds.js +86 -0
- package/dist/cjs/permissionless/api/transactions/types.js +1 -0
- package/dist/cjs/permissionless/api/types.js +1 -0
- package/dist/cjs/permissionless/bindings/cross-chain-multisig.js +1 -1
- package/dist/cjs/permissionless/bindings/index.js +3 -3
- package/dist/cjs/permissionless/bindings/instance-manager.js +3 -3
- package/dist/cjs/permissionless/index.js +31 -8
- package/dist/cjs/permissionless/utils/governance/timelock-txs.js +1 -1
- package/dist/cjs/permissionless/utils/index.js +4 -4
- package/dist/cjs/permissionless/utils/price-update/get-price-update-tx.js +1 -1
- package/dist/cjs/permissionless/utils/price-update/index.js +1 -1
- package/dist/esm/dev/AccountOpener.js +1 -1
- package/dist/esm/dev/withdrawalUtils.js +1 -1
- package/dist/esm/history/trace/extractTransfers.js +1 -1
- package/dist/esm/offchain/AbstractOffchainNamespace.js +31 -8
- package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +2 -2
- package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +1 -1
- package/dist/esm/onchain/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
- package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
- package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
- package/dist/esm/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
- package/dist/esm/onchain/base/TokensMeta.js +3 -3
- package/dist/esm/onchain/core/createAddressProvider.js +1 -1
- package/dist/esm/onchain/market/adapters/contracts/AccountMigratorAdapterContract.js +1 -1
- package/dist/esm/onchain/market/adapters/contracts/ERC4626AdapterContract.js +1 -1
- package/dist/esm/onchain/market/credit/CreditFacadeV310BaseContract.js +1 -1
- package/dist/esm/onchain/market/pool/PoolV310Contract.js +1 -1
- package/dist/esm/onchain/market/rwa/createDegenNFT.js +1 -1
- package/dist/esm/onchain/market/zapper/IETHZapperContract.js +1 -1
- package/dist/esm/onchain/market/zapper/ZapperContract.js +1 -1
- package/dist/esm/onchain/preview/preview/previewPoolPositionOperation.js +2 -2
- package/dist/esm/onchain/utils/viem/simulateWithPriceUpdates.js +1 -1
- package/dist/esm/permissionless/api/GearboxPermissionless.js +78 -0
- package/dist/esm/permissionless/api/chains/ChainsNamespace.js +179 -0
- package/dist/esm/permissionless/api/chains/index.js +3 -0
- package/dist/esm/permissionless/api/chains/schemas.js +30 -0
- package/dist/esm/permissionless/api/chains/types.js +1 -0
- package/dist/esm/permissionless/api/deploy/PermissionlessDeploy.js +149 -0
- package/dist/esm/permissionless/api/deploy/effective-staleness.js +46 -0
- package/dist/esm/permissionless/api/deploy/index.js +4 -0
- package/dist/esm/permissionless/api/deploy/types.js +1 -0
- package/dist/esm/permissionless/api/errors.js +77 -0
- package/dist/esm/permissionless/api/index.js +13 -0
- package/dist/esm/permissionless/api/oracles/PermissionlessOracles.js +81 -0
- package/dist/esm/permissionless/api/oracles/index.js +3 -0
- package/dist/esm/permissionless/api/oracles/schemas.js +59 -0
- package/dist/esm/permissionless/api/oracles/types.js +1 -0
- package/dist/esm/permissionless/api/schemas.js +25 -0
- package/dist/esm/permissionless/api/transactions/InstanceOwnerTransactions.js +229 -0
- package/dist/esm/permissionless/api/transactions/index.js +3 -0
- package/dist/esm/permissionless/api/transactions/lp-price-feeds.js +84 -0
- package/dist/esm/permissionless/api/transactions/types.js +1 -0
- package/dist/esm/permissionless/api/types.js +1 -0
- package/dist/esm/permissionless/bindings/cross-chain-multisig.js +1 -1
- package/dist/esm/permissionless/bindings/index.js +3 -3
- package/dist/esm/permissionless/bindings/instance-manager.js +3 -3
- package/dist/esm/permissionless/index.js +17 -9
- package/dist/esm/permissionless/utils/governance/timelock-txs.js +1 -1
- package/dist/esm/permissionless/utils/index.js +4 -4
- package/dist/esm/permissionless/utils/price-update/get-price-update-tx.js +1 -1
- package/dist/esm/permissionless/utils/price-update/index.js +1 -1
- package/dist/types/offchain/AbstractOffchainNamespace.d.ts +12 -0
- package/dist/types/permissionless/api/GearboxPermissionless.d.ts +71 -0
- package/dist/types/permissionless/api/chains/ChainsNamespace.d.ts +99 -0
- package/dist/types/permissionless/api/chains/index.d.ts +3 -0
- package/dist/types/permissionless/api/chains/schemas.d.ts +49 -0
- package/dist/types/permissionless/api/chains/types.d.ts +58 -0
- package/dist/types/permissionless/api/deploy/PermissionlessDeploy.d.ts +69 -0
- package/dist/types/permissionless/api/deploy/effective-staleness.d.ts +19 -0
- package/dist/types/permissionless/api/deploy/index.d.ts +4 -0
- package/dist/types/permissionless/api/deploy/types.d.ts +87 -0
- package/dist/types/permissionless/api/errors.d.ts +63 -0
- package/dist/types/permissionless/api/index.d.ts +17 -0
- package/dist/types/permissionless/api/oracles/PermissionlessOracles.d.ts +64 -0
- package/dist/types/permissionless/api/oracles/index.d.ts +3 -0
- package/dist/types/permissionless/api/oracles/schemas.d.ts +103 -0
- package/dist/types/permissionless/api/oracles/types.d.ts +63 -0
- package/dist/types/permissionless/api/schemas.d.ts +22 -0
- package/dist/types/permissionless/api/transactions/InstanceOwnerTransactions.d.ts +60 -0
- package/dist/types/permissionless/api/transactions/index.d.ts +3 -0
- package/dist/types/permissionless/api/transactions/lp-price-feeds.d.ts +17 -0
- package/dist/types/permissionless/api/transactions/types.d.ts +36 -0
- package/dist/types/permissionless/api/types.d.ts +12 -0
- package/dist/types/permissionless/bindings/factory/credit-factory.d.ts +1 -1
- package/dist/types/permissionless/bindings/factory/loss-policy-factory.d.ts +1 -1
- package/dist/types/permissionless/bindings/factory/pool-factory.d.ts +1 -1
- package/dist/types/permissionless/bindings/factory/price-oracle-factory.d.ts +1 -1
- package/dist/types/permissionless/bindings/index.d.ts +1 -1
- package/dist/types/permissionless/core/index.d.ts +1 -1
- package/dist/types/permissionless/index.d.ts +23 -10
- package/dist/types/permissionless/utils/governance/index.d.ts +1 -1
- package/dist/types/permissionless/utils/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_offchain_AbstractOffchainNamespace = require("../../../offchain/AbstractOffchainNamespace.js");
|
|
3
|
+
const require_permissionless_utils_price_update_get_prices = require("../../utils/price-update/get-prices.js");
|
|
4
|
+
const require_permissionless_api_oracles_schemas = require("./schemas.js");
|
|
5
|
+
//#region src/permissionless/api/oracles/PermissionlessOracles.ts
|
|
6
|
+
const GET_PRICES_GAS_LIMIT_BY_CHAIN_ID = { 143: 100000000n };
|
|
7
|
+
const GET_PRICES_CHUNK_SIZE = 200;
|
|
8
|
+
/**
|
|
9
|
+
* The price feeds of one chain: the PriceFeedStore as the backend has indexed
|
|
10
|
+
* it, and the prices behind it.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const store = await permissionless.oracles.store({ chainId: 1 });
|
|
14
|
+
* const { prices } = await permissionless.oracles.prices({ chainId: 1 });
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Read-only. What the store carries is decided on chain, so putting a feed
|
|
18
|
+
* there is a batch the instance owner executes — see
|
|
19
|
+
* {@link InstanceOwnerTransactions} — not a row a client writes here.
|
|
20
|
+
**/
|
|
21
|
+
var PermissionlessOracles = class extends require_offchain_AbstractOffchainNamespace.AbstractOffchainNamespace {
|
|
22
|
+
#chains;
|
|
23
|
+
constructor(options, chains) {
|
|
24
|
+
super("PermissionlessOracles", {
|
|
25
|
+
...options,
|
|
26
|
+
chainIds: []
|
|
27
|
+
});
|
|
28
|
+
this.#chains = chains;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The store with the assets and feeds of one chain.
|
|
32
|
+
**/
|
|
33
|
+
async store({ chainId }) {
|
|
34
|
+
return this.getData({
|
|
35
|
+
path: `/pfs/${chainId}`,
|
|
36
|
+
schema: require_permissionless_api_oracles_schemas.priceFeedStoreSchema
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A price per feed, and a market cap per feed and asset. The feeds the
|
|
41
|
+
* indexer has not seen are read off the chain by the backend, so the store
|
|
42
|
+
* is priced whole.
|
|
43
|
+
**/
|
|
44
|
+
async prices({ chainId }) {
|
|
45
|
+
return this.getData({
|
|
46
|
+
path: `/pfs/${chainId}/prices`,
|
|
47
|
+
schema: require_permissionless_api_oracles_schemas.pricesSchema
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The price each of the named feeds reports, read off the chain.
|
|
52
|
+
*
|
|
53
|
+
* Where {@link prices} answers for the store as a whole and at whatever
|
|
54
|
+
* moment the backend priced it, this prices exactly the feeds asked for, at
|
|
55
|
+
* the current block. A feed the store does not carry prices the same way,
|
|
56
|
+
* which is what makes this the call to reach for after a deploy, or while a
|
|
57
|
+
* form is still choosing between candidates.
|
|
58
|
+
*
|
|
59
|
+
* Feeds needing a fresh answer before they can be read are updated inside
|
|
60
|
+
* the same simulation, so a push-based feed prices as readily as a
|
|
61
|
+
* pull-based one. `null` is a feed whose read reverted, not a zero.
|
|
62
|
+
*
|
|
63
|
+
* ```ts
|
|
64
|
+
* const prices = await permissionless.oracles.getPrices({
|
|
65
|
+
* chainId: 1,
|
|
66
|
+
* priceFeeds: [feed],
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @returns A price per feed, in the 8 decimals every Gearbox feed reports.
|
|
71
|
+
**/
|
|
72
|
+
async getPrices({ chainId, priceFeeds }) {
|
|
73
|
+
return require_permissionless_utils_price_update_get_prices.getPrices({
|
|
74
|
+
client: this.#chains.client(chainId),
|
|
75
|
+
priceFeeds,
|
|
76
|
+
chunkSize: 200,
|
|
77
|
+
gasLimit: GET_PRICES_GAS_LIMIT_BY_CHAIN_ID[chainId]
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
//#endregion
|
|
82
|
+
exports.GET_PRICES_CHUNK_SIZE = GET_PRICES_CHUNK_SIZE;
|
|
83
|
+
exports.GET_PRICES_GAS_LIMIT_BY_CHAIN_ID = GET_PRICES_GAS_LIMIT_BY_CHAIN_ID;
|
|
84
|
+
exports.PermissionlessOracles = PermissionlessOracles;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_permissionless_api_oracles_PermissionlessOracles = require("./PermissionlessOracles.js");
|
|
3
|
+
require("./types.js");
|
|
4
|
+
exports.GET_PRICES_CHUNK_SIZE = require_permissionless_api_oracles_PermissionlessOracles.GET_PRICES_CHUNK_SIZE;
|
|
5
|
+
exports.GET_PRICES_GAS_LIMIT_BY_CHAIN_ID = require_permissionless_api_oracles_PermissionlessOracles.GET_PRICES_GAS_LIMIT_BY_CHAIN_ID;
|
|
6
|
+
exports.PermissionlessOracles = require_permissionless_api_oracles_PermissionlessOracles.PermissionlessOracles;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_permissionless_api_schemas = require("../schemas.js");
|
|
3
|
+
let zod_v4 = require("zod/v4");
|
|
4
|
+
//#region src/permissionless/api/oracles/schemas.ts
|
|
5
|
+
/**
|
|
6
|
+
* Runtime schemas for {@link ./types.js}.
|
|
7
|
+
*
|
|
8
|
+
* The objects are loose: the backend reads most of these rows straight off the
|
|
9
|
+
* chain through the SDK's own bindings, which attach fields the hand-written
|
|
10
|
+
* types do not declare, and dropping them would make this client lossier than
|
|
11
|
+
* the payload it decodes.
|
|
12
|
+
**/
|
|
13
|
+
/** {@link PriceFeed}, as the backend serves it. */
|
|
14
|
+
const priceFeedSchema = zod_v4.z.looseObject({
|
|
15
|
+
address: require_permissionless_api_schemas.addressSchema,
|
|
16
|
+
contractType: zod_v4.z.string(),
|
|
17
|
+
version: zod_v4.z.number(),
|
|
18
|
+
deployedBy: require_permissionless_api_schemas.addressSchema,
|
|
19
|
+
isInStore: zod_v4.z.boolean(),
|
|
20
|
+
stalenessPeriod: zod_v4.z.number(),
|
|
21
|
+
name: zod_v4.z.string()
|
|
22
|
+
});
|
|
23
|
+
/** {@link PermissionlessPriceFeedStatus} */
|
|
24
|
+
const priceFeedStatusSchema = zod_v4.z.enum([
|
|
25
|
+
"private",
|
|
26
|
+
"inStore",
|
|
27
|
+
"pendingForbidden",
|
|
28
|
+
"forbidden"
|
|
29
|
+
]);
|
|
30
|
+
/** {@link PermissionlessAsset} */
|
|
31
|
+
const assetSchema = zod_v4.z.looseObject({
|
|
32
|
+
address: require_permissionless_api_schemas.addressSchema,
|
|
33
|
+
symbol: zod_v4.z.string(),
|
|
34
|
+
name: zod_v4.z.string(),
|
|
35
|
+
decimals: zod_v4.z.number(),
|
|
36
|
+
isInStore: zod_v4.z.boolean(),
|
|
37
|
+
owner: require_permissionless_api_schemas.addressSchema,
|
|
38
|
+
priceFeeds: zod_v4.z.array(zod_v4.z.looseObject({
|
|
39
|
+
pricefeed: priceFeedSchema,
|
|
40
|
+
status: priceFeedStatusSchema
|
|
41
|
+
}))
|
|
42
|
+
});
|
|
43
|
+
/** {@link PermissionlessPriceFeedStore} */
|
|
44
|
+
const priceFeedStoreSchema = zod_v4.z.looseObject({
|
|
45
|
+
chainId: zod_v4.z.number(),
|
|
46
|
+
name: zod_v4.z.string(),
|
|
47
|
+
isPublic: zod_v4.z.boolean(),
|
|
48
|
+
isActivated: zod_v4.z.boolean(),
|
|
49
|
+
explorerUrl: zod_v4.z.string(),
|
|
50
|
+
assets: zod_v4.z.array(assetSchema),
|
|
51
|
+
priceFeeds: zod_v4.z.array(priceFeedSchema)
|
|
52
|
+
});
|
|
53
|
+
/** {@link PermissionlessPrices} */
|
|
54
|
+
const pricesSchema = zod_v4.z.looseObject({
|
|
55
|
+
prices: require_permissionless_api_schemas.addressRecord(zod_v4.z.string().nullable()),
|
|
56
|
+
marketCaps: require_permissionless_api_schemas.addressRecord(require_permissionless_api_schemas.addressRecord(zod_v4.z.string().nullable())),
|
|
57
|
+
time: zod_v4.z.number()
|
|
58
|
+
});
|
|
59
|
+
//#endregion
|
|
60
|
+
exports.assetSchema = assetSchema;
|
|
61
|
+
exports.priceFeedSchema = priceFeedSchema;
|
|
62
|
+
exports.priceFeedStatusSchema = priceFeedStatusSchema;
|
|
63
|
+
exports.priceFeedStoreSchema = priceFeedStoreSchema;
|
|
64
|
+
exports.pricesSchema = pricesSchema;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let viem = require("viem");
|
|
3
|
+
let zod_v4 = require("zod/v4");
|
|
4
|
+
//#region src/permissionless/api/schemas.ts
|
|
5
|
+
/**
|
|
6
|
+
* Runtime schemas shared by the {@link GearboxPermissionless} namespaces.
|
|
7
|
+
*
|
|
8
|
+
* Addresses are validated but never rewritten: the backend serves them in the
|
|
9
|
+
* case its database holds, and its payloads key records by address, so
|
|
10
|
+
* checksumming here would silently break a lookup by the key it answered with.
|
|
11
|
+
* A caller that needs one form converts with viem's `getAddress`.
|
|
12
|
+
**/
|
|
13
|
+
/** An address, in whatever case the backend serves it. */
|
|
14
|
+
const addressSchema = zod_v4.z.custom((value) => typeof value === "string" && (0, viem.isAddress)(value, { strict: false }), { message: "invalid address" });
|
|
15
|
+
/** A `0x`-prefixed hex string, as viem's `Hex`. */
|
|
16
|
+
const hexSchema = zod_v4.z.custom((value) => typeof value === "string" && (0, viem.isHex)(value), { message: "invalid hex string" });
|
|
17
|
+
/**
|
|
18
|
+
* A record keyed by address. Spelled out here because zod types a record key
|
|
19
|
+
* by the schema's output, which the branded `Address` is not inferred as.
|
|
20
|
+
**/
|
|
21
|
+
function addressRecord(value) {
|
|
22
|
+
const key = zod_v4.z.string().refine((v) => (0, viem.isAddress)(v, { strict: false }), { message: "invalid address" });
|
|
23
|
+
return zod_v4.z.record(key, value);
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
exports.addressRecord = addressRecord;
|
|
27
|
+
exports.addressSchema = addressSchema;
|
|
28
|
+
exports.hexSchema = hexSchema;
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_onchain_utils_createRawTx = require("../../../onchain/utils/createRawTx.js");
|
|
3
|
+
const require_onchain_chain_chains = require("../../../onchain/chain/chains.js");
|
|
4
|
+
const require_onchain_constants_address_provider = require("../../../onchain/constants/address-provider.js");
|
|
5
|
+
const require_onchain_constants_versions = require("../../../onchain/constants/versions.js");
|
|
6
|
+
const require_onchain_base_ChainContractsRegister = require("../../../onchain/base/ChainContractsRegister.js");
|
|
7
|
+
const require_onchain_OnchainSDK = require("../../../onchain/OnchainSDK.js");
|
|
8
|
+
require("../../../onchain/index.js");
|
|
9
|
+
const require_permissionless_api_errors = require("../errors.js");
|
|
10
|
+
const require_permissionless_utils_literals = require("../../utils/literals.js");
|
|
11
|
+
const require_permissionless_bindings_price_feed_store = require("../../bindings/price-feed-store.js");
|
|
12
|
+
require("../../deployment/addresses.js");
|
|
13
|
+
const require_permissionless_bindings_address_provider = require("../../bindings/address-provider.js");
|
|
14
|
+
const require_permissionless_bindings_instance_manager = require("../../bindings/instance-manager.js");
|
|
15
|
+
const require_permissionless_utils_governance_batch = require("../../utils/governance/batch.js");
|
|
16
|
+
const require_permissionless_utils_price_update_get_updatable_feeds = require("../../utils/price-update/get-updatable-feeds.js");
|
|
17
|
+
const require_permissionless_api_transactions_lp_price_feeds = require("./lp-price-feeds.js");
|
|
18
|
+
//#region src/permissionless/api/transactions/InstanceOwnerTransactions.ts
|
|
19
|
+
const lower = (value) => value.toLowerCase();
|
|
20
|
+
/**
|
|
21
|
+
* The Safe batches an instance owner executes to apply what a curator
|
|
22
|
+
* prepared: adding their private feeds to the PriceFeedStore, renaming feeds,
|
|
23
|
+
* changing staleness periods, forbidding feeds and refreshing LP bounds.
|
|
24
|
+
*
|
|
25
|
+
* Every batch is wrapped with `wrapConfigureLocal`, so the InstanceManager is
|
|
26
|
+
* the only caller the PriceFeedStore ever sees.
|
|
27
|
+
*
|
|
28
|
+
* Backend-free: a batch is built off the chain it will be executed on, and
|
|
29
|
+
* the store it reads is the one {@link PermissionlessOracles} already
|
|
30
|
+
* fetched. Nothing is sent either — a curator never executes these
|
|
31
|
+
* themselves. They prepare a batch and hand it to the instance owner, who
|
|
32
|
+
* reviews and executes it from their Safe.
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* const txs = await permissionless.transactions.addFeeds({
|
|
36
|
+
* chainId: 1,
|
|
37
|
+
* owner: curator,
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
**/
|
|
41
|
+
var InstanceOwnerTransactions = class {
|
|
42
|
+
#chains;
|
|
43
|
+
#oracles;
|
|
44
|
+
constructor(chains, oracles) {
|
|
45
|
+
this.#chains = chains;
|
|
46
|
+
this.#oracles = oracles;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The batch that adds the owner's private feeds to the store and allows
|
|
50
|
+
* them on the assets they were connected to. Only feeds that actually carry
|
|
51
|
+
* a connection are added: a feed nobody priced would land in the store
|
|
52
|
+
* doing nothing.
|
|
53
|
+
**/
|
|
54
|
+
async addFeeds({ chainId, owner }) {
|
|
55
|
+
const [batch, store] = await Promise.all([this.#batchContext(chainId), this.#oracles.store({ chainId })]);
|
|
56
|
+
const pairs = store.assets.flatMap((asset) => asset.priceFeeds.filter((entry) => entry.status === "private").map((entry) => ({
|
|
57
|
+
asset: asset.address,
|
|
58
|
+
priceFeed: entry.pricefeed.address
|
|
59
|
+
})));
|
|
60
|
+
const connected = new Set(pairs.map((pair) => lower(pair.priceFeed)));
|
|
61
|
+
const feedsToAdd = store.priceFeeds.filter((feed) => !feed.isInStore && connected.has(lower(feed.address)));
|
|
62
|
+
const txs = [...feedsToAdd.map((feed) => batch.store.addPriceFeedTx(feed.address, feed.stalenessPeriod, feed.name)), ...pairs.map((pair) => batch.store.allowPriceFeedTx(pair.asset, pair.priceFeed))];
|
|
63
|
+
return this.#envelope({
|
|
64
|
+
batch,
|
|
65
|
+
author: owner,
|
|
66
|
+
name: "pfs-updates",
|
|
67
|
+
txs,
|
|
68
|
+
touchedFeeds: feedsToAdd.map((feed) => feed.address)
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The batch that renames feeds already in the store. A name is part of what
|
|
73
|
+
* the store holds, so changing one is a remove and a fresh add, followed by
|
|
74
|
+
* allowing the feed again on every asset that priced it.
|
|
75
|
+
**/
|
|
76
|
+
async changeNames({ chainId, owner, names }) {
|
|
77
|
+
const [batch, store] = await Promise.all([this.#batchContext(chainId), this.#oracles.store({ chainId })]);
|
|
78
|
+
const feedToAssets = await this.#feedToAssets(batch.store);
|
|
79
|
+
const inStore = new Map(store.priceFeeds.filter((feed) => feed.isInStore).map((feed) => [lower(feed.address), feed]));
|
|
80
|
+
const txs = [];
|
|
81
|
+
for (const [address, name] of Object.entries(names)) {
|
|
82
|
+
const feed = inStore.get(lower(address));
|
|
83
|
+
if (!feed) throw new require_permissionless_api_errors.PriceFeedNotInStoreError(address, chainId);
|
|
84
|
+
txs.push(batch.store.removePriceFeedTx(feed.address), batch.store.addPriceFeedTx(feed.address, feed.stalenessPeriod, name));
|
|
85
|
+
for (const asset of feedToAssets.get(lower(address)) ?? []) txs.push(batch.store.allowPriceFeedTx(asset, feed.address));
|
|
86
|
+
}
|
|
87
|
+
return this.#envelope({
|
|
88
|
+
batch,
|
|
89
|
+
author: owner,
|
|
90
|
+
name: "pricefeed-name-changes",
|
|
91
|
+
txs,
|
|
92
|
+
touchedFeeds: Object.keys(names)
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The batch that changes how long each feed's price stays valid.
|
|
97
|
+
**/
|
|
98
|
+
async changeStalenessPeriods({ chainId, owner, periods }) {
|
|
99
|
+
const batch = await this.#batchContext(chainId);
|
|
100
|
+
const entries = Object.entries(periods);
|
|
101
|
+
const txs = entries.map(([address, period]) => batch.store.setStalenessPeriodTx(address, period));
|
|
102
|
+
return this.#envelope({
|
|
103
|
+
batch,
|
|
104
|
+
author: owner,
|
|
105
|
+
name: "pricefeed-staleness-changes",
|
|
106
|
+
txs,
|
|
107
|
+
touchedFeeds: entries.map(([address]) => address)
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The batch that forbids feeds on the assets they were allowed for.
|
|
112
|
+
**/
|
|
113
|
+
async forbidFeeds({ chainId, owner, tokens }) {
|
|
114
|
+
const batch = await this.#batchContext(chainId);
|
|
115
|
+
const txs = Object.entries(tokens).flatMap(([token, feeds]) => feeds.map((feed) => require_onchain_utils_createRawTx.createRawTx(batch.store.address, {
|
|
116
|
+
abi: batch.store.abi,
|
|
117
|
+
functionName: "forbidPriceFeed",
|
|
118
|
+
args: [token, feed]
|
|
119
|
+
})));
|
|
120
|
+
return this.#envelope({
|
|
121
|
+
batch,
|
|
122
|
+
author: owner,
|
|
123
|
+
name: "forbid-feeds",
|
|
124
|
+
txs,
|
|
125
|
+
touchedFeeds: []
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The batch that pulls every drifted LP feed's lower bound back under its
|
|
130
|
+
* exchange rate. Unlike the others this takes no input: the whole store is
|
|
131
|
+
* scanned and only the feeds that drifted produce a transaction, so this
|
|
132
|
+
* one is slow.
|
|
133
|
+
**/
|
|
134
|
+
async updateBounds({ chainId, owner }) {
|
|
135
|
+
const batch = await this.#batchContext(chainId);
|
|
136
|
+
const pfCompressor = await this.#priceFeedCompressor(batch.client);
|
|
137
|
+
const known = await batch.store.getKnownPriceFeeds();
|
|
138
|
+
const feeds = await require_permissionless_api_transactions_lp_price_feeds.getFeedsToUpdate(batch.client, pfCompressor, known);
|
|
139
|
+
const configureTxs = [];
|
|
140
|
+
for (const feed of feeds) configureTxs.push(...await require_permissionless_api_transactions_lp_price_feeds.updateBounds(batch.client, feed));
|
|
141
|
+
const txs = [batch.store.configurePriceFeeds(configureTxs.map((tx) => ({
|
|
142
|
+
target: tx.to,
|
|
143
|
+
callData: tx.callData
|
|
144
|
+
})))];
|
|
145
|
+
return this.#envelope({
|
|
146
|
+
batch,
|
|
147
|
+
author: owner,
|
|
148
|
+
name: "update-bounds",
|
|
149
|
+
txs,
|
|
150
|
+
touchedFeeds: []
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The contracts every batch of one chain is built against.
|
|
155
|
+
*
|
|
156
|
+
* Nothing here checks that the instance is activated: that is a backend
|
|
157
|
+
* read, and an instance without a deployed InstanceManager fails on the
|
|
158
|
+
* owner lookup below anyway.
|
|
159
|
+
**/
|
|
160
|
+
async #batchContext(chainId) {
|
|
161
|
+
const client = this.#chains.client(chainId);
|
|
162
|
+
const addressProvider = new require_permissionless_bindings_address_provider.AddressProviderContract("0xF7f0a609BfAb9a0A98786951ef10e5FE26cC1E38", client);
|
|
163
|
+
const instanceManager = new require_permissionless_bindings_instance_manager.InstanceManagerContract(await addressProvider.getAddressOrRevert(require_permissionless_utils_literals.INSTANCE_MANAGER), new require_onchain_base_ChainContractsRegister.ChainContractsRegister(client));
|
|
164
|
+
return {
|
|
165
|
+
chainId,
|
|
166
|
+
client,
|
|
167
|
+
store: new require_permissionless_bindings_price_feed_store.PriceFeedStoreContract("0x74A868AC479EE145029bB80827BB77F7B7c441cB", client),
|
|
168
|
+
instanceManager,
|
|
169
|
+
instanceOwner: await instanceManager.getOwner()
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/** The common shape every batch is returned in. */
|
|
173
|
+
async #envelope(args) {
|
|
174
|
+
const { batch, author, name, txs, touchedFeeds } = args;
|
|
175
|
+
const { chainId, client, instanceManager, instanceOwner } = batch;
|
|
176
|
+
const wrapped = txs.map((tx) => instanceManager.wrapConfigureLocal(tx));
|
|
177
|
+
const safeBatch = require_permissionless_utils_governance_batch.getSafeBatch({
|
|
178
|
+
chainId,
|
|
179
|
+
safeAddress: instanceOwner,
|
|
180
|
+
name,
|
|
181
|
+
txs: wrapped.map((tx) => require_permissionless_utils_governance_batch.convertRawTxToSafeMultisigTx(tx))
|
|
182
|
+
});
|
|
183
|
+
const [block, updatableFeeds] = await Promise.all([client.getBlock(), this.#updatableFeeds(touchedFeeds, client)]);
|
|
184
|
+
return {
|
|
185
|
+
chainId,
|
|
186
|
+
author,
|
|
187
|
+
instanceManager: instanceManager.address,
|
|
188
|
+
batches: [safeBatch.transactions],
|
|
189
|
+
createdAtBlock: Number(block.number),
|
|
190
|
+
updatableFeeds: [updatableFeeds]
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/** Which of the touched feeds the executor has to push a price update for. */
|
|
194
|
+
async #updatableFeeds(touchedFeeds, client) {
|
|
195
|
+
if (touchedFeeds.length === 0) return [];
|
|
196
|
+
const sdk = await this.#sdk(client);
|
|
197
|
+
return (await require_permissionless_utils_price_update_get_updatable_feeds.getUpdatablePriceFeeds({
|
|
198
|
+
sdk,
|
|
199
|
+
client,
|
|
200
|
+
pfCompressor: this.#compressorFrom(sdk),
|
|
201
|
+
priceFeeds: touchedFeeds
|
|
202
|
+
})).map((contract) => contract.address);
|
|
203
|
+
}
|
|
204
|
+
async #priceFeedCompressor(client) {
|
|
205
|
+
return this.#compressorFrom(await this.#sdk(client));
|
|
206
|
+
}
|
|
207
|
+
#compressorFrom(sdk) {
|
|
208
|
+
const [compressor] = sdk.addressProvider.mustGetLatest(require_onchain_constants_address_provider.AP_PRICE_FEED_COMPRESSOR, require_onchain_constants_versions.VERSION_RANGE_310);
|
|
209
|
+
return compressor;
|
|
210
|
+
}
|
|
211
|
+
async #sdk(client) {
|
|
212
|
+
const chainId = client.chain?.id ?? await client.getChainId();
|
|
213
|
+
const sdk = new require_onchain_OnchainSDK.OnchainSDK(require_onchain_chain_chains.getNetworkType(chainId), { client });
|
|
214
|
+
await sdk.attach({ marketConfigurators: [] });
|
|
215
|
+
return sdk;
|
|
216
|
+
}
|
|
217
|
+
/** Every asset each feed is currently allowed on, keyed by lowercase feed. */
|
|
218
|
+
async #feedToAssets(store) {
|
|
219
|
+
const byFeed = /* @__PURE__ */ new Map();
|
|
220
|
+
for (const { token, priceFeeds } of await store.getTokenPriceFeedsMap()) for (const feed of priceFeeds) {
|
|
221
|
+
const key = lower(feed);
|
|
222
|
+
const assets = byFeed.get(key);
|
|
223
|
+
if (assets) assets.push(token.toLowerCase());
|
|
224
|
+
else byFeed.set(key, [token.toLowerCase()]);
|
|
225
|
+
}
|
|
226
|
+
return byFeed;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
//#endregion
|
|
230
|
+
exports.InstanceOwnerTransactions = InstanceOwnerTransactions;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_permissionless_api_transactions_InstanceOwnerTransactions = require("./InstanceOwnerTransactions.js");
|
|
3
|
+
require("./types.js");
|
|
4
|
+
exports.InstanceOwnerTransactions = require_permissionless_api_transactions_InstanceOwnerTransactions.InstanceOwnerTransactions;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_onchain_utils_createRawTx = require("../../../onchain/utils/createRawTx.js");
|
|
3
|
+
const require_onchain_utils_viem_simulateMulticall = require("../../../onchain/utils/viem/simulateMulticall.js");
|
|
4
|
+
const require_abi_compressors_priceFeedCompressor = require("../../../abi/compressors/priceFeedCompressor.js");
|
|
5
|
+
require("../../../onchain/index.js");
|
|
6
|
+
let viem = require("viem");
|
|
7
|
+
//#region src/permissionless/api/transactions/lp-price-feeds.ts
|
|
8
|
+
const LOWER_BOUND_FACTOR = 999n;
|
|
9
|
+
const ilpPriceFeedAbi = (0, viem.parseAbi)([
|
|
10
|
+
"function contractType() external view returns (bytes32)",
|
|
11
|
+
"function setLimiter(uint256 newLimiter) external",
|
|
12
|
+
"function getLPExchangeRate() public view returns (uint256 exchangeRate)",
|
|
13
|
+
"function lowerBound() external view returns (uint256)",
|
|
14
|
+
"function upperBound() external view returns (uint256)"
|
|
15
|
+
]);
|
|
16
|
+
function currentLowerBound(client, address) {
|
|
17
|
+
return client.readContract({
|
|
18
|
+
abi: ilpPriceFeedAbi,
|
|
19
|
+
address,
|
|
20
|
+
functionName: "lowerBound"
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function getValue(client, address) {
|
|
24
|
+
return client.readContract({
|
|
25
|
+
abi: ilpPriceFeedAbi,
|
|
26
|
+
address,
|
|
27
|
+
functionName: "getLPExchangeRate"
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function toLowerBound(value) {
|
|
31
|
+
return value * LOWER_BOUND_FACTOR / 1000n;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Moves an LP feed's lower bound back under its current exchange rate, when
|
|
35
|
+
* the rate has outgrown the bound or drifted far enough from it to be worth a
|
|
36
|
+
* transaction. Returns nothing when the bound still fits.
|
|
37
|
+
**/
|
|
38
|
+
async function updateBounds(client, address) {
|
|
39
|
+
const value = await getValue(client, address);
|
|
40
|
+
const currentLowerBoundValue = await currentLowerBound(client, address);
|
|
41
|
+
const lowerBound = toLowerBound(value);
|
|
42
|
+
const deviationFromValue = Math.floor(Number(10000n * (value - currentLowerBoundValue) / currentLowerBoundValue)) / 1e4;
|
|
43
|
+
const deviationFromBound = Math.floor(Number(10000n * (lowerBound - currentLowerBoundValue) / currentLowerBoundValue)) / 1e4;
|
|
44
|
+
const txs = [];
|
|
45
|
+
if (deviationFromValue < 0 || Math.abs(deviationFromBound) > .005) txs.push(require_onchain_utils_createRawTx.createRawTx(address, {
|
|
46
|
+
abi: ilpPriceFeedAbi,
|
|
47
|
+
functionName: "setLimiter",
|
|
48
|
+
args: [lowerBound]
|
|
49
|
+
}, `[${address}].setLimiter(${lowerBound}); // deviationFromValue: ${(100 * deviationFromValue).toFixed(2)}%`));
|
|
50
|
+
return txs;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Of the whole feed tree behind `feeds`, the ones that are LP feeds: the
|
|
54
|
+
* probe keeps whatever answers `getLPExchangeRate`.
|
|
55
|
+
**/
|
|
56
|
+
async function getFeedsToUpdate(client, pfCompressor, feeds) {
|
|
57
|
+
const updateableFeeds = /* @__PURE__ */ new Set();
|
|
58
|
+
const { data } = await client.call({
|
|
59
|
+
to: pfCompressor,
|
|
60
|
+
data: (0, viem.encodeFunctionData)({
|
|
61
|
+
abi: require_abi_compressors_priceFeedCompressor.priceFeedCompressorAbi,
|
|
62
|
+
functionName: "loadPriceFeedTree",
|
|
63
|
+
args: [feeds]
|
|
64
|
+
}),
|
|
65
|
+
gas: 200000000n
|
|
66
|
+
});
|
|
67
|
+
const trees = (0, viem.decodeFunctionResult)({
|
|
68
|
+
abi: require_abi_compressors_priceFeedCompressor.priceFeedCompressorAbi,
|
|
69
|
+
functionName: "loadPriceFeedTree",
|
|
70
|
+
data: data ?? "0x"
|
|
71
|
+
});
|
|
72
|
+
for (const tree of trees) updateableFeeds.add(tree.baseParams.addr.toLowerCase());
|
|
73
|
+
const candidates = Array.from(updateableFeeds);
|
|
74
|
+
const { results } = await require_onchain_utils_viem_simulateMulticall.simulateMulticall(client, {
|
|
75
|
+
contracts: candidates.map((feed) => ({
|
|
76
|
+
address: feed,
|
|
77
|
+
abi: ilpPriceFeedAbi,
|
|
78
|
+
functionName: "getLPExchangeRate"
|
|
79
|
+
})),
|
|
80
|
+
allowFailure: true
|
|
81
|
+
});
|
|
82
|
+
return candidates.filter((_, index) => results[index]?.status === "success");
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
exports.getFeedsToUpdate = getFeedsToUpdate;
|
|
86
|
+
exports.updateBounds = updateBounds;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
@@ -4,9 +4,9 @@ const require_onchain_base_BaseContract = require("../../onchain/base/BaseContra
|
|
|
4
4
|
require("../../onchain/index.js");
|
|
5
5
|
const require_permissionless_utils_literals = require("../utils/literals.js");
|
|
6
6
|
const require_permissionless_utils_signature = require("../utils/signature.js");
|
|
7
|
-
const require_abi_310_crossChainMultisig = require("../../abi/310/crossChainMultisig.js");
|
|
8
7
|
require("../deployment/addresses.js");
|
|
9
8
|
const require_permissionless_bindings_instance_manager = require("./instance-manager.js");
|
|
9
|
+
const require_abi_310_crossChainMultisig = require("../../abi/310/crossChainMultisig.js");
|
|
10
10
|
const require_permissionless_bindings_market_configurator_factory = require("./market-configurator-factory.js");
|
|
11
11
|
let viem = require("viem");
|
|
12
12
|
//#region src/permissionless/bindings/cross-chain-multisig.ts
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_permissionless_bindings_address_provider = require("./address-provider.js");
|
|
3
2
|
const require_permissionless_bindings_bytecode_repository = require("./bytecode-repository.js");
|
|
3
|
+
const require_permissionless_bindings_pricefeeds_index = require("./pricefeeds/index.js");
|
|
4
|
+
const require_permissionless_bindings_price_feed_store = require("./price-feed-store.js");
|
|
5
|
+
const require_permissionless_bindings_address_provider = require("./address-provider.js");
|
|
4
6
|
const require_permissionless_bindings_compressors_token_compressor = require("./compressors/token-compressor.js");
|
|
5
7
|
const require_permissionless_bindings_compressors_withdrawal_compressor = require("./compressors/withdrawal-compressor.js");
|
|
6
8
|
require("./compressors/index.js");
|
|
7
|
-
const require_permissionless_bindings_pricefeeds_index = require("./pricefeeds/index.js");
|
|
8
|
-
const require_permissionless_bindings_price_feed_store = require("./price-feed-store.js");
|
|
9
9
|
const require_permissionless_bindings_router_routing_manager = require("./router/routing-manager.js");
|
|
10
10
|
require("./router/index.js");
|
|
11
11
|
const require_permissionless_bindings_treasury_splitter = require("./treasury-splitter.js");
|
|
@@ -4,8 +4,7 @@ const require_onchain_base_BaseContract = require("../../onchain/base/BaseContra
|
|
|
4
4
|
const require_abi_router_gearboxRouter = require("../../abi/router/gearboxRouter.js");
|
|
5
5
|
require("../../onchain/index.js");
|
|
6
6
|
const require_permissionless_bindings_bytecode_repository = require("./bytecode-repository.js");
|
|
7
|
-
const
|
|
8
|
-
require("./compressors/index.js");
|
|
7
|
+
const require_permissionless_bindings_price_feed_store = require("./price-feed-store.js");
|
|
9
8
|
require("../deployment/addresses.js");
|
|
10
9
|
const require_abi_310_instanceManager = require("../../abi/310/instanceManager.js");
|
|
11
10
|
const require_abi_router_camelotV3Worker = require("../../abi/router/camelotV3Worker.js");
|
|
@@ -14,7 +13,8 @@ const require_abi_router_mellow4626Worker = require("../../abi/router/mellow4626
|
|
|
14
13
|
const require_abi_router_pendleRouterWorker = require("../../abi/router/pendleRouterWorker.js");
|
|
15
14
|
const require_abi_router_uniswapV3Worker = require("../../abi/router/uniswapV3Worker.js");
|
|
16
15
|
const require_abi_router_uniswapV4Worker = require("../../abi/router/uniswapV4Worker.js");
|
|
17
|
-
const
|
|
16
|
+
const require_permissionless_bindings_compressors_withdrawal_compressor = require("./compressors/withdrawal-compressor.js");
|
|
17
|
+
require("./compressors/index.js");
|
|
18
18
|
const require_permissionless_bindings_router_routing_manager = require("./router/routing-manager.js");
|
|
19
19
|
require("./router/index.js");
|
|
20
20
|
const require_permissionless_bindings_treasury_splitter = require("./treasury-splitter.js");
|