@instadapp/interop-x 0.0.0-dev.5953f3d → 0.0.0-dev.5a90c8d
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/package.json +8 -1
- package/dist/src/abi/aaveV2Resolver.json +832 -0
- package/dist/src/abi/balanceResolver.json +211 -0
- package/dist/src/abi/index.js +6 -0
- package/dist/src/abi/instList.json +232 -0
- package/dist/src/api/index.js +7 -0
- package/dist/src/constants/addresses.js +8 -2
- package/dist/src/constants/capPerChain.js +8 -0
- package/dist/src/constants/index.js +2 -0
- package/dist/src/constants/tokens.js +44 -44
- package/dist/src/constants/wrappedNativeToken.js +8 -0
- package/dist/src/crons/index.js +3 -0
- package/dist/src/crons/prices.js +16 -0
- package/dist/src/db/models/transaction.js +15 -7
- package/dist/src/errors/index.js +30 -0
- package/dist/src/gnosis/actions/aaveV2/source.js +17 -5
- package/dist/src/gnosis/actions/aaveV2/target.js +79 -0
- package/dist/src/index.js +2 -1
- package/dist/src/providers/index.js +17 -0
- package/dist/src/providers/retry-provider.js +45 -0
- package/dist/src/services/Prices.js +74 -0
- package/dist/src/services/index.js +8 -0
- package/dist/src/tasks/InteropX/{ProcessSubmitSubmitEvents.js → ProcessSubmitEvents.js} +84 -7
- package/dist/src/tasks/InteropX/ProcessValidateEvents.js +185 -0
- package/dist/src/tasks/InteropX/SyncLogExecuteEvents.js +113 -0
- package/dist/src/tasks/InteropX/SyncLogSubmitEvents.js +3 -1
- package/dist/src/tasks/InteropX/SyncLogValidateEvents.js +106 -0
- package/dist/src/tasks/index.js +13 -5
- package/dist/src/typechain/AaveV2Resolver.js +2 -0
- package/dist/src/typechain/BalanceResolver.js +2 -0
- package/dist/src/typechain/InstList.js +2 -0
- package/dist/src/typechain/factories/AaveV2Resolver__factory.js +1191 -0
- package/dist/src/typechain/factories/BalanceResolver__factory.js +228 -0
- package/dist/src/typechain/factories/InstList__factory.js +249 -0
- package/dist/src/typechain/factories/index.js +7 -1
- package/dist/src/typechain/index.js +7 -1
- package/dist/src/utils/async.js +18 -0
- package/dist/src/utils/dsa.js +24 -0
- package/dist/src/utils/formatting.js +67 -0
- package/dist/src/utils/gnosis.js +62 -0
- package/dist/src/utils/http.js +10 -0
- package/dist/src/utils/index.js +22 -220
- package/dist/src/utils/interop.js +16 -0
- package/dist/src/utils/tokens.js +22 -0
- package/dist/src/utils/validate.js +111 -0
- package/dist/src/utils/web3.js +93 -0
- package/package.json +8 -1
- package/src/abi/aaveV2Resolver.json +832 -0
- package/src/abi/balanceResolver.json +211 -0
- package/src/abi/index.ts +6 -0
- package/src/abi/instList.json +232 -0
- package/src/api/index.ts +8 -0
- package/src/constants/addresses.ts +19 -3
- package/src/constants/capPerChain.ts +5 -0
- package/src/constants/index.ts +2 -0
- package/src/constants/tokens.ts +44 -44
- package/src/constants/wrappedNativeToken.ts +5 -0
- package/src/crons/index.ts +1 -0
- package/src/crons/prices.ts +12 -0
- package/src/db/models/transaction.ts +134 -80
- package/src/errors/index.ts +26 -0
- package/src/gnosis/actions/aaveV2/source.ts +21 -6
- package/src/gnosis/actions/aaveV2/target.ts +131 -2
- package/src/index.ts +1 -0
- package/src/providers/index.ts +1 -0
- package/src/providers/retry-provider.ts +51 -0
- package/src/services/Prices.ts +89 -0
- package/src/services/index.ts +1 -0
- package/src/tasks/InteropX/{ProcessSubmitSubmitEvents.ts → ProcessSubmitEvents.ts} +104 -11
- package/src/tasks/InteropX/ProcessValidateEvents.ts +272 -0
- package/src/tasks/InteropX/SyncLogExecuteEvents.ts +161 -0
- package/src/tasks/InteropX/SyncLogSubmitEvents.ts +6 -6
- package/src/tasks/InteropX/SyncLogValidateEvents.ts +151 -0
- package/src/tasks/index.ts +16 -5
- package/src/typechain/AaveV2Resolver.ts +1017 -0
- package/src/typechain/BalanceResolver.ts +266 -0
- package/src/typechain/InstList.ts +402 -0
- package/src/typechain/factories/AaveV2Resolver__factory.ts +1198 -0
- package/src/typechain/factories/BalanceResolver__factory.ts +235 -0
- package/src/typechain/factories/InstList__factory.ts +253 -0
- package/src/typechain/factories/index.ts +3 -0
- package/src/typechain/index.ts +6 -0
- package/src/utils/async.ts +22 -0
- package/src/utils/dsa.ts +30 -0
- package/src/utils/formatting.ts +68 -0
- package/src/utils/gnosis.ts +123 -0
- package/src/utils/http.ts +6 -0
- package/src/utils/index.ts +9 -365
- package/src/utils/interop.ts +28 -0
- package/src/utils/tokens.ts +21 -0
- package/src/utils/validate.ts +174 -0
- package/src/utils/web3.ts +132 -0
@@ -5,12 +5,16 @@ import abi from "@/abi";
|
|
5
5
|
import { Transaction } from "@/db";
|
6
6
|
import {
|
7
7
|
buildSignatureBytes,
|
8
|
+
chainIdToName,
|
8
9
|
generateGnosisTransaction,
|
9
|
-
|
10
|
+
getChainIdNativeSymbol,
|
10
11
|
getContract,
|
12
|
+
getExplorerUrl,
|
11
13
|
getRpcProviderUrl,
|
12
|
-
LiquidityError,
|
13
14
|
Signature,
|
15
|
+
validateChains,
|
16
|
+
validateLiquidityCap,
|
17
|
+
validateSourceLiquidity,
|
14
18
|
} from "@/utils";
|
15
19
|
import { addresses, blockConfirmations } from "@/constants";
|
16
20
|
import { ChainId } from "@/types";
|
@@ -22,9 +26,13 @@ import { buildGnosisAction } from "@/gnosis";
|
|
22
26
|
import { peerPool, protocol } from "@/net";
|
23
27
|
import { LogDescription } from "ethers/lib/utils";
|
24
28
|
import wait from "waait";
|
29
|
+
import { LiquidityError, UnsupportedChaindIdError } from "@/errors";
|
30
|
+
import { BigNumber } from "bignumber.js";
|
31
|
+
import dedent from "dedent";
|
32
|
+
import { JsonRpcRetryProvider } from "@/providers";
|
25
33
|
|
26
|
-
class
|
27
|
-
sourceProvider:
|
34
|
+
export default class ProcessSubmitEvents extends BaseTask {
|
35
|
+
sourceProvider: JsonRpcRetryProvider;
|
28
36
|
sourceGnosisContract: GnosisSafe;
|
29
37
|
sourceWallet: Wallet;
|
30
38
|
chainId: ChainId;
|
@@ -33,7 +41,7 @@ class ProcessSubmitSubmitEvents extends BaseTask {
|
|
33
41
|
|
34
42
|
constructor({ chainId }: { chainId: ChainId }) {
|
35
43
|
super({
|
36
|
-
logger: new Logger("InteropX::
|
44
|
+
logger: new Logger("InteropX::ProcessSubmitEvents"),
|
37
45
|
});
|
38
46
|
this.chainId = chainId;
|
39
47
|
}
|
@@ -68,12 +76,86 @@ class ProcessSubmitSubmitEvents extends BaseTask {
|
|
68
76
|
return;
|
69
77
|
}
|
70
78
|
|
79
|
+
this.logger.debug(`Processing transaction ${transaction.transactionHash}`);
|
80
|
+
|
71
81
|
transaction.sourceStatus = "proccessing";
|
72
82
|
await transaction.save();
|
73
83
|
|
84
|
+
const { submitEvent: { position, sourceChainId, targetChainId } } = transaction;
|
85
|
+
try {
|
86
|
+
validateChains({ sourceChainId, targetChainId });
|
87
|
+
} catch (error) {
|
88
|
+
transaction.sourceErrors = [error.message];
|
89
|
+
transaction.sourceStatus = "failed";
|
90
|
+
transaction.targetStatus = "failed";
|
91
|
+
transaction.status = "failed";
|
92
|
+
await transaction.save();
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
|
96
|
+
const walletBalance = (await this.sourceWallet.getBalance()).toString();
|
97
|
+
const currentGasPrice = (await this.sourceWallet.getGasPrice()).toString()
|
98
|
+
|
99
|
+
const minBalanceRequired = new BigNumber(currentGasPrice)
|
100
|
+
.multipliedBy(4_000_000)
|
101
|
+
.multipliedBy(2) // 2x balance
|
102
|
+
|
103
|
+
if (
|
104
|
+
new BigNumber(walletBalance).isLessThan(minBalanceRequired)
|
105
|
+
) {
|
106
|
+
console.log(
|
107
|
+
dedent`Not enough balance in wallet ${getExplorerUrl(sourceChainId, '/address/' + this.sourceWallet.address)} on ${chainIdToName(sourceChainId)}
|
108
|
+
Balance: ${ethers.utils.parseEther(walletBalance)} ${getChainIdNativeSymbol(sourceChainId)}
|
109
|
+
Required Balance: ${ethers.utils.parseEther(minBalanceRequired.toString())}
|
110
|
+
Require more: ${ethers.utils.parseEther(minBalanceRequired.minus(walletBalance).toString())}`
|
111
|
+
);
|
112
|
+
transaction.sourceDelayUntil = moment().add({ minutes: 5 }).toDate();
|
113
|
+
transaction.sourceStatus = "pending";
|
114
|
+
await transaction.save();
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
|
118
|
+
try {
|
119
|
+
await validateLiquidityCap(position, sourceChainId, targetChainId);
|
120
|
+
} catch (error) {
|
121
|
+
transaction.sourceErrors = [error.message];
|
122
|
+
transaction.sourceStatus = "failed";
|
123
|
+
transaction.targetStatus = "failed";
|
124
|
+
transaction.status = "failed";
|
125
|
+
await transaction.save();
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
|
129
|
+
try {
|
130
|
+
await validateSourceLiquidity({
|
131
|
+
position,
|
132
|
+
sourceChainId,
|
133
|
+
sourceProvider: this.sourceProvider,
|
134
|
+
});
|
135
|
+
} catch (error) {
|
136
|
+
if (error instanceof UnsupportedChaindIdError) {
|
137
|
+
console.log(`Dropping transaction ${transaction.transactionHash}`);
|
138
|
+
|
139
|
+
transaction.sourceErrors = [error.message];
|
140
|
+
transaction.sourceStatus = "failed";
|
141
|
+
transaction.targetStatus = "failed";
|
142
|
+
transaction.status = "failed";
|
143
|
+
await transaction.save();
|
144
|
+
} else {
|
145
|
+
transaction.sourceStatus = "pending";
|
146
|
+
transaction.sourceDelayUntil = moment().add({ minutes: 5 }).toDate();
|
147
|
+
await transaction.save();
|
148
|
+
|
149
|
+
console.log("[validateSourceLiquidity][Warning]", error.message);
|
150
|
+
return;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
74
154
|
const ownersThreshold = await this.sourceGnosisContract.getThreshold();
|
75
155
|
await wait(10000);
|
76
156
|
|
157
|
+
this.logger.debug(`Build gnosis action for ${transaction.transactionHash}`);
|
158
|
+
|
77
159
|
let data,
|
78
160
|
logs = [];
|
79
161
|
|
@@ -101,6 +183,10 @@ class ProcessSubmitSubmitEvents extends BaseTask {
|
|
101
183
|
return;
|
102
184
|
}
|
103
185
|
|
186
|
+
this.logger.debug(
|
187
|
+
`Generating gnosis tx for ${transaction.transactionHash}`
|
188
|
+
);
|
189
|
+
|
104
190
|
let gnosisTx = await generateGnosisTransaction(
|
105
191
|
{
|
106
192
|
baseGas: "0",
|
@@ -186,10 +272,20 @@ class ProcessSubmitSubmitEvents extends BaseTask {
|
|
186
272
|
buildSignatureBytes(validSignatures)
|
187
273
|
);
|
188
274
|
|
275
|
+
const [gasPrice, gasLimit] = await Promise.all([
|
276
|
+
this.sourceProvider.getGasPrice(),
|
277
|
+
this.sourceProvider.estimateGas({
|
278
|
+
from: this.sourceWallet.address,
|
279
|
+
to: this.sourceGnosisContract.address,
|
280
|
+
data: txData,
|
281
|
+
}),
|
282
|
+
]);
|
283
|
+
|
189
284
|
const txSent = await this.sourceWallet.sendTransaction({
|
190
285
|
from: this.sourceWallet.address,
|
191
|
-
gasPrice: ethers.BigNumber.from(120 * 10 ** 9),
|
192
286
|
to: this.sourceGnosisContract.address,
|
287
|
+
gasPrice: gasPrice.mul(120).div(100),
|
288
|
+
gasLimit: 5_000_000,//gasLimit.mul(120).div(100),
|
193
289
|
data: txData,
|
194
290
|
});
|
195
291
|
|
@@ -202,7 +298,7 @@ class ProcessSubmitSubmitEvents extends BaseTask {
|
|
202
298
|
receipt.logs.forEach((log) => {
|
203
299
|
try {
|
204
300
|
parsedLogs.push(this.sourceGnosisContract.interface.parseLog(log));
|
205
|
-
} catch (e) {}
|
301
|
+
} catch (e) { }
|
206
302
|
});
|
207
303
|
|
208
304
|
if (parsedLogs.find((e) => e.name === "ExecutionSuccess")) {
|
@@ -219,7 +315,6 @@ class ProcessSubmitSubmitEvents extends BaseTask {
|
|
219
315
|
if (txSent.blockNumber)
|
220
316
|
transaction.sourceBlockNumber = txSent.blockNumber;
|
221
317
|
transaction.sourceTransactionHash = txSent.hash;
|
222
|
-
transaction.sourceTransactionHash = txSent.hash;
|
223
318
|
transaction.status = "failed";
|
224
319
|
await transaction.save();
|
225
320
|
}
|
@@ -230,7 +325,7 @@ class ProcessSubmitSubmitEvents extends BaseTask {
|
|
230
325
|
async start(): Promise<void> {
|
231
326
|
this.blockConfirmationsCount = blockConfirmations[this.chainId] + 1;
|
232
327
|
|
233
|
-
this.sourceProvider = new
|
328
|
+
this.sourceProvider = new JsonRpcRetryProvider(
|
234
329
|
getRpcProviderUrl(this.chainId)
|
235
330
|
);
|
236
331
|
|
@@ -248,5 +343,3 @@ class ProcessSubmitSubmitEvents extends BaseTask {
|
|
248
343
|
await super.start();
|
249
344
|
}
|
250
345
|
}
|
251
|
-
|
252
|
-
export default ProcessSubmitSubmitEvents;
|
@@ -0,0 +1,272 @@
|
|
1
|
+
import { BaseTask } from "../BaseTask";
|
2
|
+
import Logger from "@/logger";
|
3
|
+
import { ethers, Wallet } from "ethers";
|
4
|
+
import abi from "@/abi";
|
5
|
+
import { Transaction } from "@/db";
|
6
|
+
import {
|
7
|
+
buildSignatureBytes,
|
8
|
+
generateGnosisTransaction,
|
9
|
+
getContract,
|
10
|
+
getRpcProviderUrl,
|
11
|
+
Signature,
|
12
|
+
} from "@/utils";
|
13
|
+
import { addresses, blockConfirmations } from "@/constants";
|
14
|
+
import { ChainId } from "@/types";
|
15
|
+
import config from "@/config";
|
16
|
+
import { GnosisSafe, InteropX } from "@/typechain";
|
17
|
+
import moment from "moment";
|
18
|
+
import { Op } from "sequelize";
|
19
|
+
import { buildGnosisAction } from "@/gnosis";
|
20
|
+
import { peerPool, protocol } from "@/net";
|
21
|
+
import { LogDescription } from "ethers/lib/utils";
|
22
|
+
import wait from "waait";
|
23
|
+
import { LiquidityError } from "@/errors";
|
24
|
+
import { JsonRpcRetryProvider } from "@/providers";
|
25
|
+
|
26
|
+
export default class ProcessValidateEvents extends BaseTask {
|
27
|
+
sourceProvider: JsonRpcRetryProvider;
|
28
|
+
chainId: ChainId;
|
29
|
+
leadNodeOnly: boolean = true;
|
30
|
+
blockConfirmationsCount: number = 12;
|
31
|
+
|
32
|
+
constructor({ chainId }: { chainId: ChainId }) {
|
33
|
+
super({
|
34
|
+
logger: new Logger("InteropX::ProcessValidateEvents"),
|
35
|
+
});
|
36
|
+
this.chainId = chainId;
|
37
|
+
}
|
38
|
+
|
39
|
+
async pollHandler() {
|
40
|
+
const currentBlockNumber = await this.sourceProvider.getBlockNumber();
|
41
|
+
|
42
|
+
const transaction = await Transaction.findOne({
|
43
|
+
where: {
|
44
|
+
status: "pending",
|
45
|
+
sourceStatus: "success",
|
46
|
+
targetStatus: "pending",
|
47
|
+
sourceChainId: this.chainId,
|
48
|
+
sourceBlockNumber: {
|
49
|
+
[Op.lt]: currentBlockNumber - this.blockConfirmationsCount,
|
50
|
+
},
|
51
|
+
targetDelayUntil: {
|
52
|
+
[Op.or]: {
|
53
|
+
[Op.is]: null,
|
54
|
+
[Op.lt]: new Date(),
|
55
|
+
},
|
56
|
+
},
|
57
|
+
|
58
|
+
submitEvent: { $ne: null },
|
59
|
+
validateEvent: { $ne: null },
|
60
|
+
|
61
|
+
createdAt: {
|
62
|
+
[Op.gt]: moment().subtract({ hours: 12 }).toDate(),
|
63
|
+
},
|
64
|
+
},
|
65
|
+
});
|
66
|
+
|
67
|
+
if (!transaction) {
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
|
71
|
+
this.logger.debug(`Processing transaction ${transaction.transactionHash}`);
|
72
|
+
|
73
|
+
transaction.targetStatus = "proccessing";
|
74
|
+
await transaction.save();
|
75
|
+
|
76
|
+
const { sourceChainId, targetChainId } = transaction.validateEvent
|
77
|
+
|
78
|
+
const targetProvider = new JsonRpcRetryProvider(
|
79
|
+
getRpcProviderUrl(targetChainId as ChainId)
|
80
|
+
);
|
81
|
+
|
82
|
+
const targetWallet = new ethers.Wallet(
|
83
|
+
config.privateKey!,
|
84
|
+
targetProvider
|
85
|
+
);
|
86
|
+
|
87
|
+
const targetGnosisContract = getContract<GnosisSafe>(
|
88
|
+
addresses[targetChainId].gnosisSafe,
|
89
|
+
abi.gnosisSafe,
|
90
|
+
targetWallet
|
91
|
+
);
|
92
|
+
|
93
|
+
const ownersThreshold = await targetGnosisContract.getThreshold();
|
94
|
+
await wait(10000);
|
95
|
+
|
96
|
+
this.logger.debug(`Build gnosis action for ${transaction.transactionHash}`);
|
97
|
+
|
98
|
+
let data,
|
99
|
+
logs = [];
|
100
|
+
|
101
|
+
try {
|
102
|
+
({ data, logs } = await buildGnosisAction(transaction, "target"));
|
103
|
+
} catch (error) {
|
104
|
+
if (error instanceof LiquidityError) {
|
105
|
+
await transaction.save();
|
106
|
+
transaction.targetDelayUntil = new Date(Date.now() + 60 * 5 * 1000);
|
107
|
+
transaction.targetStatus = "pending";
|
108
|
+
|
109
|
+
await transaction.save();
|
110
|
+
|
111
|
+
throw error;
|
112
|
+
return;
|
113
|
+
}
|
114
|
+
|
115
|
+
transaction.targetStatus = "failed";
|
116
|
+
transaction.targetErrors = [error.message];
|
117
|
+
transaction.status = "failed";
|
118
|
+
await transaction.save();
|
119
|
+
protocol.sendTransaction(transaction);
|
120
|
+
return;
|
121
|
+
}
|
122
|
+
|
123
|
+
this.logger.debug(
|
124
|
+
`Generating gnosis tx for ${transaction.transactionHash}`
|
125
|
+
);
|
126
|
+
|
127
|
+
let gnosisTx = await generateGnosisTransaction(
|
128
|
+
{
|
129
|
+
baseGas: "0",
|
130
|
+
data,
|
131
|
+
gasPrice: "0",
|
132
|
+
gasToken: "0x0000000000000000000000000000000000000000",
|
133
|
+
nonce: "0",
|
134
|
+
operation: "1",
|
135
|
+
refundReceiver: "0x0000000000000000000000000000000000000000",
|
136
|
+
safeAddress: targetGnosisContract.address,
|
137
|
+
safeTxGas: "79668",
|
138
|
+
to: addresses[transaction.targetChainId].multisend,
|
139
|
+
value: "0",
|
140
|
+
},
|
141
|
+
targetGnosisContract
|
142
|
+
);
|
143
|
+
|
144
|
+
const owners = await targetGnosisContract
|
145
|
+
.getOwners()
|
146
|
+
.then((owners) => owners.map((owner) => owner.toLowerCase()));
|
147
|
+
|
148
|
+
const ownerPeerIds = peerPool.activePeers
|
149
|
+
.filter((peer) => owners.includes(peer.publicAddress.toLowerCase()))
|
150
|
+
.map((peer) => peer.id);
|
151
|
+
|
152
|
+
console.log(
|
153
|
+
`Collecting signatures for execution ${transaction.transactionHash}`
|
154
|
+
);
|
155
|
+
|
156
|
+
console.log(ownerPeerIds);
|
157
|
+
|
158
|
+
const signatures = await protocol.requestSignatures(
|
159
|
+
{
|
160
|
+
type: "target",
|
161
|
+
transactionHash: transaction.transactionHash,
|
162
|
+
safeTxGas: gnosisTx.safeTxGas,
|
163
|
+
safeNonce: gnosisTx.nonce,
|
164
|
+
chainId: targetChainId,
|
165
|
+
},
|
166
|
+
ownerPeerIds
|
167
|
+
);
|
168
|
+
|
169
|
+
const validSignatures = signatures.filter(
|
170
|
+
(s) => !!s.data && s.data !== "0x"
|
171
|
+
) as Signature[];
|
172
|
+
|
173
|
+
console.log({
|
174
|
+
signatures,
|
175
|
+
validSignatures,
|
176
|
+
ownersThreshold: ownersThreshold.toString(),
|
177
|
+
});
|
178
|
+
|
179
|
+
if (
|
180
|
+
validSignatures.length === 0 ||
|
181
|
+
ownersThreshold.gt(validSignatures.length)
|
182
|
+
) {
|
183
|
+
await transaction.save();
|
184
|
+
transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
|
185
|
+
transaction.targetStatus = "pending";
|
186
|
+
|
187
|
+
await transaction.save();
|
188
|
+
const errorMessage = signatures.find((s) => !!s.error)?.error;
|
189
|
+
throw new Error(
|
190
|
+
`Not enough signatures` + (errorMessage ? `: ${errorMessage}` : "")
|
191
|
+
);
|
192
|
+
}
|
193
|
+
|
194
|
+
console.log(
|
195
|
+
`Executing transaction for execution ${transaction.transactionHash}`
|
196
|
+
);
|
197
|
+
|
198
|
+
const { data: txData } =
|
199
|
+
await targetGnosisContract.populateTransaction.execTransaction(
|
200
|
+
gnosisTx.to,
|
201
|
+
gnosisTx.value,
|
202
|
+
gnosisTx.data,
|
203
|
+
gnosisTx.operation,
|
204
|
+
gnosisTx.safeTxGas,
|
205
|
+
gnosisTx.baseGas,
|
206
|
+
gnosisTx.gasPrice,
|
207
|
+
gnosisTx.gasToken,
|
208
|
+
gnosisTx.refundReceiver,
|
209
|
+
buildSignatureBytes(validSignatures)
|
210
|
+
);
|
211
|
+
|
212
|
+
const [gasPrice, gasLimit] = await Promise.all([
|
213
|
+
targetProvider.getGasPrice(),
|
214
|
+
targetProvider.estimateGas({
|
215
|
+
from: targetWallet.address,
|
216
|
+
to: targetGnosisContract.address,
|
217
|
+
data: txData,
|
218
|
+
}),
|
219
|
+
]);
|
220
|
+
|
221
|
+
const txSent = await targetWallet.sendTransaction({
|
222
|
+
from: targetWallet.address,
|
223
|
+
to: targetGnosisContract.address,
|
224
|
+
gasPrice: gasPrice.mul(120).div(100),
|
225
|
+
gasLimit: 5_000_000,//gasLimit.mul(120).div(100),
|
226
|
+
data: txData,
|
227
|
+
});
|
228
|
+
|
229
|
+
console.log(txSent);
|
230
|
+
|
231
|
+
const receipt = await txSent.wait();
|
232
|
+
|
233
|
+
const parsedLogs: LogDescription[] = [];
|
234
|
+
|
235
|
+
receipt.logs.forEach((log) => {
|
236
|
+
try {
|
237
|
+
parsedLogs.push(targetGnosisContract.interface.parseLog(log));
|
238
|
+
} catch (e) { }
|
239
|
+
});
|
240
|
+
|
241
|
+
if (parsedLogs.find((e) => e.name === "ExecutionSuccess")) {
|
242
|
+
console.log("ExecutionSuccess");
|
243
|
+
transaction.targetStatus = "success";
|
244
|
+
transaction.status = "success";
|
245
|
+
if (txSent.blockNumber)
|
246
|
+
transaction.targetBlockNumber = txSent.blockNumber;
|
247
|
+
transaction.targetTransactionHash = txSent.hash;
|
248
|
+
transaction.targetLogs = logs;
|
249
|
+
await transaction.save();
|
250
|
+
} else {
|
251
|
+
console.log("ExecutionFailure");
|
252
|
+
transaction.targetStatus = "failed";
|
253
|
+
if (txSent.blockNumber)
|
254
|
+
transaction.targetBlockNumber = txSent.blockNumber;
|
255
|
+
transaction.targetTransactionHash = txSent.hash;
|
256
|
+
transaction.status = "failed";
|
257
|
+
await transaction.save();
|
258
|
+
}
|
259
|
+
|
260
|
+
protocol.sendTransaction(transaction);
|
261
|
+
}
|
262
|
+
|
263
|
+
async start(): Promise<void> {
|
264
|
+
this.blockConfirmationsCount = blockConfirmations[this.chainId] + 1;
|
265
|
+
|
266
|
+
this.sourceProvider = new JsonRpcRetryProvider(
|
267
|
+
getRpcProviderUrl(this.chainId)
|
268
|
+
);
|
269
|
+
|
270
|
+
await super.start();
|
271
|
+
}
|
272
|
+
}
|
@@ -0,0 +1,161 @@
|
|
1
|
+
import { BaseTask } from "../BaseTask";
|
2
|
+
import Logger from "@/logger";
|
3
|
+
import { ethers } from "ethers";
|
4
|
+
import abi from "@/abi";
|
5
|
+
import { Transaction } from "@/db";
|
6
|
+
import {
|
7
|
+
generateInteropTransactionHash,
|
8
|
+
getContract,
|
9
|
+
getRpcProviderUrl,
|
10
|
+
} from "@/utils";
|
11
|
+
import { addresses } from "@/constants";
|
12
|
+
import { ChainId } from "@/types";
|
13
|
+
import config from "@/config";
|
14
|
+
import { InteropX } from "@/typechain";
|
15
|
+
import { Op } from "sequelize";
|
16
|
+
import { JsonRpcRetryProvider } from "@/providers";
|
17
|
+
|
18
|
+
export default class SyncLogExecuteEvents extends BaseTask {
|
19
|
+
contractAddress: string;
|
20
|
+
provider: JsonRpcRetryProvider;
|
21
|
+
contract: InteropX;
|
22
|
+
targetChainId: ChainId;
|
23
|
+
|
24
|
+
constructor({ targetChainId }: { targetChainId: ChainId }) {
|
25
|
+
super({
|
26
|
+
logger: new Logger("InteropX::SyncLogExecuteEvents"),
|
27
|
+
});
|
28
|
+
this.targetChainId = targetChainId;
|
29
|
+
}
|
30
|
+
|
31
|
+
async pollHandler() {
|
32
|
+
const currentBlock = await this.provider.getBlockNumber();
|
33
|
+
|
34
|
+
const events = await this.contract.queryFilter(
|
35
|
+
this.contract.filters.LogExecute(),
|
36
|
+
currentBlock - 2000,
|
37
|
+
currentBlock
|
38
|
+
);
|
39
|
+
|
40
|
+
let processedEvents = 0;
|
41
|
+
|
42
|
+
for (const event of events) {
|
43
|
+
try {
|
44
|
+
if (!event.args) {
|
45
|
+
continue;
|
46
|
+
}
|
47
|
+
|
48
|
+
const {
|
49
|
+
sourceSpells,
|
50
|
+
targetSpells,
|
51
|
+
position,
|
52
|
+
actionId,
|
53
|
+
actionIdHash,
|
54
|
+
sourceSender,
|
55
|
+
sourceDsaId,
|
56
|
+
targetDsaId,
|
57
|
+
sourceChainId,
|
58
|
+
targetChainId,
|
59
|
+
vnonce,
|
60
|
+
metadata,
|
61
|
+
} = event.args;
|
62
|
+
|
63
|
+
const uniqueIdentifier = {
|
64
|
+
actionId,
|
65
|
+
vnonce: vnonce.toString(),
|
66
|
+
sourceSender: sourceSender.toString(),
|
67
|
+
sourceChainId: sourceChainId.toNumber(),
|
68
|
+
targetChainId: targetChainId.toNumber(),
|
69
|
+
sourceDsaId: sourceDsaId.toString(),
|
70
|
+
targetDsaId: targetDsaId.toString(),
|
71
|
+
};
|
72
|
+
|
73
|
+
let transactionHash = generateInteropTransactionHash(uniqueIdentifier);
|
74
|
+
|
75
|
+
const transaction = await Transaction.findOne({
|
76
|
+
where: {
|
77
|
+
transactionHash,
|
78
|
+
executeEvent: { [Op.eq]: null },
|
79
|
+
},
|
80
|
+
});
|
81
|
+
|
82
|
+
if (!transaction) {
|
83
|
+
continue;
|
84
|
+
}
|
85
|
+
|
86
|
+
if (transaction.targetStatus != "success") {
|
87
|
+
transaction.targetStatus = "success";
|
88
|
+
}
|
89
|
+
|
90
|
+
if (transaction.status != "success") {
|
91
|
+
transaction.status = "success";
|
92
|
+
}
|
93
|
+
|
94
|
+
if (!transaction.targetCreatedAt) {
|
95
|
+
transaction.targetCreatedAt = new Date();
|
96
|
+
}
|
97
|
+
|
98
|
+
transaction.targetTransactionHash = event.transactionHash;
|
99
|
+
transaction.targetBlockNumber = event.blockNumber;
|
100
|
+
transaction.targetLogs = [];
|
101
|
+
transaction.executeEvent = {
|
102
|
+
actionId,
|
103
|
+
actionIdHashHash: actionIdHash,
|
104
|
+
actionIdHash,
|
105
|
+
vnonce: vnonce.toString(),
|
106
|
+
sourceSpells: sourceSpells.map(({ connector, data }) => ({
|
107
|
+
connector,
|
108
|
+
data,
|
109
|
+
})),
|
110
|
+
targetSpells: targetSpells.map(({ connector, data }) => ({
|
111
|
+
connector,
|
112
|
+
data,
|
113
|
+
})),
|
114
|
+
position: {
|
115
|
+
withdraw: position.withdraw.map((v) => ({
|
116
|
+
sourceToken: v.sourceToken,
|
117
|
+
targetToken: v.targetToken,
|
118
|
+
amount: v.amount.toString(),
|
119
|
+
})),
|
120
|
+
supply: position.supply.map((v) => ({
|
121
|
+
sourceToken: v.sourceToken,
|
122
|
+
targetToken: v.targetToken,
|
123
|
+
amount: v.amount.toString(),
|
124
|
+
})),
|
125
|
+
},
|
126
|
+
sourceChainId: sourceChainId.toNumber(),
|
127
|
+
targetChainId: targetChainId.toNumber(),
|
128
|
+
sourceSender,
|
129
|
+
sourceDsaId: sourceDsaId.toString(),
|
130
|
+
targetDsaId: targetDsaId.toString(),
|
131
|
+
metadata,
|
132
|
+
};
|
133
|
+
|
134
|
+
await transaction.save();
|
135
|
+
|
136
|
+
this.logger.info(`New InteropX tranaction: ${transactionHash} `);
|
137
|
+
} catch (error) {
|
138
|
+
this.logger.error(error);
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
if (processedEvents > 0)
|
143
|
+
this.logger.info(`${processedEvents} events processed`);
|
144
|
+
}
|
145
|
+
|
146
|
+
async start(): Promise<void> {
|
147
|
+
this.contractAddress = addresses[this.targetChainId].interopX;
|
148
|
+
|
149
|
+
this.provider = new JsonRpcRetryProvider(
|
150
|
+
getRpcProviderUrl(this.targetChainId)
|
151
|
+
);
|
152
|
+
|
153
|
+
this.contract = getContract<InteropX>(
|
154
|
+
this.contractAddress,
|
155
|
+
abi.interopX,
|
156
|
+
new ethers.Wallet(config.privateKey!, this.provider)
|
157
|
+
);
|
158
|
+
|
159
|
+
await super.start();
|
160
|
+
}
|
161
|
+
}
|
@@ -12,10 +12,11 @@ import { addresses } from "@/constants";
|
|
12
12
|
import { ChainId } from "@/types";
|
13
13
|
import config from "@/config";
|
14
14
|
import { InteropX } from "@/typechain";
|
15
|
+
import { JsonRpcRetryProvider } from "@/providers";
|
15
16
|
|
16
|
-
class SyncLogSubmitEvents extends BaseTask {
|
17
|
+
export default class SyncLogSubmitEvents extends BaseTask {
|
17
18
|
contractAddress: string;
|
18
|
-
provider:
|
19
|
+
provider: JsonRpcRetryProvider;
|
19
20
|
contract: InteropX;
|
20
21
|
chainId: ChainId;
|
21
22
|
|
@@ -86,6 +87,7 @@ class SyncLogSubmitEvents extends BaseTask {
|
|
86
87
|
submitEvent: {
|
87
88
|
actionId,
|
88
89
|
actionIdHashHash,
|
90
|
+
actionIdHash: actionIdHashHash,
|
89
91
|
vnonce: vnonce.toString(),
|
90
92
|
position: {
|
91
93
|
withdraw: position.withdraw.map((v) => ({
|
@@ -121,7 +123,7 @@ class SyncLogSubmitEvents extends BaseTask {
|
|
121
123
|
async start(): Promise<void> {
|
122
124
|
this.contractAddress = addresses[this.chainId].interopX;
|
123
125
|
|
124
|
-
this.provider = new
|
126
|
+
this.provider = new JsonRpcRetryProvider(
|
125
127
|
getRpcProviderUrl(this.chainId)
|
126
128
|
);
|
127
129
|
|
@@ -133,6 +135,4 @@ class SyncLogSubmitEvents extends BaseTask {
|
|
133
135
|
|
134
136
|
await super.start();
|
135
137
|
}
|
136
|
-
}
|
137
|
-
|
138
|
-
export default SyncLogSubmitEvents;
|
138
|
+
}
|