@instadapp/interop-x 0.0.0-dev.1abc1ca → 0.0.0-dev.2c0a756
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/bin/interop-x +1 -1
- package/dist/package.json +9 -5
- package/dist/src/abi/interopBridgeToken.json +21 -9
- package/dist/src/abi/interopXGateway.json +11 -11
- package/dist/src/api/index.js +3 -3
- package/dist/src/config/index.js +11 -1
- package/dist/src/constants/addresses.js +1 -1
- package/dist/src/constants/itokens.js +1 -1
- package/dist/src/index.js +69 -7
- package/dist/src/net/peer/index.js +8 -3
- package/dist/src/net/pool/index.js +32 -9
- package/dist/src/net/protocol/dial/SignatureDialProtocol.js +11 -4
- package/dist/src/net/protocol/dial/TransactionStatusDialProtocol.js +28 -0
- package/dist/src/net/protocol/index.js +41 -1
- package/dist/src/tasks/AutoUpdateTask.js +70 -0
- package/dist/src/tasks/BaseTask.js +12 -4
- package/dist/src/tasks/InteropBridge/ProcessWithdrawEvents.js +146 -0
- package/dist/src/tasks/InteropBridge/SyncBurnEvents.js +71 -0
- package/dist/src/tasks/InteropBridge/SyncMintEvents.js +66 -0
- package/dist/src/tasks/InteropXGateway/ProcessDepositEvents.js +45 -23
- package/dist/src/tasks/InteropXGateway/SyncDepositEvents.js +6 -7
- package/dist/src/tasks/InteropXGateway/SyncWithdrawtEvents.js +71 -0
- package/dist/src/tasks/Transactions/SyncTransactionStatusTask.js +53 -0
- package/dist/src/tasks/index.js +29 -0
- package/dist/src/typechain/factories/InteropBridgeToken__factory.js +23 -11
- package/dist/src/typechain/factories/InteropXGateway__factory.js +14 -14
- package/dist/src/utils/index.js +111 -10
- package/package.json +9 -5
- package/patches/@ethersproject+properties+5.6.0.patch +13 -0
- package/src/abi/interopBridgeToken.json +21 -9
- package/src/abi/interopXGateway.json +11 -11
- package/src/api/index.ts +2 -2
- package/src/config/index.ts +11 -1
- package/src/constants/addresses.ts +1 -1
- package/src/constants/itokens.ts +1 -1
- package/src/index.ts +90 -9
- package/src/net/peer/index.ts +9 -7
- package/src/net/pool/index.ts +41 -11
- package/src/net/protocol/dial/SignatureDialProtocol.ts +12 -4
- package/src/net/protocol/dial/TransactionStatusDialProtocol.ts +31 -0
- package/src/net/protocol/index.ts +57 -1
- package/src/tasks/AutoUpdateTask.ts +82 -0
- package/src/tasks/BaseTask.ts +14 -4
- package/src/tasks/InteropBridge/ProcessWithdrawEvents.ts +231 -0
- package/src/tasks/InteropBridge/SyncBurnEvents.ts +121 -0
- package/src/tasks/InteropBridge/SyncMintEvents.ts +98 -0
- package/src/tasks/InteropXGateway/ProcessDepositEvents.ts +57 -32
- package/src/tasks/InteropXGateway/SyncDepositEvents.ts +8 -10
- package/src/tasks/InteropXGateway/SyncWithdrawtEvents.ts +103 -0
- package/src/tasks/Transactions/SyncTransactionStatusTask.ts +65 -0
- package/src/tasks/index.ts +44 -2
- package/src/typechain/InteropBridgeToken.ts +23 -17
- package/src/typechain/InteropXGateway.ts +13 -13
- package/src/typechain/factories/InteropBridgeToken__factory.ts +23 -11
- package/src/typechain/factories/InteropXGateway__factory.ts +14 -14
- package/src/utils/index.ts +146 -12
@@ -0,0 +1,231 @@
|
|
1
|
+
import { BaseTask } from "../BaseTask";
|
2
|
+
import Logger from '@/logger';
|
3
|
+
import { BigNumber, ethers } from "ethers";
|
4
|
+
import abi from "@/abi";
|
5
|
+
import { Transaction } from "@/db";
|
6
|
+
import { buildDataForTransaction, buildSignatureBytes, getContract, getRpcProviderUrl, Signature } from "@/utils";
|
7
|
+
import { addresses } from "@/constants";
|
8
|
+
import { ChainId } from "@/types";
|
9
|
+
import config from "@/config";
|
10
|
+
import { GnosisSafe, InteropXGateway } from "@/typechain";
|
11
|
+
import { Op } from "sequelize";
|
12
|
+
import wait from "waait";
|
13
|
+
import { peerPool, protocol } from "@/net";
|
14
|
+
import { LogDescription } from "ethers/lib/utils";
|
15
|
+
|
16
|
+
const generateGnosisTransaction = async (transactionData: any, safeContract: GnosisSafe) => {
|
17
|
+
console.log(transactionData);
|
18
|
+
|
19
|
+
let isExecuted = await safeContract.dataHashes(
|
20
|
+
await safeContract.getTransactionHash(
|
21
|
+
transactionData.to,
|
22
|
+
transactionData.value,
|
23
|
+
transactionData.data,
|
24
|
+
transactionData.operation,
|
25
|
+
transactionData.safeTxGas,
|
26
|
+
transactionData.baseGas,
|
27
|
+
transactionData.gasPrice,
|
28
|
+
transactionData.gasToken,
|
29
|
+
transactionData.refundReceiver,
|
30
|
+
transactionData.nonce
|
31
|
+
)
|
32
|
+
)
|
33
|
+
|
34
|
+
while (isExecuted == 1) {
|
35
|
+
transactionData.safeTxGas = BigNumber.from(String(transactionData.safeTxGas)).add(1).toString()
|
36
|
+
|
37
|
+
isExecuted = await safeContract.dataHashes(
|
38
|
+
await safeContract.getTransactionHash(
|
39
|
+
transactionData.to,
|
40
|
+
transactionData.value,
|
41
|
+
transactionData.data,
|
42
|
+
transactionData.operation,
|
43
|
+
transactionData.safeTxGas,
|
44
|
+
transactionData.baseGas,
|
45
|
+
transactionData.gasPrice,
|
46
|
+
transactionData.gasToken,
|
47
|
+
transactionData.refundReceiver,
|
48
|
+
transactionData.nonce
|
49
|
+
)
|
50
|
+
)
|
51
|
+
}
|
52
|
+
|
53
|
+
return transactionData
|
54
|
+
}
|
55
|
+
|
56
|
+
class ProcessWithdrawEvents extends BaseTask {
|
57
|
+
provider: ethers.providers.JsonRpcProvider;
|
58
|
+
chainId: ChainId;
|
59
|
+
leadNodeOnly = true
|
60
|
+
|
61
|
+
constructor({ chainId }: { chainId: ChainId }) {
|
62
|
+
super({
|
63
|
+
logger: new Logger("InteropXGateway::ProcessWithdrawEvents"),
|
64
|
+
})
|
65
|
+
this.chainId = chainId;
|
66
|
+
}
|
67
|
+
|
68
|
+
async pollHandler() {
|
69
|
+
const blockNumber = await this.provider.getBlockNumber()
|
70
|
+
|
71
|
+
const transaction = await Transaction.findOne({
|
72
|
+
where: {
|
73
|
+
status: 'pending',
|
74
|
+
sourceStatus: 'success',
|
75
|
+
targetStatus: 'uninitialised',
|
76
|
+
action: 'withdraw',
|
77
|
+
sourceCreatedAt: {
|
78
|
+
[Op.gte]: new Date(Date.now() - 12 * 60 * 60 * 1000),
|
79
|
+
},
|
80
|
+
targetDelayUntil: {
|
81
|
+
[Op.or]: {
|
82
|
+
[Op.is]: null,
|
83
|
+
[Op.lt]: new Date(),
|
84
|
+
}
|
85
|
+
},
|
86
|
+
sourceBlockNumber: {
|
87
|
+
[Op.lt]: blockNumber - 12,
|
88
|
+
},
|
89
|
+
sourceChainId: this.chainId,
|
90
|
+
}
|
91
|
+
})
|
92
|
+
|
93
|
+
if (!transaction) {
|
94
|
+
return;
|
95
|
+
}
|
96
|
+
|
97
|
+
console.log(`Processing transaction ${transaction.transactionHash}`);
|
98
|
+
|
99
|
+
transaction.targetStatus = 'pending';
|
100
|
+
await transaction.save();
|
101
|
+
|
102
|
+
// refresh event data?
|
103
|
+
|
104
|
+
const targetChainProvider = new ethers.providers.JsonRpcProvider(
|
105
|
+
getRpcProviderUrl(transaction.targetChainId as ChainId)
|
106
|
+
);
|
107
|
+
|
108
|
+
const targetWallet = new ethers.Wallet(config.privateKey!, targetChainProvider);
|
109
|
+
|
110
|
+
const safeAddress = addresses[transaction.targetChainId].gnosisSafe;
|
111
|
+
|
112
|
+
|
113
|
+
const safeContract = getContract<GnosisSafe>(
|
114
|
+
safeAddress,
|
115
|
+
abi.gnosisSafe,
|
116
|
+
targetWallet
|
117
|
+
)
|
118
|
+
|
119
|
+
const ownersThreshold = await safeContract.getThreshold();
|
120
|
+
await wait(10000);
|
121
|
+
|
122
|
+
let gnosisTx = await generateGnosisTransaction({
|
123
|
+
baseGas: "0",
|
124
|
+
data: await buildDataForTransaction(transaction),
|
125
|
+
gasPrice: "0",
|
126
|
+
gasToken: "0x0000000000000000000000000000000000000000",
|
127
|
+
nonce: '0',
|
128
|
+
operation: "1",
|
129
|
+
refundReceiver: "0x0000000000000000000000000000000000000000",
|
130
|
+
safeAddress: safeAddress,
|
131
|
+
safeTxGas: "79668",
|
132
|
+
to: addresses[transaction.targetChainId].multisend,
|
133
|
+
value: "0",
|
134
|
+
}, safeContract);
|
135
|
+
|
136
|
+
const owners = await safeContract.getOwners().then(owners => owners.map(owner => owner.toLowerCase()));
|
137
|
+
|
138
|
+
const ownerPeerIds = peerPool.activePeers.filter(peer => owners.includes(peer.publicAddress.toLowerCase())).map(peer => peer.id)
|
139
|
+
|
140
|
+
console.log(`Collecting signatures for execution ${transaction.transactionHash}`)
|
141
|
+
|
142
|
+
console.log(ownerPeerIds);
|
143
|
+
|
144
|
+
const signatures = await protocol.requestSignatures({
|
145
|
+
type: 'source',
|
146
|
+
transactionHash: transaction.transactionHash,
|
147
|
+
safeTxGas: gnosisTx.safeTxGas,
|
148
|
+
safeNonce: gnosisTx.nonce
|
149
|
+
}, ownerPeerIds)
|
150
|
+
|
151
|
+
|
152
|
+
const validSignatures = signatures.filter(s => !!s.data && s.data !== '0x') as Signature[];
|
153
|
+
|
154
|
+
console.log({ signatures, validSignatures, ownersThreshold: ownersThreshold.toString() });
|
155
|
+
|
156
|
+
if (validSignatures.length === 0 || ownersThreshold.gt(validSignatures.length)) {
|
157
|
+
await transaction.save();
|
158
|
+
transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
|
159
|
+
transaction.targetStatus = 'uninitialised'
|
160
|
+
|
161
|
+
await transaction.save();
|
162
|
+
const errorMessage = signatures.find(s => !!s.error)?.error;
|
163
|
+
throw new Error(`Not enough signatures` + (errorMessage ? `: ${errorMessage}` : ''));
|
164
|
+
}
|
165
|
+
|
166
|
+
|
167
|
+
console.log(`Executing transaction for execution ${transaction.transactionHash}`)
|
168
|
+
|
169
|
+
const { data: txData } = await safeContract.populateTransaction.execTransaction(
|
170
|
+
gnosisTx.to,
|
171
|
+
gnosisTx.value,
|
172
|
+
gnosisTx.data,
|
173
|
+
gnosisTx.operation,
|
174
|
+
gnosisTx.safeTxGas,
|
175
|
+
gnosisTx.baseGas,
|
176
|
+
gnosisTx.gasPrice,
|
177
|
+
gnosisTx.gasToken,
|
178
|
+
gnosisTx.refundReceiver,
|
179
|
+
buildSignatureBytes(validSignatures)
|
180
|
+
);
|
181
|
+
|
182
|
+
console.log({
|
183
|
+
from: targetWallet.address,
|
184
|
+
gasPrice: BigNumber.from(120 * 10 ** 9).toString(),
|
185
|
+
to: safeAddress,
|
186
|
+
data: txData,
|
187
|
+
})
|
188
|
+
|
189
|
+
|
190
|
+
const txSent = await targetWallet.sendTransaction({
|
191
|
+
from: targetWallet.address,
|
192
|
+
gasPrice: BigNumber.from(120 * 10 ** 9),
|
193
|
+
to: safeAddress,
|
194
|
+
data: txData,
|
195
|
+
})
|
196
|
+
|
197
|
+
const receipt = await txSent.wait();
|
198
|
+
|
199
|
+
const parsedLogs: LogDescription[] = [];
|
200
|
+
|
201
|
+
receipt.logs.forEach((log) => {
|
202
|
+
try {
|
203
|
+
parsedLogs.push(safeContract.interface.parseLog(log));
|
204
|
+
} catch (e) { }
|
205
|
+
});
|
206
|
+
|
207
|
+
if (parsedLogs.find(e => e.name === 'ExecutionSuccess')) {
|
208
|
+
console.log('ExecutionSuccess')
|
209
|
+
transaction.targetStatus = 'success'
|
210
|
+
transaction.targetTransactionHash = txSent.hash
|
211
|
+
transaction.status = 'success'
|
212
|
+
await transaction.save();
|
213
|
+
} else {
|
214
|
+
console.log('ExecutionFailure')
|
215
|
+
transaction.targetStatus = 'failed'
|
216
|
+
transaction.targetTransactionHash = txSent.hash
|
217
|
+
transaction.status = 'failed'
|
218
|
+
await transaction.save();
|
219
|
+
}
|
220
|
+
}
|
221
|
+
|
222
|
+
async start(): Promise<void> {
|
223
|
+
this.provider = new ethers.providers.JsonRpcProvider(
|
224
|
+
getRpcProviderUrl(this.chainId)
|
225
|
+
);
|
226
|
+
|
227
|
+
await super.start()
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
export default ProcessWithdrawEvents;
|
@@ -0,0 +1,121 @@
|
|
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 { generateInteropTransactionHash, getContract, getRpcProviderUrl } from "@/utils";
|
7
|
+
import { ChainId } from "@/types";
|
8
|
+
import config from "@/config";
|
9
|
+
import { InteropBridgeToken } from "@/typechain";
|
10
|
+
|
11
|
+
class SyncBurnEvents extends BaseTask {
|
12
|
+
contractAddress: string;
|
13
|
+
provider: ethers.providers.JsonRpcProvider;
|
14
|
+
contract: InteropBridgeToken;
|
15
|
+
chainId: ChainId;
|
16
|
+
itokenAddress: string;
|
17
|
+
|
18
|
+
constructor({ chainId, itokenAddress }: { chainId: ChainId, itokenAddress: string }) {
|
19
|
+
super({
|
20
|
+
logger: new Logger("InteropBridgeToken::SyncBurnEvents"),
|
21
|
+
})
|
22
|
+
this.chainId = chainId;
|
23
|
+
this.itokenAddress = itokenAddress;
|
24
|
+
}
|
25
|
+
|
26
|
+
async pollHandler() {
|
27
|
+
const currentBlock = await this.provider.getBlockNumber();
|
28
|
+
|
29
|
+
const events = await this.contract.queryFilter(
|
30
|
+
this.contract.filters.Burn(),
|
31
|
+
currentBlock - 2000,
|
32
|
+
currentBlock,
|
33
|
+
);
|
34
|
+
|
35
|
+
let processedEvents = 0;
|
36
|
+
|
37
|
+
for (const event of events) {
|
38
|
+
|
39
|
+
try {
|
40
|
+
if (!event.args) {
|
41
|
+
continue;
|
42
|
+
}
|
43
|
+
|
44
|
+
const { to, amount, sourceChainId, targetChainId } = event.args;
|
45
|
+
|
46
|
+
const uniqueIdentifier = {
|
47
|
+
action: 'withdraw',
|
48
|
+
submitTransactionHash: event.transactionHash,
|
49
|
+
sourceChainId: sourceChainId,
|
50
|
+
targetChainId: targetChainId,
|
51
|
+
}
|
52
|
+
|
53
|
+
if (await Transaction.findOne({ where: uniqueIdentifier })) {
|
54
|
+
continue;
|
55
|
+
}
|
56
|
+
|
57
|
+
const tx = await event.getTransaction()
|
58
|
+
|
59
|
+
await Transaction.create({
|
60
|
+
...uniqueIdentifier,
|
61
|
+
transactionHash: generateInteropTransactionHash(uniqueIdentifier),
|
62
|
+
from: tx.from,
|
63
|
+
to,
|
64
|
+
|
65
|
+
|
66
|
+
submitTransactionHash: event.transactionHash,
|
67
|
+
submitBlockNumber: event.blockNumber,
|
68
|
+
|
69
|
+
// submit & source are the same
|
70
|
+
sourceTransactionHash: event.transactionHash,
|
71
|
+
sourceBlockNumber: event.blockNumber,
|
72
|
+
sourceStatus: "success",
|
73
|
+
|
74
|
+
targetStatus: "uninitialised",
|
75
|
+
|
76
|
+
submitEvent: {
|
77
|
+
to,
|
78
|
+
amount: amount.toString(),
|
79
|
+
itoken: this.itokenAddress,
|
80
|
+
sourceChainId: sourceChainId,
|
81
|
+
targetChainId: targetChainId,
|
82
|
+
},
|
83
|
+
|
84
|
+
sourceEvent: {
|
85
|
+
to,
|
86
|
+
amount: amount.toString(),
|
87
|
+
itoken: this.itokenAddress,
|
88
|
+
sourceChainId: sourceChainId,
|
89
|
+
targetChainId: targetChainId,
|
90
|
+
},
|
91
|
+
status: "pending",
|
92
|
+
})
|
93
|
+
|
94
|
+
this.logger.info(
|
95
|
+
`Withdraw queued: ${event.transactionHash} ${event.blockNumber}`
|
96
|
+
);
|
97
|
+
} catch (error) {
|
98
|
+
this.logger.error(error);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
if (processedEvents > 0)
|
103
|
+
this.logger.info(`${processedEvents} events processed`);
|
104
|
+
}
|
105
|
+
|
106
|
+
async start(): Promise<void> {
|
107
|
+
this.provider = new ethers.providers.JsonRpcProvider(
|
108
|
+
getRpcProviderUrl(this.chainId)
|
109
|
+
);
|
110
|
+
|
111
|
+
this.contract = getContract<InteropBridgeToken>(
|
112
|
+
this.itokenAddress,
|
113
|
+
abi.interopBridgeToken,
|
114
|
+
new ethers.Wallet(config.privateKey!, this.provider)
|
115
|
+
);
|
116
|
+
|
117
|
+
await super.start()
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
export default SyncBurnEvents;
|
@@ -0,0 +1,98 @@
|
|
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 { getContract, getRpcProviderUrl } from "@/utils";
|
7
|
+
import { ChainId } from "@/types";
|
8
|
+
import config from "@/config";
|
9
|
+
import { InteropBridgeToken } from "@/typechain";
|
10
|
+
|
11
|
+
class SyncMintEvents extends BaseTask {
|
12
|
+
contractAddress: string;
|
13
|
+
provider: ethers.providers.JsonRpcProvider;
|
14
|
+
contract: InteropBridgeToken;
|
15
|
+
chainId: ChainId;
|
16
|
+
itokenAddress: string;
|
17
|
+
|
18
|
+
constructor({ chainId, itokenAddress }: { chainId: ChainId, itokenAddress: string }) {
|
19
|
+
super({
|
20
|
+
logger: new Logger("InteropBridgeToken::SyncMintEvents"),
|
21
|
+
})
|
22
|
+
this.chainId = chainId;
|
23
|
+
this.itokenAddress = itokenAddress;
|
24
|
+
}
|
25
|
+
|
26
|
+
async pollHandler() {
|
27
|
+
const currentBlock = await this.provider.getBlockNumber();
|
28
|
+
|
29
|
+
const events = await this.contract.queryFilter(
|
30
|
+
this.contract.filters.Mint(),
|
31
|
+
currentBlock - 300,
|
32
|
+
currentBlock,
|
33
|
+
);
|
34
|
+
|
35
|
+
|
36
|
+
for (const event of events) {
|
37
|
+
|
38
|
+
try {
|
39
|
+
if (!event.args) {
|
40
|
+
continue;
|
41
|
+
}
|
42
|
+
|
43
|
+
const { sourceChainId, targetChainId, amount, to, submitTransactionHash } = event.args;
|
44
|
+
|
45
|
+
const uniqueIdentifier = {
|
46
|
+
action: 'deposit',
|
47
|
+
submitTransactionHash: submitTransactionHash,
|
48
|
+
sourceChainId: sourceChainId,
|
49
|
+
targetChainId: targetChainId,
|
50
|
+
}
|
51
|
+
|
52
|
+
const transaction = await Transaction.findOne({ where: uniqueIdentifier });
|
53
|
+
|
54
|
+
if(! transaction){
|
55
|
+
return;
|
56
|
+
}
|
57
|
+
|
58
|
+
const tx = await event.getTransaction()
|
59
|
+
|
60
|
+
transaction.targetStatus = 'success'
|
61
|
+
transaction.targetErrors = []
|
62
|
+
transaction.targetTransactionHash = tx.hash
|
63
|
+
transaction.targetEvent = {
|
64
|
+
sourceChainId,
|
65
|
+
targetChainId,
|
66
|
+
amount: amount.toString(),
|
67
|
+
to,
|
68
|
+
submitTransactionHash
|
69
|
+
}
|
70
|
+
transaction.status = 'success'
|
71
|
+
|
72
|
+
await transaction.save()
|
73
|
+
|
74
|
+
this.logger.info(
|
75
|
+
`Mint confirmation received: ${transaction.transactionHash} `
|
76
|
+
);
|
77
|
+
} catch (error) {
|
78
|
+
this.logger.error(error);
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
async start(): Promise<void> {
|
84
|
+
this.provider = new ethers.providers.JsonRpcProvider(
|
85
|
+
getRpcProviderUrl(this.chainId)
|
86
|
+
);
|
87
|
+
|
88
|
+
this.contract = getContract<InteropBridgeToken>(
|
89
|
+
this.itokenAddress,
|
90
|
+
abi.interopBridgeToken,
|
91
|
+
new ethers.Wallet(config.privateKey!, this.provider)
|
92
|
+
);
|
93
|
+
|
94
|
+
await super.start()
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
export default SyncMintEvents;
|
@@ -3,7 +3,7 @@ import Logger from '@/logger';
|
|
3
3
|
import { BigNumber, ethers } from "ethers";
|
4
4
|
import abi from "@/abi";
|
5
5
|
import { Transaction } from "@/db";
|
6
|
-
import { buildDataForTransaction, buildSignatureBytes, getRpcProviderUrl, Signature } from "@/utils";
|
6
|
+
import { buildDataForTransaction, buildSignatureBytes, getContract, getRpcProviderUrl, Signature } from "@/utils";
|
7
7
|
import { addresses } from "@/constants";
|
8
8
|
import { ChainId } from "@/types";
|
9
9
|
import config from "@/config";
|
@@ -13,7 +13,9 @@ import wait from "waait";
|
|
13
13
|
import { peerPool, protocol } from "@/net";
|
14
14
|
import { LogDescription } from "ethers/lib/utils";
|
15
15
|
|
16
|
-
const generateGnosisTransaction = async (transactionData: any, safeContract:
|
16
|
+
const generateGnosisTransaction = async (transactionData: any, safeContract: GnosisSafe) => {
|
17
|
+
console.log(transactionData);
|
18
|
+
|
17
19
|
let isExecuted = await safeContract.dataHashes(
|
18
20
|
await safeContract.getTransactionHash(
|
19
21
|
transactionData.to,
|
@@ -72,13 +74,21 @@ class ProcessDepositEvents extends BaseTask {
|
|
72
74
|
where: {
|
73
75
|
status: 'pending',
|
74
76
|
sourceStatus: 'success',
|
77
|
+
targetStatus: 'uninitialised',
|
75
78
|
action: 'deposit',
|
76
79
|
sourceCreatedAt: {
|
77
80
|
[Op.gte]: new Date(Date.now() - 12 * 60 * 60 * 1000),
|
78
81
|
},
|
82
|
+
targetDelayUntil: {
|
83
|
+
[Op.or]: {
|
84
|
+
[Op.is]: null,
|
85
|
+
[Op.lt]: new Date(),
|
86
|
+
}
|
87
|
+
},
|
79
88
|
sourceBlockNumber: {
|
80
89
|
[Op.lt]: blockNumber - 12,
|
81
|
-
}
|
90
|
+
},
|
91
|
+
sourceChainId: this.chainId,
|
82
92
|
}
|
83
93
|
})
|
84
94
|
|
@@ -86,11 +96,11 @@ class ProcessDepositEvents extends BaseTask {
|
|
86
96
|
return;
|
87
97
|
}
|
88
98
|
|
99
|
+
console.log(`Processing transaction ${transaction.transactionHash}`);
|
89
100
|
|
90
|
-
transaction.
|
101
|
+
transaction.targetStatus = 'pending';
|
91
102
|
await transaction.save();
|
92
103
|
|
93
|
-
|
94
104
|
// refresh event data?
|
95
105
|
|
96
106
|
const targetChainProvider = new ethers.providers.JsonRpcProvider(
|
@@ -101,19 +111,33 @@ class ProcessDepositEvents extends BaseTask {
|
|
101
111
|
|
102
112
|
const safeAddress = addresses[transaction.targetChainId].gnosisSafe;
|
103
113
|
|
104
|
-
|
114
|
+
|
115
|
+
const safeContract = getContract<GnosisSafe>(
|
105
116
|
safeAddress,
|
106
117
|
abi.gnosisSafe,
|
107
118
|
targetWallet
|
108
|
-
)
|
119
|
+
)
|
109
120
|
|
110
121
|
const ownersThreshold = await safeContract.getThreshold();
|
111
|
-
|
112
122
|
await wait(10000);
|
113
123
|
|
124
|
+
let data;
|
125
|
+
|
126
|
+
try {
|
127
|
+
data = await buildDataForTransaction(transaction);
|
128
|
+
} catch (error) {
|
129
|
+
console.log(error);
|
130
|
+
transaction.targetStatus = 'failed';
|
131
|
+
transaction.targetErrors = [error.message];
|
132
|
+
transaction.status = 'failed'
|
133
|
+
await transaction.save();
|
134
|
+
protocol.sendTransaction(transaction)
|
135
|
+
return;
|
136
|
+
}
|
137
|
+
|
114
138
|
let gnosisTx = await generateGnosisTransaction({
|
115
139
|
baseGas: "0",
|
116
|
-
data
|
140
|
+
data,
|
117
141
|
gasPrice: "0",
|
118
142
|
gasToken: "0x0000000000000000000000000000000000000000",
|
119
143
|
nonce: '0',
|
@@ -131,6 +155,8 @@ class ProcessDepositEvents extends BaseTask {
|
|
131
155
|
|
132
156
|
console.log(`Collecting signatures for execution ${transaction.transactionHash}`)
|
133
157
|
|
158
|
+
console.log(ownerPeerIds);
|
159
|
+
|
134
160
|
const signatures = await protocol.requestSignatures({
|
135
161
|
type: 'source',
|
136
162
|
transactionHash: transaction.transactionHash,
|
@@ -145,33 +171,17 @@ class ProcessDepositEvents extends BaseTask {
|
|
145
171
|
|
146
172
|
if (validSignatures.length === 0 || ownersThreshold.gt(validSignatures.length)) {
|
147
173
|
await transaction.save();
|
148
|
-
transaction.
|
149
|
-
transaction.
|
174
|
+
transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
|
175
|
+
transaction.targetStatus = 'uninitialised'
|
150
176
|
|
151
177
|
await transaction.save();
|
152
178
|
const errorMessage = signatures.find(s => !!s.error)?.error;
|
153
179
|
throw new Error(`Not enough signatures` + (errorMessage ? `: ${errorMessage}` : ''));
|
154
180
|
}
|
155
181
|
|
156
|
-
const execTransactionParams = [
|
157
|
-
gnosisTx.to,
|
158
|
-
gnosisTx.value,
|
159
|
-
gnosisTx.data,
|
160
|
-
gnosisTx.operation,
|
161
|
-
gnosisTx.safeTxGas,
|
162
|
-
gnosisTx.baseGas,
|
163
|
-
gnosisTx.gasPrice,
|
164
|
-
gnosisTx.gasToken,
|
165
|
-
gnosisTx.refundReceiver,
|
166
|
-
buildSignatureBytes(validSignatures),
|
167
|
-
];
|
168
182
|
|
169
183
|
console.log(`Executing transaction for execution ${transaction.transactionHash}`)
|
170
184
|
|
171
|
-
console.log({
|
172
|
-
execTransactionParams
|
173
|
-
})
|
174
|
-
|
175
185
|
const { data: txData } = await safeContract.populateTransaction.execTransaction(
|
176
186
|
gnosisTx.to,
|
177
187
|
gnosisTx.value,
|
@@ -185,10 +195,17 @@ class ProcessDepositEvents extends BaseTask {
|
|
185
195
|
buildSignatureBytes(validSignatures)
|
186
196
|
);
|
187
197
|
|
198
|
+
console.log({
|
199
|
+
from: targetWallet.address,
|
200
|
+
gasPrice: BigNumber.from(120 * 10 ** 9).toString(),
|
201
|
+
to: safeAddress,
|
202
|
+
data: txData,
|
203
|
+
})
|
204
|
+
|
205
|
+
|
188
206
|
const txSent = await targetWallet.sendTransaction({
|
189
207
|
from: targetWallet.address,
|
190
208
|
gasPrice: BigNumber.from(120 * 10 ** 9),
|
191
|
-
gasLimit: BigNumber.from(6_000_000),
|
192
209
|
to: safeAddress,
|
193
210
|
data: txData,
|
194
211
|
})
|
@@ -205,25 +222,33 @@ class ProcessDepositEvents extends BaseTask {
|
|
205
222
|
|
206
223
|
if (parsedLogs.find(e => e.name === 'ExecutionSuccess')) {
|
207
224
|
console.log('ExecutionSuccess')
|
225
|
+
transaction.targetStatus = 'success'
|
226
|
+
transaction.targetTransactionHash = txSent.hash
|
227
|
+
transaction.status = 'success'
|
228
|
+
await transaction.save();
|
208
229
|
} else {
|
209
230
|
console.log('ExecutionFailure')
|
231
|
+
transaction.targetStatus = 'failed'
|
232
|
+
transaction.targetTransactionHash = txSent.hash
|
233
|
+
transaction.status = 'failed'
|
234
|
+
await transaction.save();
|
210
235
|
}
|
236
|
+
|
237
|
+
protocol.sendTransaction(transaction)
|
211
238
|
}
|
212
239
|
|
213
240
|
async start(): Promise<void> {
|
214
|
-
this.logger.info(`Starting execution watcher on interop chain`);
|
215
|
-
|
216
241
|
this.contractAddress = addresses[this.chainId].interopXGateway;
|
217
242
|
|
218
243
|
this.provider = new ethers.providers.JsonRpcProvider(
|
219
244
|
getRpcProviderUrl(this.chainId)
|
220
245
|
);
|
221
246
|
|
222
|
-
this.contract =
|
247
|
+
this.contract = getContract<InteropXGateway>(
|
223
248
|
this.contractAddress,
|
224
249
|
abi.interopXGateway,
|
225
250
|
new ethers.Wallet(config.privateKey!, this.provider)
|
226
|
-
)
|
251
|
+
);
|
227
252
|
|
228
253
|
await super.start()
|
229
254
|
}
|