@instadapp/interop-x 0.0.0-dev.f39d622 → 0.0.0-dev.f45bd03

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.
Files changed (49) hide show
  1. package/dist/package.json +4 -2
  2. package/dist/src/abi/aaveV3Resolver.json +628 -0
  3. package/dist/src/abi/index.js +2 -0
  4. package/dist/src/constants/addresses.js +4 -2
  5. package/dist/src/db/models/transaction.js +1 -1
  6. package/dist/src/gnosis/actions/aaveV2/source.js +26 -1
  7. package/dist/src/gnosis/actions/aaveV2/target.js +16 -1
  8. package/dist/src/gnosis/actions/aaveV3/index.js +11 -0
  9. package/dist/src/gnosis/actions/aaveV3/source.js +74 -0
  10. package/dist/src/gnosis/actions/aaveV3/target.js +87 -0
  11. package/dist/src/gnosis/actions/index.js +2 -0
  12. package/dist/src/index.js +1 -1
  13. package/dist/src/providers/index.js +17 -0
  14. package/dist/src/providers/retry-provider.js +45 -0
  15. package/dist/src/tasks/InteropX/ProcessSubmitEvents.js +38 -10
  16. package/dist/src/tasks/InteropX/ProcessValidateEvents.js +28 -9
  17. package/dist/src/tasks/InteropX/SyncLogExecuteEvents.js +2 -1
  18. package/dist/src/tasks/InteropX/SyncLogSubmitEvents.js +2 -1
  19. package/dist/src/tasks/InteropX/SyncLogValidateEvents.js +2 -1
  20. package/dist/src/typechain/AaveV3Resolver.js +2 -0
  21. package/dist/src/typechain/factories/AaveV3Resolver__factory.js +887 -0
  22. package/dist/src/typechain/factories/index.js +3 -1
  23. package/dist/src/typechain/index.js +3 -1
  24. package/dist/src/utils/gnosis.js +42 -17
  25. package/dist/src/utils/validate.js +10 -14
  26. package/package.json +4 -2
  27. package/src/abi/aaveV3Resolver.json +628 -0
  28. package/src/abi/index.ts +2 -0
  29. package/src/constants/addresses.ts +6 -3
  30. package/src/db/models/transaction.ts +1 -1
  31. package/src/gnosis/actions/aaveV2/source.ts +58 -2
  32. package/src/gnosis/actions/aaveV2/target.ts +29 -2
  33. package/src/gnosis/actions/aaveV3/index.ts +9 -0
  34. package/src/gnosis/actions/aaveV3/source.ts +119 -0
  35. package/src/gnosis/actions/aaveV3/target.ts +142 -0
  36. package/src/gnosis/actions/index.ts +2 -0
  37. package/src/providers/index.ts +1 -0
  38. package/src/providers/retry-provider.ts +51 -0
  39. package/src/tasks/InteropX/ProcessSubmitEvents.ts +52 -13
  40. package/src/tasks/InteropX/ProcessValidateEvents.ts +39 -13
  41. package/src/tasks/InteropX/SyncLogExecuteEvents.ts +3 -2
  42. package/src/tasks/InteropX/SyncLogSubmitEvents.ts +3 -2
  43. package/src/tasks/InteropX/SyncLogValidateEvents.ts +3 -2
  44. package/src/typechain/AaveV3Resolver.ts +935 -0
  45. package/src/typechain/factories/AaveV3Resolver__factory.ts +894 -0
  46. package/src/typechain/factories/index.ts +1 -0
  47. package/src/typechain/index.ts +2 -0
  48. package/src/utils/gnosis.ts +75 -32
  49. package/src/utils/validate.ts +17 -19
@@ -2,12 +2,15 @@ import abi from "@/abi";
2
2
  import config from "@/config";
3
3
  import { addresses } from "@/constants";
4
4
  import { Transaction } from "@/db";
5
- import { InteropX } from "@/typechain";
5
+ import { JsonRpcRetryProvider } from "@/providers";
6
+ import { AaveV2Resolver, InstList, InteropX } from "@/typechain";
6
7
  import { ChainId } from "@/types";
