viem 2.55.11 → 2.55.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/_cjs/actions/wallet/prepareTransactionRequest.js +12 -12
- package/_cjs/actions/wallet/prepareTransactionRequest.js.map +1 -1
- package/_cjs/actions/wallet/sendTransaction.js +24 -12
- package/_cjs/actions/wallet/sendTransaction.js.map +1 -1
- package/_cjs/actions/wallet/sendTransactionSync.js +24 -12
- package/_cjs/actions/wallet/sendTransactionSync.js.map +1 -1
- package/_cjs/clients/createClient.js +1 -0
- package/_cjs/clients/createClient.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/tempo/Decorator.js +7 -0
- package/_cjs/tempo/Decorator.js.map +1 -1
- package/_cjs/tempo/actions/earn/deployment.js +654 -0
- package/_cjs/tempo/actions/earn/deployment.js.map +1 -0
- package/_cjs/tempo/actions/earn.js +15 -0
- package/_cjs/tempo/actions/earn.js.map +1 -1
- package/_cjs/tempo/actions/zone.js +11 -1
- package/_cjs/tempo/actions/zone.js.map +1 -1
- package/_cjs/tempo/chainConfig.js +24 -23
- package/_cjs/tempo/chainConfig.js.map +1 -1
- package/_cjs/tempo/internal/WithdrawalSenderTag.js +2 -2
- package/_cjs/tempo/internal/WithdrawalSenderTag.js.map +1 -1
- package/_cjs/tempo/zones/Abis.js +17 -0
- package/_cjs/tempo/zones/Abis.js.map +1 -1
- package/_esm/actions/wallet/prepareTransactionRequest.js +14 -13
- package/_esm/actions/wallet/prepareTransactionRequest.js.map +1 -1
- package/_esm/actions/wallet/sendTransaction.js +24 -12
- package/_esm/actions/wallet/sendTransaction.js.map +1 -1
- package/_esm/actions/wallet/sendTransactionSync.js +24 -12
- package/_esm/actions/wallet/sendTransactionSync.js.map +1 -1
- package/_esm/clients/createClient.js +4 -3
- package/_esm/clients/createClient.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/tempo/Decorator.js +7 -0
- package/_esm/tempo/Decorator.js.map +1 -1
- package/_esm/tempo/actions/earn/deployment.js +967 -0
- package/_esm/tempo/actions/earn/deployment.js.map +1 -0
- package/_esm/tempo/actions/earn.js +2 -0
- package/_esm/tempo/actions/earn.js.map +1 -1
- package/_esm/tempo/actions/zone.js +11 -1
- package/_esm/tempo/actions/zone.js.map +1 -1
- package/_esm/tempo/chainConfig.js +26 -28
- package/_esm/tempo/chainConfig.js.map +1 -1
- package/_esm/tempo/internal/WithdrawalSenderTag.js +3 -3
- package/_esm/tempo/internal/WithdrawalSenderTag.js.map +1 -1
- package/_esm/tempo/zones/Abis.js +17 -0
- package/_esm/tempo/zones/Abis.js.map +1 -1
- package/_types/actions/wallet/prepareTransactionRequest.d.ts.map +1 -1
- package/_types/actions/wallet/sendTransaction.d.ts.map +1 -1
- package/_types/actions/wallet/sendTransactionSync.d.ts.map +1 -1
- package/_types/clients/createClient.d.ts +3 -3
- package/_types/clients/createClient.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/tempo/Decorator.d.ts +18 -0
- package/_types/tempo/Decorator.d.ts.map +1 -1
- package/_types/tempo/actions/earn/deployment.d.ts +1710 -0
- package/_types/tempo/actions/earn/deployment.d.ts.map +1 -0
- package/_types/tempo/actions/earn.d.ts +1 -1
- package/_types/tempo/actions/earn.d.ts.map +1 -1
- package/_types/tempo/actions/zone.d.ts.map +1 -1
- package/_types/tempo/chainConfig.d.ts.map +1 -1
- package/_types/tempo/internal/WithdrawalSenderTag.d.ts +2 -1
- package/_types/tempo/internal/WithdrawalSenderTag.d.ts.map +1 -1
- package/_types/tempo/zones/Abis.d.ts +48 -0
- package/_types/tempo/zones/Abis.d.ts.map +1 -1
- package/actions/wallet/prepareTransactionRequest.ts +18 -17
- package/actions/wallet/sendTransaction.ts +25 -10
- package/actions/wallet/sendTransactionSync.ts +25 -10
- package/clients/createClient.ts +4 -3
- package/errors/version.ts +1 -1
- package/package.json +1 -1
- package/tempo/Decorator.ts +41 -0
- package/tempo/actions/earn/deployment.ts +1427 -0
- package/tempo/actions/earn.ts +3 -0
- package/tempo/actions/zone.ts +10 -1
- package/tempo/chainConfig.ts +30 -27
- package/tempo/internal/WithdrawalSenderTag.ts +5 -4
- package/tempo/zones/Abis.ts +17 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeployErc4626StackError = void 0;
|
|
4
|
+
exports.createErc4626Engine = createErc4626Engine;
|
|
5
|
+
exports.createErc4626EngineSync = createErc4626EngineSync;
|
|
6
|
+
exports.createStack = createStack;
|
|
7
|
+
exports.createStackSync = createStackSync;
|
|
8
|
+
exports.bindErc4626Engine = bindErc4626Engine;
|
|
9
|
+
exports.bindErc4626EngineSync = bindErc4626EngineSync;
|
|
10
|
+
exports.deployErc4626StackSync = deployErc4626StackSync;
|
|
11
|
+
const ox_1 = require("ox");
|
|
12
|
+
const parseAccount_js_1 = require("../../../accounts/utils/parseAccount.js");
|
|
13
|
+
const getCode_js_1 = require("../../../actions/public/getCode.js");
|
|
14
|
+
const getLogs_js_1 = require("../../../actions/public/getLogs.js");
|
|
15
|
+
const readContract_js_1 = require("../../../actions/public/readContract.js");
|
|
16
|
+
const simulateContract_js_1 = require("../../../actions/public/simulateContract.js");
|
|
17
|
+
const writeContract_js_1 = require("../../../actions/wallet/writeContract.js");
|
|
18
|
+
const writeContractSync_js_1 = require("../../../actions/wallet/writeContractSync.js");
|
|
19
|
+
const address_js_1 = require("../../../constants/address.js");
|
|
20
|
+
const number_js_1 = require("../../../constants/number.js");
|
|
21
|
+
const account_js_1 = require("../../../errors/account.js");
|
|
22
|
+
const base_js_1 = require("../../../errors/base.js");
|
|
23
|
+
const transaction_js_1 = require("../../../errors/transaction.js");
|
|
24
|
+
const getAbiItem_js_1 = require("../../../utils/abi/getAbiItem.js");
|
|
25
|
+
const parseEventLogs_js_1 = require("../../../utils/abi/parseEventLogs.js");
|
|
26
|
+
const isAddressEqual_js_1 = require("../../../utils/address/isAddressEqual.js");
|
|
27
|
+
const Abis = require("../../Abis.js");
|
|
28
|
+
const Addresses = require("../../Addresses.js");
|
|
29
|
+
const utils_js_1 = require("../../internal/utils.js");
|
|
30
|
+
async function createErc4626Engine(client, parameters) {
|
|
31
|
+
return createErc4626Engine.inner(writeContract_js_1.writeContract, client, parameters);
|
|
32
|
+
}
|
|
33
|
+
(function (createErc4626Engine) {
|
|
34
|
+
async function inner(action, client, parameters) {
|
|
35
|
+
const { account = client.account, chain = client.chain, deploymentId, factory, name, owner: owner_ = account, symbol, venue, ...rest } = parameters;
|
|
36
|
+
if (!account)
|
|
37
|
+
throw new account_js_1.AccountNotFoundError();
|
|
38
|
+
if (!owner_)
|
|
39
|
+
throw new Error('`owner` is required.');
|
|
40
|
+
const owner = (0, parseAccount_js_1.parseAccount)(owner_).address;
|
|
41
|
+
return (await action(client, {
|
|
42
|
+
...rest,
|
|
43
|
+
account,
|
|
44
|
+
chain,
|
|
45
|
+
...createErc4626Engine.call({
|
|
46
|
+
deploymentId,
|
|
47
|
+
factory,
|
|
48
|
+
name,
|
|
49
|
+
owner,
|
|
50
|
+
symbol,
|
|
51
|
+
venue,
|
|
52
|
+
}),
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
createErc4626Engine.inner = inner;
|
|
56
|
+
function call(args) {
|
|
57
|
+
validateDeploymentId(args.deploymentId);
|
|
58
|
+
return (0, utils_js_1.defineCall)({
|
|
59
|
+
address: args.factory,
|
|
60
|
+
abi: Abis.erc4626EngineFactory,
|
|
61
|
+
functionName: 'deploy',
|
|
62
|
+
args: [
|
|
63
|
+
args.deploymentId,
|
|
64
|
+
args.venue,
|
|
65
|
+
args.owner,
|
|
66
|
+
args.name ?? '',
|
|
67
|
+
args.symbol ?? '',
|
|
68
|
+
],
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
createErc4626Engine.call = call;
|
|
72
|
+
async function predict(client, args) {
|
|
73
|
+
validateDeploymentId(args.deploymentId);
|
|
74
|
+
return (0, readContract_js_1.readContract)(client, {
|
|
75
|
+
address: args.factory,
|
|
76
|
+
abi: Abis.erc4626EngineFactory,
|
|
77
|
+
functionName: 'predictEngine',
|
|
78
|
+
args: [
|
|
79
|
+
args.deploymentId,
|
|
80
|
+
args.venue,
|
|
81
|
+
args.owner,
|
|
82
|
+
args.name ?? '',
|
|
83
|
+
args.symbol ?? '',
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
createErc4626Engine.predict = predict;
|
|
88
|
+
function extractEvent(logs, parameters) {
|
|
89
|
+
const [log] = (0, parseEventLogs_js_1.parseEventLogs)({
|
|
90
|
+
abi: Abis.erc4626EngineFactory,
|
|
91
|
+
eventName: 'ERC4626EngineDeployed',
|
|
92
|
+
logs: logs.filter((log) => (0, isAddressEqual_js_1.isAddressEqual)(log.address, parameters.factory)),
|
|
93
|
+
strict: true,
|
|
94
|
+
});
|
|
95
|
+
if (!log)
|
|
96
|
+
throw new Error('`ERC4626EngineDeployed` event not found.');
|
|
97
|
+
return log;
|
|
98
|
+
}
|
|
99
|
+
createErc4626Engine.extractEvent = extractEvent;
|
|
100
|
+
})(createErc4626Engine || (exports.createErc4626Engine = createErc4626Engine = {}));
|
|
101
|
+
async function createErc4626EngineSync(client, parameters) {
|
|
102
|
+
const { factory, throwOnReceiptRevert = true } = parameters;
|
|
103
|
+
const receipt = await createErc4626Engine.inner(writeContractSync_js_1.writeContractSync, client, {
|
|
104
|
+
...parameters,
|
|
105
|
+
throwOnReceiptRevert,
|
|
106
|
+
});
|
|
107
|
+
const { args } = createErc4626Engine.extractEvent(receipt.logs, { factory });
|
|
108
|
+
return { ...args, receipt };
|
|
109
|
+
}
|
|
110
|
+
async function createStack(client, parameters) {
|
|
111
|
+
return createStack.inner(writeContract_js_1.writeContract, client, parameters);
|
|
112
|
+
}
|
|
113
|
+
(function (createStack) {
|
|
114
|
+
async function inner(action, client, parameters) {
|
|
115
|
+
const { account = client.account, chain = client.chain, controls, deploymentId, distributor, engine, factory, fees, owner: owner_ = account, transferPolicyId, ...rest } = parameters;
|
|
116
|
+
if (!account)
|
|
117
|
+
throw new account_js_1.AccountNotFoundError();
|
|
118
|
+
if (!owner_)
|
|
119
|
+
throw new Error('`owner` is required.');
|
|
120
|
+
return (await action(client, {
|
|
121
|
+
...rest,
|
|
122
|
+
account,
|
|
123
|
+
chain,
|
|
124
|
+
...createStack.call({
|
|
125
|
+
controls,
|
|
126
|
+
deploymentId,
|
|
127
|
+
distributor,
|
|
128
|
+
engine,
|
|
129
|
+
factory,
|
|
130
|
+
fees,
|
|
131
|
+
owner: (0, parseAccount_js_1.parseAccount)(owner_).address,
|
|
132
|
+
transferPolicyId,
|
|
133
|
+
}),
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
createStack.inner = inner;
|
|
137
|
+
function call(args) {
|
|
138
|
+
validateDeploymentId(args.deploymentId);
|
|
139
|
+
return (0, utils_js_1.defineCall)({
|
|
140
|
+
address: args.factory,
|
|
141
|
+
abi: Abis.earnFactory,
|
|
142
|
+
functionName: 'deploy',
|
|
143
|
+
args: [toDeployParameters(args)],
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
createStack.call = call;
|
|
147
|
+
async function predict(client, args) {
|
|
148
|
+
validateDeploymentId(args.deploymentId);
|
|
149
|
+
const parameters = toDeployParameters(args);
|
|
150
|
+
const [earnShare, earnFees] = await Promise.all([
|
|
151
|
+
(0, readContract_js_1.readContract)(client, {
|
|
152
|
+
address: args.factory,
|
|
153
|
+
abi: Abis.earnFactory,
|
|
154
|
+
functionName: 'predictEarnShare',
|
|
155
|
+
args: [parameters],
|
|
156
|
+
}),
|
|
157
|
+
(0, readContract_js_1.readContract)(client, {
|
|
158
|
+
address: args.factory,
|
|
159
|
+
abi: Abis.earnFactory,
|
|
160
|
+
functionName: 'predictEarnFees',
|
|
161
|
+
args: [parameters],
|
|
162
|
+
}),
|
|
163
|
+
]);
|
|
164
|
+
return { earnFees, earnShare };
|
|
165
|
+
}
|
|
166
|
+
createStack.predict = predict;
|
|
167
|
+
function extractEvent(logs, parameters) {
|
|
168
|
+
const [log] = (0, parseEventLogs_js_1.parseEventLogs)({
|
|
169
|
+
abi: Abis.earnFactory,
|
|
170
|
+
eventName: 'EarnStackDeployed',
|
|
171
|
+
logs: logs.filter((log) => (0, isAddressEqual_js_1.isAddressEqual)(log.address, parameters.factory)),
|
|
172
|
+
strict: true,
|
|
173
|
+
});
|
|
174
|
+
if (!log)
|
|
175
|
+
throw new Error('`EarnStackDeployed` event not found.');
|
|
176
|
+
return log;
|
|
177
|
+
}
|
|
178
|
+
createStack.extractEvent = extractEvent;
|
|
179
|
+
})(createStack || (exports.createStack = createStack = {}));
|
|
180
|
+
async function createStackSync(client, parameters) {
|
|
181
|
+
const { factory, throwOnReceiptRevert = true } = parameters;
|
|
182
|
+
const receipt = await createStack.inner(writeContractSync_js_1.writeContractSync, client, {
|
|
183
|
+
...parameters,
|
|
184
|
+
throwOnReceiptRevert,
|
|
185
|
+
});
|
|
186
|
+
const { args } = createStack.extractEvent(receipt.logs, { factory });
|
|
187
|
+
return { ...args, receipt };
|
|
188
|
+
}
|
|
189
|
+
async function bindErc4626Engine(client, parameters) {
|
|
190
|
+
return bindErc4626Engine.inner(writeContract_js_1.writeContract, client, parameters);
|
|
191
|
+
}
|
|
192
|
+
(function (bindErc4626Engine) {
|
|
193
|
+
async function inner(action, client, parameters) {
|
|
194
|
+
const { engine, vault, ...rest } = parameters;
|
|
195
|
+
return (await action(client, {
|
|
196
|
+
...rest,
|
|
197
|
+
...bindErc4626Engine.call({ engine, vault }),
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
200
|
+
bindErc4626Engine.inner = inner;
|
|
201
|
+
function call(args) {
|
|
202
|
+
return (0, utils_js_1.defineCall)({
|
|
203
|
+
address: args.engine,
|
|
204
|
+
abi: Abis.erc4626Engine,
|
|
205
|
+
functionName: 'initializeEarnVault',
|
|
206
|
+
args: [args.vault],
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
bindErc4626Engine.call = call;
|
|
210
|
+
function extractEvent(logs, parameters) {
|
|
211
|
+
const [log] = (0, parseEventLogs_js_1.parseEventLogs)({
|
|
212
|
+
abi: Abis.erc4626Engine,
|
|
213
|
+
eventName: 'EarnVaultInitialized',
|
|
214
|
+
logs: logs.filter((log) => (0, isAddressEqual_js_1.isAddressEqual)(log.address, parameters.engine)),
|
|
215
|
+
strict: true,
|
|
216
|
+
});
|
|
217
|
+
if (!log)
|
|
218
|
+
throw new Error('`EarnVaultInitialized` event not found.');
|
|
219
|
+
return log;
|
|
220
|
+
}
|
|
221
|
+
bindErc4626Engine.extractEvent = extractEvent;
|
|
222
|
+
})(bindErc4626Engine || (exports.bindErc4626Engine = bindErc4626Engine = {}));
|
|
223
|
+
async function bindErc4626EngineSync(client, parameters) {
|
|
224
|
+
const { engine, throwOnReceiptRevert = true } = parameters;
|
|
225
|
+
const receipt = await bindErc4626Engine.inner(writeContractSync_js_1.writeContractSync, client, {
|
|
226
|
+
...parameters,
|
|
227
|
+
throwOnReceiptRevert,
|
|
228
|
+
});
|
|
229
|
+
const { args } = bindErc4626Engine.extractEvent(receipt.logs, { engine });
|
|
230
|
+
return { engine, vault: args.earnVault, receipt };
|
|
231
|
+
}
|
|
232
|
+
class DeployErc4626StackError extends base_js_1.BaseError {
|
|
233
|
+
constructor(cause, parameters) {
|
|
234
|
+
super(`ERC-4626 Earn deployment failed during ${parameters.stage}.`, {
|
|
235
|
+
cause,
|
|
236
|
+
name: 'DeployErc4626StackError',
|
|
237
|
+
});
|
|
238
|
+
Object.defineProperty(this, "receipts", {
|
|
239
|
+
enumerable: true,
|
|
240
|
+
configurable: true,
|
|
241
|
+
writable: true,
|
|
242
|
+
value: void 0
|
|
243
|
+
});
|
|
244
|
+
Object.defineProperty(this, "stage", {
|
|
245
|
+
enumerable: true,
|
|
246
|
+
configurable: true,
|
|
247
|
+
writable: true,
|
|
248
|
+
value: void 0
|
|
249
|
+
});
|
|
250
|
+
Object.defineProperty(this, "state", {
|
|
251
|
+
enumerable: true,
|
|
252
|
+
configurable: true,
|
|
253
|
+
writable: true,
|
|
254
|
+
value: void 0
|
|
255
|
+
});
|
|
256
|
+
this.receipts = parameters.receipts;
|
|
257
|
+
this.stage = parameters.stage;
|
|
258
|
+
this.state = parameters.state;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
exports.DeployErc4626StackError = DeployErc4626StackError;
|
|
262
|
+
async function deployErc4626StackSync(client, parameters) {
|
|
263
|
+
const deployer = parameters.account ?? client.account;
|
|
264
|
+
if (!deployer)
|
|
265
|
+
throw new account_js_1.AccountNotFoundError();
|
|
266
|
+
const owner_ = parameters.owner ?? deployer;
|
|
267
|
+
const owner = (0, parseAccount_js_1.parseAccount)(owner_).address;
|
|
268
|
+
const deployerAddress = (0, parseAccount_js_1.parseAccount)(deployer).address;
|
|
269
|
+
const bindingAccount = (() => {
|
|
270
|
+
if (parameters.bindingAccount)
|
|
271
|
+
return parameters.bindingAccount;
|
|
272
|
+
if (typeof owner_ !== 'string')
|
|
273
|
+
return owner_;
|
|
274
|
+
if ((0, isAddressEqual_js_1.isAddressEqual)(owner, deployerAddress))
|
|
275
|
+
return deployer;
|
|
276
|
+
return undefined;
|
|
277
|
+
})();
|
|
278
|
+
if (bindingAccount &&
|
|
279
|
+
!(0, isAddressEqual_js_1.isAddressEqual)((0, parseAccount_js_1.parseAccount)(bindingAccount).address, owner))
|
|
280
|
+
throw new Error('`bindingAccount` must match `owner`.');
|
|
281
|
+
validateDeploymentId(parameters.deploymentId);
|
|
282
|
+
if (parameters.resume &&
|
|
283
|
+
parameters.resume.deploymentId.toLowerCase() !==
|
|
284
|
+
parameters.deploymentId.toLowerCase())
|
|
285
|
+
throw new Error('The resumed deployment ID does not match `deploymentId`.');
|
|
286
|
+
await validateContracts(client, {
|
|
287
|
+
factories: parameters.factories,
|
|
288
|
+
venue: parameters.venue,
|
|
289
|
+
});
|
|
290
|
+
const { gas: _, keyAuthorization: __, nonce: ___, ...sharedWriteParameters } = (0, utils_js_1.pickWriteParameters)(parameters);
|
|
291
|
+
const writeParameters = {
|
|
292
|
+
...sharedWriteParameters,
|
|
293
|
+
...(0, utils_js_1.pickWriteSyncParameters)(parameters),
|
|
294
|
+
account: deployer,
|
|
295
|
+
throwOnReceiptRevert: true,
|
|
296
|
+
};
|
|
297
|
+
const engineArgs = {
|
|
298
|
+
deploymentId: parameters.deploymentId,
|
|
299
|
+
factory: parameters.factories.erc4626Engine,
|
|
300
|
+
name: parameters.name,
|
|
301
|
+
owner,
|
|
302
|
+
symbol: parameters.symbol,
|
|
303
|
+
venue: parameters.venue,
|
|
304
|
+
};
|
|
305
|
+
const predictedEngine = await createErc4626Engine.predict(client, engineArgs);
|
|
306
|
+
const state = {
|
|
307
|
+
deploymentId: parameters.deploymentId,
|
|
308
|
+
earnShare: parameters.resume?.earnShare,
|
|
309
|
+
engine: predictedEngine,
|
|
310
|
+
fees: parameters.resume?.fees,
|
|
311
|
+
vault: parameters.resume?.vault,
|
|
312
|
+
};
|
|
313
|
+
if (parameters.resume?.engine &&
|
|
314
|
+
!(0, isAddressEqual_js_1.isAddressEqual)(parameters.resume.engine, predictedEngine))
|
|
315
|
+
throw new Error('The resumed engine does not match the factory prediction.');
|
|
316
|
+
const engineExists = await hasCode(client, predictedEngine);
|
|
317
|
+
if (!bindingAccount) {
|
|
318
|
+
const boundVault = engineExists
|
|
319
|
+
? await (0, readContract_js_1.readContract)(client, {
|
|
320
|
+
address: predictedEngine,
|
|
321
|
+
abi: Abis.erc4626Engine,
|
|
322
|
+
functionName: 'earnVault',
|
|
323
|
+
})
|
|
324
|
+
: address_js_1.zeroAddress;
|
|
325
|
+
if ((0, isAddressEqual_js_1.isAddressEqual)(boundVault, address_js_1.zeroAddress))
|
|
326
|
+
throw new Error('`bindingAccount` is required when the final owner differs from the deployment account.');
|
|
327
|
+
}
|
|
328
|
+
const receipts = {};
|
|
329
|
+
try {
|
|
330
|
+
if (!engineExists) {
|
|
331
|
+
await (0, simulateContract_js_1.simulateContract)(client, {
|
|
332
|
+
...sharedWriteParameters,
|
|
333
|
+
account: deployer,
|
|
334
|
+
...createErc4626Engine.call(engineArgs),
|
|
335
|
+
});
|
|
336
|
+
const receipt = await createErc4626Engine.inner(writeContractSync_js_1.writeContractSync, client, {
|
|
337
|
+
...writeParameters,
|
|
338
|
+
...engineArgs,
|
|
339
|
+
});
|
|
340
|
+
receipts.engine = receipt;
|
|
341
|
+
createErc4626Engine.extractEvent(receipt.logs, {
|
|
342
|
+
factory: parameters.factories.erc4626Engine,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
await verifyEngine(client, engineArgs, predictedEngine);
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
throw deploymentError(error, 'engine', state, receipts);
|
|
349
|
+
}
|
|
350
|
+
const stackArgs = {
|
|
351
|
+
controls: parameters.controls,
|
|
352
|
+
deploymentId: parameters.deploymentId,
|
|
353
|
+
distributor: parameters.distributor,
|
|
354
|
+
engine: predictedEngine,
|
|
355
|
+
factory: parameters.factories.earn,
|
|
356
|
+
fees: parameters.fees,
|
|
357
|
+
owner,
|
|
358
|
+
transferPolicyId: parameters.transferPolicyId,
|
|
359
|
+
};
|
|
360
|
+
try {
|
|
361
|
+
const predicted = await createStack.predict(client, stackArgs);
|
|
362
|
+
if (parameters.resume?.earnShare &&
|
|
363
|
+
!(0, isAddressEqual_js_1.isAddressEqual)(parameters.resume.earnShare, predicted.earnShare))
|
|
364
|
+
throw new Error('The resumed EarnShare does not match the factory prediction.');
|
|
365
|
+
if (parameters.resume?.fees &&
|
|
366
|
+
!(0, isAddressEqual_js_1.isAddressEqual)(parameters.resume.fees, predicted.earnFees))
|
|
367
|
+
throw new Error('The resumed EarnFees does not match the factory prediction.');
|
|
368
|
+
state.earnShare = predicted.earnShare;
|
|
369
|
+
state.fees = predicted.earnFees;
|
|
370
|
+
if (!(await hasCode(client, predicted.earnShare))) {
|
|
371
|
+
if (await hasCode(client, predicted.earnFees))
|
|
372
|
+
throw new Error('Predicted EarnFees exists without the predicted EarnShare.');
|
|
373
|
+
await (0, simulateContract_js_1.simulateContract)(client, {
|
|
374
|
+
...sharedWriteParameters,
|
|
375
|
+
account: deployer,
|
|
376
|
+
...createStack.call(stackArgs),
|
|
377
|
+
});
|
|
378
|
+
const receipt = await createStack.inner(writeContractSync_js_1.writeContractSync, client, {
|
|
379
|
+
...writeParameters,
|
|
380
|
+
...stackArgs,
|
|
381
|
+
});
|
|
382
|
+
receipts.stack = receipt;
|
|
383
|
+
const { args } = createStack.extractEvent(receipt.logs, {
|
|
384
|
+
factory: parameters.factories.earn,
|
|
385
|
+
});
|
|
386
|
+
state.vault = args.earnVault;
|
|
387
|
+
if (parameters.resume?.vault &&
|
|
388
|
+
!(0, isAddressEqual_js_1.isAddressEqual)(parameters.resume.vault, args.earnVault))
|
|
389
|
+
throw new Error('The resumed EarnVault does not match the factory deployment.');
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
if (!(await hasCode(client, predicted.earnFees)))
|
|
393
|
+
throw new Error('Predicted EarnShare exists without the predicted EarnFees.');
|
|
394
|
+
state.vault = parameters.resume?.vault;
|
|
395
|
+
if (!state.vault) {
|
|
396
|
+
const event = await findStackDeployment(client, {
|
|
397
|
+
earnShare: predicted.earnShare,
|
|
398
|
+
factory: parameters.factories.earn,
|
|
399
|
+
fromBlock: parameters.fromBlock,
|
|
400
|
+
});
|
|
401
|
+
state.vault = event.args.earnVault;
|
|
402
|
+
if (!(0, isAddressEqual_js_1.isAddressEqual)(event.args.earnFees, predicted.earnFees))
|
|
403
|
+
throw new Error('Recovered EarnFees does not match the factory prediction.');
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (!state.vault)
|
|
407
|
+
throw new Error('EarnVault address was not recovered.');
|
|
408
|
+
await verifyStack(client, {
|
|
409
|
+
engine: predictedEngine,
|
|
410
|
+
fees: predicted.earnFees,
|
|
411
|
+
owner,
|
|
412
|
+
share: predicted.earnShare,
|
|
413
|
+
vault: state.vault,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
throw deploymentError(error, 'stack', state, receipts);
|
|
418
|
+
}
|
|
419
|
+
try {
|
|
420
|
+
const vault = state.vault;
|
|
421
|
+
const boundVault = await (0, readContract_js_1.readContract)(client, {
|
|
422
|
+
address: predictedEngine,
|
|
423
|
+
abi: Abis.erc4626Engine,
|
|
424
|
+
functionName: 'earnVault',
|
|
425
|
+
});
|
|
426
|
+
if ((0, isAddressEqual_js_1.isAddressEqual)(boundVault, address_js_1.zeroAddress)) {
|
|
427
|
+
if (!bindingAccount)
|
|
428
|
+
throw new Error('`bindingAccount` is required when the final owner differs from the deployment account.');
|
|
429
|
+
const bindingParameters = {
|
|
430
|
+
...writeParameters,
|
|
431
|
+
account: bindingAccount,
|
|
432
|
+
engine: predictedEngine,
|
|
433
|
+
vault,
|
|
434
|
+
};
|
|
435
|
+
await (0, simulateContract_js_1.simulateContract)(client, {
|
|
436
|
+
...sharedWriteParameters,
|
|
437
|
+
account: bindingAccount,
|
|
438
|
+
...bindErc4626Engine.call({ engine: predictedEngine, vault }),
|
|
439
|
+
});
|
|
440
|
+
const receipt = await bindErc4626Engine.inner(writeContractSync_js_1.writeContractSync, client, bindingParameters);
|
|
441
|
+
receipts.binding = receipt;
|
|
442
|
+
bindErc4626Engine.extractEvent(receipt.logs, { engine: predictedEngine });
|
|
443
|
+
}
|
|
444
|
+
else if (!(0, isAddressEqual_js_1.isAddressEqual)(boundVault, vault)) {
|
|
445
|
+
throw new Error(`Engine is already bound to ${boundVault}.`);
|
|
446
|
+
}
|
|
447
|
+
const verified = await (0, readContract_js_1.readContract)(client, {
|
|
448
|
+
address: predictedEngine,
|
|
449
|
+
abi: Abis.erc4626Engine,
|
|
450
|
+
functionName: 'earnVault',
|
|
451
|
+
});
|
|
452
|
+
if (!(0, isAddressEqual_js_1.isAddressEqual)(verified, vault))
|
|
453
|
+
throw new Error('Engine binding verification failed.');
|
|
454
|
+
}
|
|
455
|
+
catch (error) {
|
|
456
|
+
throw deploymentError(error, 'binding', state, receipts);
|
|
457
|
+
}
|
|
458
|
+
return {
|
|
459
|
+
deploymentId: parameters.deploymentId,
|
|
460
|
+
earnShare: state.earnShare,
|
|
461
|
+
engine: predictedEngine,
|
|
462
|
+
fees: state.fees,
|
|
463
|
+
receipts,
|
|
464
|
+
vault: state.vault,
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
function validateDeploymentId(deploymentId) {
|
|
468
|
+
if (ox_1.Hex.size(deploymentId) !== 32 || BigInt(deploymentId) === 0n)
|
|
469
|
+
throw new Error('`deploymentId` must be a nonzero 32-byte hex value.');
|
|
470
|
+
}
|
|
471
|
+
function toDeployParameters(args) {
|
|
472
|
+
const fixedFees = args.fees?.fixedFees ?? [];
|
|
473
|
+
if (fixedFees.length > 4)
|
|
474
|
+
throw new Error('Earn supports at most four fixed fee recipients.');
|
|
475
|
+
const seen = new Set();
|
|
476
|
+
let totalRateBps = 0;
|
|
477
|
+
for (const fee of fixedFees) {
|
|
478
|
+
validateFeeRate(fee.rateBps, '`fixedFees[].rateBps`', false);
|
|
479
|
+
if ((0, isAddressEqual_js_1.isAddressEqual)(fee.account, address_js_1.zeroAddress))
|
|
480
|
+
throw new Error('Fixed fee recipients cannot be the zero address.');
|
|
481
|
+
const account = fee.account.toLowerCase();
|
|
482
|
+
if (seen.has(account))
|
|
483
|
+
throw new Error('Fixed fee recipients must be unique.');
|
|
484
|
+
seen.add(account);
|
|
485
|
+
totalRateBps += fee.rateBps;
|
|
486
|
+
}
|
|
487
|
+
if (totalRateBps > 10_000)
|
|
488
|
+
throw new Error('The total fixed fee rate cannot exceed 10,000 bps.');
|
|
489
|
+
const excess = args.fees?.excess;
|
|
490
|
+
if (excess) {
|
|
491
|
+
validateFeeRate(excess.annualTargetRateBps, '`annualTargetRateBps`', true);
|
|
492
|
+
validateFeeRate(excess.rateBps, '`excess.rateBps`', false);
|
|
493
|
+
if ((0, isAddressEqual_js_1.isAddressEqual)(excess.account, address_js_1.zeroAddress))
|
|
494
|
+
throw new Error('The excess fee recipient cannot be the zero address.');
|
|
495
|
+
}
|
|
496
|
+
const zeroFee = { account: address_js_1.zeroAddress, rateBps: 0 };
|
|
497
|
+
const distributor = args.distributor?.distributor ?? address_js_1.zeroAddress;
|
|
498
|
+
const updateDelay = args.distributor?.updateDelay ?? 0;
|
|
499
|
+
if (args.distributor) {
|
|
500
|
+
if ((0, isAddressEqual_js_1.isAddressEqual)(distributor, address_js_1.zeroAddress))
|
|
501
|
+
throw new Error('An enabled distributor cannot be the zero address.');
|
|
502
|
+
if (updateDelay <= 0)
|
|
503
|
+
throw new Error('An enabled distributor requires a positive update delay.');
|
|
504
|
+
if (fixedFees.length === 0)
|
|
505
|
+
throw new Error('An enabled distributor requires at least one fixed fee.');
|
|
506
|
+
}
|
|
507
|
+
if (!Number.isSafeInteger(updateDelay) || updateDelay > 0xffffffffff)
|
|
508
|
+
throw new Error('`updateDelay` must fit into uint40 seconds.');
|
|
509
|
+
const transferPolicyId = args.transferPolicyId ?? 0n;
|
|
510
|
+
if (transferPolicyId < 0n || transferPolicyId > number_js_1.maxUint64)
|
|
511
|
+
throw new Error('`transferPolicyId` must fit into uint64.');
|
|
512
|
+
const maxManagedAssets = args.controls?.maxManagedAssets ?? 0n;
|
|
513
|
+
if (maxManagedAssets < 0n || maxManagedAssets > number_js_1.maxUint256)
|
|
514
|
+
throw new Error('`maxManagedAssets` must fit into uint256.');
|
|
515
|
+
return {
|
|
516
|
+
controls: {
|
|
517
|
+
asyncJanitor: args.controls?.asyncJanitor ?? address_js_1.zeroAddress,
|
|
518
|
+
emergencyGuardian: args.controls?.emergencyGuardian ?? address_js_1.zeroAddress,
|
|
519
|
+
maxManagedAssets,
|
|
520
|
+
migrationMode: (args.controls?.migrationMode ?? 'userOnly') === 'userOnly' ? 0 : 1,
|
|
521
|
+
},
|
|
522
|
+
deploymentId: args.deploymentId,
|
|
523
|
+
distributorConfig: { distributor, updateDelay },
|
|
524
|
+
engine: args.engine,
|
|
525
|
+
fees: {
|
|
526
|
+
excess: excess
|
|
527
|
+
? {
|
|
528
|
+
account: excess.account,
|
|
529
|
+
annualTargetRateBps: excess.annualTargetRateBps,
|
|
530
|
+
enabled: true,
|
|
531
|
+
excessFeeRateBps: excess.rateBps,
|
|
532
|
+
}
|
|
533
|
+
: {
|
|
534
|
+
account: address_js_1.zeroAddress,
|
|
535
|
+
annualTargetRateBps: 0,
|
|
536
|
+
enabled: false,
|
|
537
|
+
excessFeeRateBps: 0,
|
|
538
|
+
},
|
|
539
|
+
fixedFeeCount: fixedFees.length,
|
|
540
|
+
fixedFees: [
|
|
541
|
+
fixedFees[0] ?? zeroFee,
|
|
542
|
+
fixedFees[1] ?? zeroFee,
|
|
543
|
+
fixedFees[2] ?? zeroFee,
|
|
544
|
+
fixedFees[3] ?? zeroFee,
|
|
545
|
+
],
|
|
546
|
+
},
|
|
547
|
+
owner: args.owner,
|
|
548
|
+
transferPolicyId,
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
function validateFeeRate(rate, name, allowZero) {
|
|
552
|
+
if (!Number.isInteger(rate) || rate < (allowZero ? 0 : 1) || rate > 10_000)
|
|
553
|
+
throw new Error(`${name} must be an integer between ${allowZero ? 0 : 1} and 10,000.`);
|
|
554
|
+
}
|
|
555
|
+
async function hasCode(client, address) {
|
|
556
|
+
const code = await (0, getCode_js_1.getCode)(client, { address });
|
|
557
|
+
return code !== undefined && code !== '0x';
|
|
558
|
+
}
|
|
559
|
+
async function validateContracts(client, parameters) {
|
|
560
|
+
const [engineFactory, earnFactory, venue] = await Promise.all([
|
|
561
|
+
hasCode(client, parameters.factories.erc4626Engine),
|
|
562
|
+
hasCode(client, parameters.factories.earn),
|
|
563
|
+
hasCode(client, parameters.venue),
|
|
564
|
+
]);
|
|
565
|
+
if (!engineFactory)
|
|
566
|
+
throw new Error('ERC4626EngineFactory has no code.');
|
|
567
|
+
if (!earnFactory)
|
|
568
|
+
throw new Error('EarnFactory has no code.');
|
|
569
|
+
if (!venue)
|
|
570
|
+
throw new Error('ERC-4626 venue has no code.');
|
|
571
|
+
const tip20Factory = await (0, readContract_js_1.readContract)(client, {
|
|
572
|
+
address: parameters.factories.earn,
|
|
573
|
+
abi: Abis.earnFactory,
|
|
574
|
+
functionName: 'tip20Factory',
|
|
575
|
+
});
|
|
576
|
+
if (!(0, isAddressEqual_js_1.isAddressEqual)(tip20Factory, Addresses.tip20Factory))
|
|
577
|
+
throw new Error('EarnFactory uses an unexpected TIP-20 factory.');
|
|
578
|
+
}
|
|
579
|
+
async function verifyEngine(client, args, engine) {
|
|
580
|
+
const [venue, owner] = await Promise.all([
|
|
581
|
+
(0, readContract_js_1.readContract)(client, {
|
|
582
|
+
address: engine,
|
|
583
|
+
abi: Abis.erc4626Engine,
|
|
584
|
+
functionName: 'vault',
|
|
585
|
+
}),
|
|
586
|
+
(0, readContract_js_1.readContract)(client, {
|
|
587
|
+
address: engine,
|
|
588
|
+
abi: Abis.erc4626Engine,
|
|
589
|
+
functionName: 'owner',
|
|
590
|
+
}),
|
|
591
|
+
]);
|
|
592
|
+
if (!(0, isAddressEqual_js_1.isAddressEqual)(venue, args.venue))
|
|
593
|
+
throw new Error('Engine venue verification failed.');
|
|
594
|
+
if (!(0, isAddressEqual_js_1.isAddressEqual)(owner, args.owner))
|
|
595
|
+
throw new Error('Engine owner verification failed.');
|
|
596
|
+
}
|
|
597
|
+
async function verifyStack(client, parameters) {
|
|
598
|
+
const [engine, fees, operator, share] = await Promise.all([
|
|
599
|
+
(0, readContract_js_1.readContract)(client, {
|
|
600
|
+
address: parameters.vault,
|
|
601
|
+
abi: Abis.earnVault,
|
|
602
|
+
functionName: 'engine',
|
|
603
|
+
}),
|
|
604
|
+
(0, readContract_js_1.readContract)(client, {
|
|
605
|
+
address: parameters.vault,
|
|
606
|
+
abi: Abis.earnVault,
|
|
607
|
+
functionName: 'earnFees',
|
|
608
|
+
}),
|
|
609
|
+
(0, readContract_js_1.readContract)(client, {
|
|
610
|
+
address: parameters.vault,
|
|
611
|
+
abi: Abis.earnVault,
|
|
612
|
+
functionName: 'operator',
|
|
613
|
+
}),
|
|
614
|
+
(0, readContract_js_1.readContract)(client, {
|
|
615
|
+
address: parameters.vault,
|
|
616
|
+
abi: Abis.earnVault,
|
|
617
|
+
functionName: 'earnShare',
|
|
618
|
+
}),
|
|
619
|
+
]);
|
|
620
|
+
if (!(0, isAddressEqual_js_1.isAddressEqual)(engine, parameters.engine))
|
|
621
|
+
throw new Error('EarnVault engine verification failed.');
|
|
622
|
+
if (!(0, isAddressEqual_js_1.isAddressEqual)(fees, parameters.fees))
|
|
623
|
+
throw new Error('EarnVault fees verification failed.');
|
|
624
|
+
if (!(0, isAddressEqual_js_1.isAddressEqual)(operator, parameters.owner))
|
|
625
|
+
throw new Error('EarnVault operator verification failed.');
|
|
626
|
+
if (!(0, isAddressEqual_js_1.isAddressEqual)(share, parameters.share))
|
|
627
|
+
throw new Error('EarnVault share verification failed.');
|
|
628
|
+
}
|
|
629
|
+
async function findStackDeployment(client, parameters) {
|
|
630
|
+
const event = (0, getAbiItem_js_1.getAbiItem)({
|
|
631
|
+
abi: Abis.earnFactory,
|
|
632
|
+
name: 'EarnStackDeployed',
|
|
633
|
+
});
|
|
634
|
+
const logs = await (0, getLogs_js_1.getLogs)(client, {
|
|
635
|
+
address: parameters.factory,
|
|
636
|
+
args: { earnShare: parameters.earnShare },
|
|
637
|
+
event,
|
|
638
|
+
fromBlock: parameters.fromBlock ?? 0n,
|
|
639
|
+
strict: true,
|
|
640
|
+
toBlock: 'latest',
|
|
641
|
+
});
|
|
642
|
+
const log = logs.at(-1);
|
|
643
|
+
if (!log)
|
|
644
|
+
throw new Error('Prior `EarnStackDeployed` event not found.');
|
|
645
|
+
return log;
|
|
646
|
+
}
|
|
647
|
+
function deploymentError(error, stage, state, receipts) {
|
|
648
|
+
if (error instanceof DeployErc4626StackError)
|
|
649
|
+
return error;
|
|
650
|
+
if (error instanceof transaction_js_1.TransactionReceiptRevertedError)
|
|
651
|
+
receipts[stage] = error.receipt;
|
|
652
|
+
return new DeployErc4626StackError(error instanceof Error ? error : new Error(String(error)), { receipts: { ...receipts }, stage, state: { ...state } });
|
|
653
|
+
}
|
|
654
|
+
//# sourceMappingURL=deployment.js.map
|