7
8
  import { encodeConnectorMethod, getContract, getRpcProviderUrl } from "@/utils";
8
9
  import { ethers } from "ethers";
9
10
  import { MetaTransaction, OperationType } from "ethers-multisend";
10
11
 
12
+ const safeUserRatioGap = "800000000000000000"
13
+
11
14
  export default async function (transaction: Transaction) {
12
15
  const transactions: MetaTransaction[] = [];
13
16
  const logs: any[] = [];
@@ -25,13 +28,20 @@ export default async function (transaction: Transaction) {
25
28
  metadata,
26
29
  } = transaction.submitEvent;
27
30
 
28
- const sourceChainProvider = new ethers.providers.JsonRpcProvider(
31
+ const sourceChainProvider = new JsonRpcRetryProvider(
29
32
  getRpcProviderUrl(sourceChainId as ChainId)
30
33
  );
31
34
  const sourceWallet = new ethers.Wallet(
32
35
  config.privateKey,
33
36
  sourceChainProvider
34
37
  );
38
+ const targetChainProvider = new JsonRpcRetryProvider(
39
+ getRpcProviderUrl(targetChainId as ChainId)
40
+ );
41
+ const targetWallet = new ethers.Wallet(
42
+ config.privateKey,
43
+ targetChainProvider
44
+ );
35
45
  const dsaAddress = addresses[sourceChainId].dsaAddress;
36
46
  const sourceUserAddress =
37
47
  Number(sourceDsaId) == 0 ? sourceSender : dsaAddress;
@@ -42,6 +52,52 @@ export default async function (transaction: Transaction) {
42
52
  sourceWallet
43
53
  );
44
54
 
55
+ const sourceResolverContract = getContract<AaveV2Resolver>(
56
+ addresses[sourceChainId].aaveV2Resolver,
57
+ abi.aaveV2Resolver,
58
+ sourceWallet
59
+ );
60
+
61
+ const targetResolverContract = getContract<AaveV2Resolver>(
62
+ addresses[targetChainId].aaveV2Resolver,
63
+ abi.aaveV2Resolver,
64
+ targetWallet
65
+ );
66
+
67
+ const sourceAavePosition = await sourceResolverContract.checkAavePosition(sourceUserAddress, position, safeUserRatioGap, false)
68
+
69
+ const userSourceAaveIsOk = sourceAavePosition.isOk;
70
+
71
+ if (!userSourceAaveIsOk) {
72
+ throw new Error("Source chain aave position is not safe to migrate.");
73
+ }
74
+
75
+ const targetInstListContract = getContract<InstList>(
76
+ addresses[targetChainId].instList,
77
+ abi.instList,
78
+ targetChainProvider,
79
+ );
80
+
81
+ const targetDsaAddress = await targetInstListContract.accountAddr(targetDsaId)
82
+
83
+ const targetAavePosition = await targetResolverContract
84
+ .checkAavePosition(targetDsaAddress, position, safeUserRatioGap, true)
85
+
86
+ const userTargetAaveIsOk = targetAavePosition.isOk;
87
+
88
+ if (!userTargetAaveIsOk) {
89
+ throw new Error("Target chain aave position will not be safe after migration.");
90
+ }
91
+
92
+ const targetAavePositionWithFee = await targetResolverContract
93
+ .checkAavePosition(targetDsaAddress, position, safeUserRatioGap, true);
94
+
95
+ const userTargetAaveIsOkWithFee = targetAavePositionWithFee.isOk;
96
+
97
+ if (!userTargetAaveIsOkWithFee) {
98
+ throw new Error("Target chain aave position will not be safe after migration due to minimum fee.");
99
+ }
100
+
45
101
  const sourceSpells: any[] = [];
46
102
  const commonSpells: any[] = [];
47
103
 
@@ -2,13 +2,15 @@ import abi from "@/abi";
2
2
  import config from "@/config";
3
3
  import { addresses } from "@/constants";
4
4
  import { Transaction } from "@/db";
5
- import { InteropX } from "@/typechain";
5
+ import { JsonRpcRetryProvider } from "@/providers";
6
+ import { AaveV2Resolver, InteropX } from "@/typechain";
6
7
  import { InstList } from "@/typechain/InstList";
7
8
  import { ChainId } from "@/types";
8
9
  import { encodeConnectorMethod, getContract, getRpcProviderUrl } from "@/utils";
9
10
  import { ethers } from "ethers";
10
11
  import { MetaTransaction, OperationType } from "ethers-multisend";
11
12
 
13
+ const safeUserRatioGap = "800000000000000000"
12
14
 
13
15
  export default async function (transaction: Transaction) {
14
16
  const transactions: MetaTransaction[] = [];
@@ -27,7 +29,7 @@ export default async function (transaction: Transaction) {
27
29
  metadata,
28
30
  } = transaction.validateEvent;
29
31
 
30
- const targetChainProvider = new ethers.providers.JsonRpcProvider(
32
+ const targetChainProvider = new JsonRpcRetryProvider(
31
33
  getRpcProviderUrl(targetChainId as ChainId)
32
34
  );
33
35
  const targetWallet = new ethers.Wallet(
@@ -35,6 +37,11 @@ export default async function (transaction: Transaction) {
35
37
  targetChainProvider
36
38
  );
37
39
 
40
+ const targetResolverContract = getContract<AaveV2Resolver>(
41
+ addresses[targetChainId].aaveV2Resolver,
42
+ abi.aaveV2Resolver,
43
+ targetWallet
44
+ );
38
45
 
39
46
  const targetInstListContract = getContract<InstList>(
40
47
  addresses[targetChainId].instList,
@@ -43,6 +50,26 @@ export default async function (transaction: Transaction) {
43
50
  );
44
51
 
45
52
  const targetDsaAddress = await targetInstListContract.accountAddr(targetDsaId)
53
+
54
+
55
+ const targetAavePosition = await targetResolverContract
56
+ .checkAavePosition(targetDsaAddress, position, safeUserRatioGap, true)
57
+
58
+ const userTargetAaveIsOk = targetAavePosition.isOk;
59
+
60
+ if (!userTargetAaveIsOk) {
61
+ throw new Error("Target chain aave position will not be safe after migration.");
62
+ }
63
+
64
+ const targetAavePositionWithFee = await targetResolverContract
65
+ .checkAavePosition(targetDsaAddress, position, safeUserRatioGap, true);
66
+
67
+ const userTargetAaveIsOkWithFee = targetAavePositionWithFee.isOk;
68
+
69
+ if (!userTargetAaveIsOkWithFee) {
70
+ throw new Error("Target chain aave position will not be safe after migration due to minimum fee.");
71
+ }
72
+
46
73
  const dsaAddress = addresses[targetChainId].dsaAddress;
47
74
  const interopAddress = addresses[targetChainId].interopX;
48
75
  const contract = getContract<InteropX>(
@@ -0,0 +1,9 @@
1
+ import { Transaction } from "@/db";
2
+ import source from "./source";
3
+ import target from "./target";
4
+
5
+
6
+
7
+ export default async function (transaction: Transaction, type: 'source' | 'target') {
8
+ return type === 'source' ? source(transaction) : target(transaction);
9
+ }
@@ -0,0 +1,119 @@
1
+ import abi from "@/abi";
2
+ import config from "@/config";
3
+ import { addresses } from "@/constants";
4
+ import { Transaction } from "@/db";
5
+ import { JsonRpcRetryProvider } from "@/providers";
6
+ import { InteropX } from "@/typechain";
7
+ import { ChainId } from "@/types";
8
+ import { encodeConnectorMethod, getContract, getRpcProviderUrl } from "@/utils";
9
+ import { ethers } from "ethers";
10
+ import { MetaTransaction, OperationType } from "ethers-multisend";
11
+
12
+ export default async function (transaction: Transaction) {
13
+ const transactions: MetaTransaction[] = [];
14
+ const logs: any[] = [];
15
+
16
+ const {
17
+ position,
18
+ actionId,
19
+ actionIdHashHash,
20
+ sourceSender,
21
+ sourceDsaId,
22
+ targetDsaId,
23
+ sourceChainId,
24
+ targetChainId,
25
+ vnonce,
26
+ metadata,
27
+ } = transaction.submitEvent;
28
+
29
+ const sourceChainProvider = new JsonRpcRetryProvider(
30
+ getRpcProviderUrl(sourceChainId as ChainId)
31
+ );
32
+ const sourceWallet = new ethers.Wallet(
33
+ config.privateKey,
34
+ sourceChainProvider
35
+ );
36
+ const dsaAddress = addresses[sourceChainId].dsaAddress;
37
+ const sourceUserAddress =
38
+ Number(sourceDsaId) == 0 ? sourceSender : dsaAddress;
39
+ const interopAddress = addresses[sourceChainId].interopX;
40
+ const contract = getContract<InteropX>(
41
+ interopAddress,
42
+ abi.interopX,
43
+ sourceWallet
44
+ );
45
+
46
+ const sourceSpells: any[] = [];
47
+ const commonSpells: any[] = [];
48
+
49
+ for (const withdraw of position.withdraw) {
50
+ let spellData = {
51
+ connector: "AAVE-V3-A",
52
+ method: "payback",
53
+ args: [withdraw.sourceToken, withdraw.amount, "2", "0", "0"],
54
+ };
55
+
56
+ sourceSpells.push({
57
+ connector: spellData.connector,
58
+ data: encodeConnectorMethod(spellData),
59
+ });
60
+
61
+ let spellDataBasicWithdraw = {
62
+ connector: "BASIC-A",
63
+ method: "withdraw",
64
+ args: [withdraw.sourceToken, withdraw.amount, sourceUserAddress, "0", "0"],
65
+ };
66
+
67
+ commonSpells.push({
68
+ connector: spellDataBasicWithdraw.connector,
69
+ data: encodeConnectorMethod(spellDataBasicWithdraw),
70
+ });
71
+ }
72
+
73
+ for (const supply of position.supply) {
74
+ let spellDataWithdraw = {
75
+ connector: "AAVE-V3-A",
76
+ method: "withdraw",
77
+ args: [supply.sourceToken, supply.amount, "0", "0"],
78
+ };
79
+
80
+ sourceSpells.push({
81
+ connector: spellDataWithdraw.connector,
82
+ data: encodeConnectorMethod(spellDataWithdraw),
83
+ });
84
+
85
+ let spellDataBasicWithdraw = {
86
+ connector: "BASIC-A",
87
+ method: "withdraw",
88
+ args: [supply.sourceToken, supply.amount, dsaAddress, "0", "0"],
89
+ };
90
+
91
+ sourceSpells.push({
92
+ connector: spellDataBasicWithdraw.connector,
93
+ data: encodeConnectorMethod(spellDataBasicWithdraw),
94
+ });
95
+ }
96
+
97
+ const { data } = await contract.populateTransaction.sourceAction(
98
+ sourceSpells,
99
+ commonSpells,
100
+ position,
101
+ actionId,
102
+ sourceSender,
103
+ sourceDsaId,
104
+ targetDsaId,
105
+ sourceChainId,
106
+ targetChainId,
107
+ vnonce,
108
+ metadata
109
+ );
110
+
111
+ transactions.push({
112
+ to: interopAddress,
113
+ data: data!,
114
+ value: "0",
115
+ operation: OperationType.Call,
116
+ });
117
+
118
+ return { transactions, logs };
119
+ }
@@ -0,0 +1,142 @@
1
+ import abi from "@/abi";
2
+ import config from "@/config";
3
+ import { addresses } from "@/constants";
4
+ import { Transaction } from "@/db";
5
+ import { JsonRpcRetryProvider } from "@/providers";
6
+ import { InteropX } from "@/typechain";
7
+ import { InstList } from "@/typechain/InstList";
8
+ import { ChainId } from "@/types";
9
+ import { encodeConnectorMethod, getContract, getRpcProviderUrl } from "@/utils";
10
+ import { ethers } from "ethers";
11
+ import { MetaTransaction, OperationType } from "ethers-multisend";
12
+
13
+
14
+ export default async function (transaction: Transaction) {
15
+ const transactions: MetaTransaction[] = [];
16
+ const logs: any[] = [];
17
+
18
+ const {
19
+ sourceSpells,
20
+ position,
21
+ actionId,
22
+ sourceSender,
23
+ sourceDsaId,
24
+ targetDsaId,
25
+ sourceChainId,
26
+ targetChainId,
27
+ vnonce,
28
+ metadata,
29
+ } = transaction.validateEvent;
30
+
31
+ const targetChainProvider = new JsonRpcRetryProvider(
32
+ getRpcProviderUrl(targetChainId as ChainId)
33
+ );
34
+ const targetWallet = new ethers.Wallet(
35
+ config.privateKey,
36
+ targetChainProvider
37
+ );
38
+
39
+
40
+ const targetInstListContract = getContract<InstList>(
41
+ addresses[targetChainId].instList,
42
+ abi.instList,
43
+ targetChainProvider,
44
+ );
45
+
46
+ const targetDsaAddress = await targetInstListContract.accountAddr(targetDsaId)
47
+ const dsaAddress = addresses[targetChainId].dsaAddress;
48
+ const interopAddress = addresses[targetChainId].interopX;
49
+ const contract = getContract<InteropX>(
50
+ interopAddress,
51
+ abi.interopX,
52
+ targetWallet
53
+ );
54
+
55
+ const targetSpells: any[] = [];
56
+ const commonSpells: any[] = [];
57
+
58
+ for (const supplyToken of position.supply) {
59
+ let spellData = {
60
+ connector: "AAVE-V3-A",
61
+ method: "deposit",
62
+ args: [supplyToken.targetToken, supplyToken.amount, "0", "0"],
63
+ };
64
+
65
+ targetSpells.push({
66
+ connector: spellData.connector,
67
+ data: encodeConnectorMethod(spellData),
68
+ });
69
+
70
+ let spellDataBasicWithdraw = {
71
+ connector: "BASIC-A",
72
+ method: "withdraw",
73
+ args: [supplyToken.targetToken, supplyToken.amount, targetDsaAddress, "0", "0"],
74
+ };
75
+
76
+ commonSpells.push({
77
+ connector: spellDataBasicWithdraw.connector,
78
+ data: encodeConnectorMethod(spellDataBasicWithdraw),
79
+ });
80
+ }
81
+
82
+ for (const withdrawToken of position.withdraw) {
83
+
84
+ let spellData = {
85
+ connector: "AAVE-V3-A",
86
+ method: "borrow",
87
+ args: [
88
+ withdrawToken.targetToken,
89
+ withdrawToken.amount,
90
+ "2",
91
+ "0",
92
+ "0",
93
+ ],
94
+ };
95
+
96
+ targetSpells.push({
97
+ connector: spellData.connector,
98
+ data: encodeConnectorMethod(spellData),
99
+ });
100
+
101
+ let spellData2 = {
102
+ connector: "BASIC-A",
103
+ method: "withdraw",
104
+ args: [
105
+ withdrawToken.targetToken,
106
+ withdrawToken.amount,
107
+ dsaAddress,
108
+ "0",
109
+ "0",
110
+ ],
111
+ };
112
+
113
+ targetSpells.push({
114
+ connector: spellData.connector,
115
+ data: encodeConnectorMethod(spellData2),
116
+ });
117
+ }
118
+
119
+ const { data } = await contract.populateTransaction.targetAction(
120
+ sourceSpells,
121
+ targetSpells,
122
+ commonSpells,
123
+ position,
124
+ actionId,
125
+ sourceSender,
126
+ sourceDsaId,
127
+ targetDsaId,
128
+ sourceChainId,
129
+ targetChainId,
130
+ vnonce,
131
+ metadata
132
+ );
133
+
134
+ transactions.push({
135
+ to: interopAddress,
136
+ data: data!,
137
+ value: "0",
138
+ operation: OperationType.Call,
139
+ });
140
+
141
+ return { transactions, logs }
142
+ }
@@ -1,5 +1,7 @@
1
1
  import aaveV2 from "./aaveV2"
2
+ import aaveV3 from "./aaveV3"
2
3
 
3
4
  export default {
4
5
  'A:AAVE-V2:AAVE-V2': aaveV2,
6
+ 'A:AAVE-V3:AAVE-V3': aaveV3,
5
7
  }
@@ -0,0 +1 @@
1
+ export * from './retry-provider';
@@ -0,0 +1,51 @@
1
+ import { ethers } from "ethers";
2
+ import wait from "waait";
3
+ import Bluebird from "bluebird";
4
+
5
+ export interface RetryOptions {
6
+ delay?: number;
7
+ timeouts: number[];
8
+ }
9
+
10
+ export function promiseTimeout<T>(ms: number, promise: Promise<T>): Promise<T> {
11
+ return Bluebird.resolve(promise).timeout(ms);
12
+ }
13
+
14
+ export function retryOperation(
15
+ retriesLeft: number,
16
+ operation: () => Promise<any>,
17
+ options: RetryOptions
18
+ ) {
19
+ return new Promise((resolve, reject) => {
20
+ const { timeouts } = options;
21
+ // Find the timeout for this specific iteration
22
+ const timeout = timeouts[timeouts.length - retriesLeft];
23
+
24
+ // Wrap the original operation in a timeout
25
+ const execution = promiseTimeout(timeout, operation());
26
+
27
+ // If the promise is successful, resolve it and bubble the result up
28
+ return execution.then(resolve).catch((reason: any) => {
29
+ // If there are any retries left, we call the same retryOperation function again,
30
+ // but decrementing the number of retries left by 1
31
+ if (retriesLeft - 1 > 0) {
32
+ // Delay the new attempt slightly
33
+ return wait(options.delay || 50)
34
+ .then(retryOperation.bind(null, retriesLeft - 1, operation, options))
35
+ .then(resolve)
36
+ .catch(reject);
37
+ }
38
+ // Reject (and bubble the result up) if there are no more retries
39
+ return reject(reason);
40
+ });
41
+ });
42
+ }
43
+
44
+ export class JsonRpcRetryProvider extends ethers.providers.JsonRpcProvider {
45
+ public perform(method: string, params: any): Promise<any> {
46
+ const timeouts = [5_000, 10_000];
47
+ const operation = () => super.perform(method, params);
48
+
49
+ return retryOperation(2, operation, { timeouts, delay: 50 });
50
+ }
51
+ }
@@ -6,6 +6,7 @@ import { Transaction } from "@/db";
6
6
  import {
7
7
  buildSignatureBytes,
8
8
  chainIdToName,
9
+ generateGnosisSignatureMessage,
9
10
  generateGnosisTransaction,
10
11
  getChainIdNativeSymbol,
11
12
  getContract,
@@ -15,6 +16,7 @@ import {
15
16
  validateChains,
16
17
  validateLiquidityCap,
17
18
  validateSourceLiquidity,
19
+ getGnosisSignatureAddress,
18
20
  } from "@/utils";
19
21
  import { addresses, blockConfirmations } from "@/constants";
20
22
  import { ChainId } from "@/types";
@@ -29,9 +31,10 @@ import wait from "waait";
29
31
  import { LiquidityError, UnsupportedChaindIdError } from "@/errors";
30
32
  import { BigNumber } from "bignumber.js";
31
33
  import dedent from "dedent";
34
+ import { JsonRpcRetryProvider } from "@/providers";
32
35
 
33
36
  export default class ProcessSubmitEvents extends BaseTask {
34
- sourceProvider: ethers.providers.JsonRpcProvider;
37
+ sourceProvider: JsonRpcRetryProvider;
35
38
  sourceGnosisContract: GnosisSafe;
36
39
  sourceWallet: Wallet;
37
40
  chainId: ChainId;
@@ -142,6 +145,7 @@ export default class ProcessSubmitEvents extends BaseTask {
142
145
  await transaction.save();
143
146
  } else {
144
147
  transaction.sourceStatus = "pending";
148
+ transaction.sourceErrors = [error.message];
145
149
  transaction.sourceDelayUntil = moment().add({ minutes: 5 }).toDate();
146
150
  await transaction.save();
147
151
 
@@ -203,19 +207,36 @@ export default class ProcessSubmitEvents extends BaseTask {
203
207
  this.sourceGnosisContract
204
208
  );
205
209
 
206
- const owners = await this.sourceGnosisContract
207
- .getOwners()
208
- .then((owners) => owners.map((owner) => owner.toLowerCase()));
209
210
 
210
- const ownerPeerIds = peerPool.activePeers
211
- .filter((peer) => owners.includes(peer.publicAddress.toLowerCase()))
212
- .map((peer) => peer.id);
211
+ async function getGnosisOwnerPeerIds({
212
+ gnosisContract
213
+ }) {
214
+ const owners = await gnosisContract
215
+ .getOwners()
216
+ .then((owners) => owners.map((owner) => owner.toLowerCase()));
217
+
218
+ return peerPool.activePeers
219
+ .filter((peer) => owners.includes(peer.publicAddress.toLowerCase()))
220
+ .map((peer) => peer.id);
221
+ }
222
+
223
+ const ownerPeerIds = await getGnosisOwnerPeerIds({
224
+ gnosisContract: this.sourceGnosisContract,
225
+ });
213
226
 
214
227
  console.log(
215
- `Collecting signatures for execution ${transaction.transactionHash}`
228
+ `Collecting signatures for execution ${transaction.transactionHash} `
216
229
  );
217
230
 
218
231
  console.log(ownerPeerIds);
232
+
233
+ const message = generateGnosisSignatureMessage({
234
+ to: addresses[data.chainId].multisend,
235
+ data,
236
+ chainId: this.chainId,
237
+ safeTxGas: gnosisTx.safeTxGas,
238
+ nonce: gnosisTx.safeNonce,
239
+ });
219
240
 
220
241
  const signatures = await protocol.requestSignatures(
221
242
  {
@@ -228,9 +249,27 @@ export default class ProcessSubmitEvents extends BaseTask {
228
249
  ownerPeerIds
229
250
  );
230
251
 
231
- const validSignatures = signatures.filter(
232
- (s) => !!s.data && s.data !== "0x"
233
- ) as Signature[];
252
+ const validSignatures = signatures
253
+ .filter(
254
+ (s) => !!s.data && s.data !== "0x"
255
+ )
256
+ .filter((s) => {
257
+
258
+ try {
259
+
260
+ const address = getGnosisSignatureAddress({
261
+ message,
262
+ signature: s.data!,
263
+ chainId: this.chainId,
264
+ })
265
+
266
+ return address?.toLowerCase() === s.signer.toLowerCase();
267
+
268
+ } catch (error) {
269
+ return false
270
+ }
271
+
272
+ }) as Signature[];
234
273
 
235
274
  console.log({
236
275
  signatures,
@@ -249,7 +288,7 @@ export default class ProcessSubmitEvents extends BaseTask {
249
288
  await transaction.save();
250
289
  const errorMessage = signatures.find((s) => !!s.error)?.error;
251
290
  throw new Error(
252
- `Not enough signatures` + (errorMessage ? `: ${errorMessage}` : "")
291
+ `Not enough signatures` + (errorMessage ? `: ${errorMessage} ` : "")
253
292
  );
254
293
  }
255
294
 
@@ -324,7 +363,7 @@ export default class ProcessSubmitEvents extends BaseTask {
324
363
  async start(): Promise<void> {
325
364
  this.blockConfirmationsCount = blockConfirmations[this.chainId] + 1;
326
365
 
327
- this.sourceProvider = new ethers.providers.JsonRpcProvider(
366
+ this.sourceProvider = new JsonRpcRetryProvider(
328
367
  getRpcProviderUrl(this.chainId)
329
368
  );
330
369