@instadapp/interop-x 0.0.0-dev.8cb1c22 → 0.0.0-dev.909c44a

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 (204) hide show
  1. package/dist/package.json +9 -2
  2. package/dist/src/abi/aaveV2Resolver.json +832 -0
  3. package/dist/src/abi/aaveV3Resolver.json +628 -0
  4. package/dist/src/abi/balanceResolver.json +211 -0
  5. package/dist/src/abi/connectors/index.js +2 -2
  6. package/dist/src/abi/connectors/v2/1INCH-A.js +39 -1
  7. package/dist/src/abi/connectors/v2/1INCH-V3-A.js +42 -0
  8. package/dist/src/abi/connectors/v2/1INCH-V4-A.js +42 -0
  9. package/dist/src/abi/connectors/v2/AAVE-IMPORT-V2-V3-A.js +57 -0
  10. package/dist/src/abi/connectors/v2/AAVE-V2-A.js +91 -133
  11. package/dist/src/abi/connectors/v2/AAVE-V2-IMPORT-C.js +4 -0
  12. package/dist/src/abi/connectors/v2/AAVE-V3-A.js +322 -0
  13. package/dist/src/abi/connectors/v2/AAVE-V3-CLAIM-A.js +58 -0
  14. package/dist/src/abi/connectors/v2/AAVE-V3-IMPORT-A.js +59 -0
  15. package/dist/src/abi/connectors/v2/AAVE-V3-IMPORT-PERMIT-A.js +81 -0
  16. package/dist/src/abi/connectors/v2/BASIC-A.js +44 -86
  17. package/dist/src/abi/connectors/v2/BENQI-A.js +901 -0
  18. package/dist/src/abi/connectors/v2/COMPOUND-IMPORT-C.js +4 -0
  19. package/dist/src/abi/connectors/v2/COMPOUND-IMPORT-D.js +27 -0
  20. package/dist/src/abi/connectors/v2/DSA-SPELL-A.js +60 -0
  21. package/dist/src/abi/connectors/v2/HOP-A.js +41 -0
  22. package/dist/src/abi/connectors/v2/HOP-MAINNET-A.js +38 -0
  23. package/dist/src/abi/connectors/v2/INSTA-DEX-SIMULATION-A.js +40 -0
  24. package/dist/src/abi/connectors/v2/INSTAPOOL-B.js +4 -0
  25. package/dist/src/abi/connectors/v2/INSTAPOOL-C.js +4 -0
  26. package/dist/src/abi/connectors/v2/INTEROP-A.js +4 -0
  27. package/dist/src/abi/connectors/v2/INTEROP-STAGING-A.js +4 -0
  28. package/dist/src/abi/connectors/v2/LIDO-STETH-A.js +36 -0
  29. package/dist/src/abi/connectors/v2/LITE-A.js +4 -0
  30. package/dist/src/abi/connectors/v2/MSTABLE-A.js +4 -0
  31. package/dist/src/abi/connectors/v2/NOTIONAL-V2-A.js +484 -0
  32. package/dist/src/abi/connectors/v2/PANGOLIN-A.js +136 -0
  33. package/dist/src/abi/connectors/v2/PANGOLIN-STAKE-A.js +227 -0
  34. package/dist/src/abi/connectors/v2/PARASWAP-A.js +26 -1
  35. package/dist/src/abi/connectors/v2/PARASWAP-V5-A.js +29 -0
  36. package/dist/src/abi/connectors/v2/POOLTOGETHER-A.js +4 -0
  37. package/dist/src/abi/connectors/v2/QI-A.js +4 -0
  38. package/dist/src/abi/connectors/v2/QUICKSWAP-A.js +136 -0
  39. package/dist/src/abi/connectors/v2/SUSHISWAP-A.js +136 -0
  40. package/dist/src/abi/connectors/v2/SWAP-AGGREGATOR-A.js +25 -0
  41. package/dist/src/abi/connectors/v2/UBIQUITY-A.js +73 -0
  42. package/dist/src/abi/connectors/v2/UNISWAP-SELL-BETA.js +4 -0
  43. package/dist/src/abi/connectors/v2/UNISWAP-V3-A.js +1 -1
  44. package/dist/src/abi/connectors/v2/UNISWAP-V3-ROUTER-A.js +4 -0
  45. package/dist/src/abi/connectors/v2/UNISWAP-V3-STAKER-B.js +193 -0
  46. package/dist/src/abi/connectors/v2/UNISWAP-V3-SWAP-A.js +74 -0
  47. package/dist/src/abi/connectors/v2/UNIVERSE-A.js +4 -0
  48. package/dist/src/abi/connectors/v2/WAVAX-A.js +4 -0
  49. package/dist/src/abi/connectors/v2/WFTM-A.js +60 -0
  50. package/dist/src/abi/connectors/v2/WMATIC-A.js +4 -0
  51. package/dist/src/abi/connectors/v2/ZEROX-A.js +29 -0
  52. package/dist/src/abi/connectors/v2/ZEROX-V4-A.js +29 -0
  53. package/dist/src/abi/connectors/v2/index.js +128 -44
  54. package/dist/src/abi/index.js +8 -0
  55. package/dist/src/abi/instList.json +232 -0
  56. package/dist/src/api/index.js +7 -0
  57. package/dist/src/constants/addresses.js +9 -1
  58. package/dist/src/constants/capPerChain.js +8 -0
  59. package/dist/src/constants/index.js +2 -0
  60. package/dist/src/constants/tokens.js +44 -44
  61. package/dist/src/constants/wrappedNativeToken.js +8 -0
  62. package/dist/src/crons/index.js +3 -0
  63. package/dist/src/crons/prices.js +16 -0
  64. package/dist/src/db/models/transaction.js +5 -1
  65. package/dist/src/errors/index.js +30 -0
  66. package/dist/src/gnosis/actions/aaveV2/source.js +26 -1
  67. package/dist/src/gnosis/actions/aaveV2/target.js +20 -5
  68. package/dist/src/gnosis/actions/aaveV3/index.js +11 -0
  69. package/dist/src/gnosis/actions/aaveV3/source.js +74 -0
  70. package/dist/src/gnosis/actions/aaveV3/target.js +87 -0
  71. package/dist/src/gnosis/actions/index.js +2 -0
  72. package/dist/src/index.js +2 -1
  73. package/dist/src/providers/index.js +17 -0
  74. package/dist/src/providers/retry-provider.js +45 -0
  75. package/dist/src/services/Prices.js +74 -0
  76. package/dist/src/services/index.js +8 -0
  77. package/dist/src/tasks/InteropX/{ProcessSubmitSubmitEvents.js → ProcessSubmitEvents.js} +110 -16
  78. package/dist/src/tasks/InteropX/ProcessValidateEvents.js +30 -10
  79. package/dist/src/tasks/InteropX/SyncLogExecuteEvents.js +113 -0
  80. package/dist/src/tasks/InteropX/SyncLogSubmitEvents.js +3 -2
  81. package/dist/src/tasks/InteropX/SyncLogValidateEvents.js +6 -5
  82. package/dist/src/tasks/index.js +7 -5
  83. package/dist/src/typechain/AaveV2Resolver.js +2 -0
  84. package/dist/src/typechain/AaveV3Resolver.js +2 -0
  85. package/dist/src/typechain/BalanceResolver.js +2 -0
  86. package/dist/src/typechain/InstList.js +2 -0
  87. package/dist/src/typechain/factories/AaveV2Resolver__factory.js +1191 -0
  88. package/dist/src/typechain/factories/AaveV3Resolver__factory.js +887 -0
  89. package/dist/src/typechain/factories/BalanceResolver__factory.js +228 -0
  90. package/dist/src/typechain/factories/InstList__factory.js +249 -0
  91. package/dist/src/typechain/factories/index.js +9 -1
  92. package/dist/src/typechain/index.js +9 -1
  93. package/dist/src/utils/async.js +18 -0
  94. package/dist/src/utils/dsa.js +36 -0
  95. package/dist/src/utils/formatting.js +67 -0
  96. package/dist/src/utils/gnosis.js +87 -0
  97. package/dist/src/utils/http.js +10 -0
  98. package/dist/src/utils/index.js +22 -220
  99. package/dist/src/utils/interop.js +16 -0
  100. package/dist/src/utils/tokens.js +22 -0
  101. package/dist/src/utils/validate.js +111 -0
  102. package/dist/src/utils/web3.js +93 -0
  103. package/package.json +9 -2
  104. package/src/abi/aaveV2Resolver.json +832 -0
  105. package/src/abi/aaveV3Resolver.json +628 -0
  106. package/src/abi/balanceResolver.json +211 -0
  107. package/src/abi/connectors/index.ts +5 -5
  108. package/src/abi/connectors/v2/1INCH-A.ts +39 -1
  109. package/src/abi/connectors/v2/1INCH-V3-A.ts +41 -0
  110. package/src/abi/connectors/v2/1INCH-V4-A.ts +41 -0
  111. package/src/abi/connectors/v2/AAVE-IMPORT-V2-V3-A.ts +56 -0
  112. package/src/abi/connectors/v2/AAVE-V2-A.ts +93 -135
  113. package/src/abi/connectors/v2/AAVE-V2-IMPORT-C.ts +3 -0
  114. package/src/abi/connectors/v2/AAVE-V3-A.ts +321 -0
  115. package/src/abi/connectors/v2/AAVE-V3-CLAIM-A.ts +57 -0
  116. package/src/abi/connectors/v2/AAVE-V3-IMPORT-A.ts +58 -0
  117. package/src/abi/connectors/v2/AAVE-V3-IMPORT-PERMIT-A.ts +80 -0
  118. package/src/abi/connectors/v2/BASIC-A.ts +44 -86
  119. package/src/abi/connectors/v2/BENQI-A.ts +900 -0
  120. package/src/abi/connectors/v2/COMPOUND-IMPORT-C.ts +3 -0
  121. package/src/abi/connectors/v2/COMPOUND-IMPORT-D.ts +26 -0
  122. package/src/abi/connectors/v2/DSA-SPELL-A.ts +59 -0
  123. package/src/abi/connectors/v2/HOP-A.ts +40 -0
  124. package/src/abi/connectors/v2/HOP-MAINNET-A.ts +37 -0
  125. package/src/abi/connectors/v2/INSTA-DEX-SIMULATION-A.ts +39 -0
  126. package/src/abi/connectors/v2/INSTAPOOL-B.ts +3 -0
  127. package/src/abi/connectors/v2/INSTAPOOL-C.ts +3 -0
  128. package/src/abi/connectors/v2/INTEROP-A.ts +3 -0
  129. package/src/abi/connectors/v2/INTEROP-STAGING-A.ts +3 -0
  130. package/src/abi/connectors/v2/LIDO-STETH-A.ts +35 -0
  131. package/src/abi/connectors/v2/LITE-A.ts +3 -0
  132. package/src/abi/connectors/v2/MSTABLE-A.ts +3 -0
  133. package/src/abi/connectors/v2/NOTIONAL-V2-A.ts +483 -0
  134. package/src/abi/connectors/v2/PANGOLIN-A.ts +135 -0
  135. package/src/abi/connectors/v2/PANGOLIN-STAKE-A.ts +226 -0
  136. package/src/abi/connectors/v2/PARASWAP-A.ts +26 -1
  137. package/src/abi/connectors/v2/PARASWAP-V5-A.ts +28 -0
  138. package/src/abi/connectors/v2/POOLTOGETHER-A.ts +3 -0
  139. package/src/abi/connectors/v2/QI-A.ts +3 -0
  140. package/src/abi/connectors/v2/QUICKSWAP-A.ts +135 -0
  141. package/src/abi/connectors/v2/SUSHISWAP-A.ts +135 -0
  142. package/src/abi/connectors/v2/SWAP-AGGREGATOR-A.ts +24 -0
  143. package/src/abi/connectors/v2/UBIQUITY-A.ts +72 -0
  144. package/src/abi/connectors/v2/UNISWAP-SELL-BETA.ts +3 -0
  145. package/src/abi/connectors/v2/UNISWAP-V3-A.ts +1 -1
  146. package/src/abi/connectors/v2/UNISWAP-V3-ROUTER-A.ts +3 -0
  147. package/src/abi/connectors/v2/UNISWAP-V3-STAKER-B.ts +192 -0
  148. package/src/abi/connectors/v2/UNISWAP-V3-SWAP-A.ts +73 -0
  149. package/src/abi/connectors/v2/UNIVERSE-A.ts +3 -0
  150. package/src/abi/connectors/v2/WAVAX-A.ts +3 -0
  151. package/src/abi/connectors/v2/WFTM-A.ts +59 -0
  152. package/src/abi/connectors/v2/WMATIC-A.ts +3 -0
  153. package/src/abi/connectors/v2/ZEROX-A.ts +28 -0
  154. package/src/abi/connectors/v2/ZEROX-V4-A.ts +28 -0
  155. package/src/abi/connectors/v2/index.ts +171 -85
  156. package/src/abi/index.ts +8 -0
  157. package/src/abi/instList.json +232 -0
  158. package/src/api/index.ts +8 -0
  159. package/src/constants/addresses.ts +21 -2
  160. package/src/constants/capPerChain.ts +5 -0
  161. package/src/constants/index.ts +2 -0
  162. package/src/constants/tokens.ts +44 -44
  163. package/src/constants/wrappedNativeToken.ts +5 -0
  164. package/src/crons/index.ts +1 -0
  165. package/src/crons/prices.ts +12 -0
  166. package/src/db/models/transaction.ts +22 -1
  167. package/src/errors/index.ts +26 -0
  168. package/src/gnosis/actions/aaveV2/source.ts +56 -3
  169. package/src/gnosis/actions/aaveV2/target.ts +35 -7
  170. package/src/gnosis/actions/aaveV3/index.ts +9 -0
  171. package/src/gnosis/actions/aaveV3/source.ts +119 -0
  172. package/src/gnosis/actions/aaveV3/target.ts +142 -0
  173. package/src/gnosis/actions/index.ts +2 -0
  174. package/src/index.ts +1 -0
  175. package/src/providers/index.ts +1 -0
  176. package/src/providers/retry-provider.ts +51 -0
  177. package/src/services/Prices.ts +89 -0
  178. package/src/services/index.ts +1 -0
  179. package/src/tasks/InteropX/{ProcessSubmitSubmitEvents.ts → ProcessSubmitEvents.ts} +139 -22
  180. package/src/tasks/InteropX/ProcessValidateEvents.ts +42 -19
  181. package/src/tasks/InteropX/SyncLogExecuteEvents.ts +161 -0
  182. package/src/tasks/InteropX/SyncLogSubmitEvents.ts +6 -7
  183. package/src/tasks/InteropX/SyncLogValidateEvents.ts +9 -10
  184. package/src/tasks/index.ts +8 -5
  185. package/src/typechain/AaveV2Resolver.ts +1017 -0
  186. package/src/typechain/AaveV3Resolver.ts +935 -0
  187. package/src/typechain/BalanceResolver.ts +266 -0
  188. package/src/typechain/InstList.ts +402 -0
  189. package/src/typechain/factories/AaveV2Resolver__factory.ts +1198 -0
  190. package/src/typechain/factories/AaveV3Resolver__factory.ts +894 -0
  191. package/src/typechain/factories/BalanceResolver__factory.ts +235 -0
  192. package/src/typechain/factories/InstList__factory.ts +253 -0
  193. package/src/typechain/factories/index.ts +4 -0
  194. package/src/typechain/index.ts +8 -0
  195. package/src/utils/async.ts +22 -0
  196. package/src/utils/dsa.ts +56 -0
  197. package/src/utils/formatting.ts +68 -0
  198. package/src/utils/gnosis.ts +166 -0
  199. package/src/utils/http.ts +6 -0
  200. package/src/utils/index.ts +9 -365
  201. package/src/utils/interop.ts +28 -0
  202. package/src/utils/tokens.ts +21 -0
  203. package/src/utils/validate.ts +179 -0
  204. package/src/utils/web3.ts +132 -0
@@ -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
+ }
@@ -0,0 +1,89 @@
1
+ import Web3Utils from "web3-utils";
2
+ import path from "path";
3
+ import fs from "fs";
4
+ import { tokens } from "@/constants";
5
+ import expandHomeDir from "expand-home-dir";
6
+ import config from "@/config";
7
+ import { http } from "@/utils";
8
+
9
+ const basePath = expandHomeDir(`~/.interop-x/data/${config.publicAddress}/${config.staging ? 'staging' : ''}`);
10
+ const mainnetPricesFilePath = path.resolve(basePath, "./mainnetPrices.json");
11
+ const networkTokenPricesFilePath = path.resolve(basePath, "./networkTokenPrices.json");
12
+
13
+ class Prices {
14
+ private static mainnetPrices = {};
15
+
16
+ private static networkTokenPrices = {};
17
+
18
+ static async fetch() {
19
+
20
+ if (!fs.existsSync(mainnetPricesFilePath)) {
21
+ fs.writeFileSync(mainnetPricesFilePath, JSON.stringify({}));
22
+ }
23
+
24
+ if (!fs.existsSync(networkTokenPricesFilePath)) {
25
+ fs.writeFileSync(networkTokenPricesFilePath, JSON.stringify({}));
26
+ }
27
+
28
+ this.mainnetPrices = JSON.parse(fs.readFileSync(mainnetPricesFilePath, "utf8"));
29
+ this.networkTokenPrices = JSON.parse(fs.readFileSync(networkTokenPricesFilePath, "utf8"));
30
+
31
+ try {
32
+ const path = tokens["1"]
33
+ .filter((a) => a.symbol !== "ETH")
34
+ .map((token) => token.address)
35
+ .join(",");
36
+
37
+ const [response, ethResponse, avaxResponse, polygonResponse] =
38
+ await Promise.all([
39
+ http.get(
40
+ "https://api.coingecko.com/api/v3/simple/token_price/ethereum",
41
+ {
42
+ params: { contract_addresses: path, vs_currencies: "usd" },
43
+ }
44
+ ),
45
+ http.get("https://api.coingecko.com/api/v3/simple/price", {
46
+ params: { ids: "ethereum", vs_currencies: "usd" },
47
+ }),
48
+ http.get("https://api.coingecko.com/api/v3/simple/price", {
49
+ params: { ids: "avalanche-2", vs_currencies: "usd" },
50
+ }),
51
+ http.get("https://api.coingecko.com/api/v3/simple/price", {
52
+ params: { ids: "matic-network", vs_currencies: "usd" },
53
+ }),
54
+ ]);
55
+
56
+ this.networkTokenPrices = {
57
+ "1": ethResponse.data.ethereum.usd.toString(),
58
+ "137": polygonResponse.data["matic-network"].usd.toString(),
59
+ "43114": avaxResponse.data["avalanche-2"].usd.toString(),
60
+ };
61
+
62
+ const data = response.data;
63
+
64
+ for (const key in data) {
65
+ const _key = Web3Utils.toChecksumAddress(key);
66
+ if (!data[key].usd) continue;
67
+ this.mainnetPrices[_key] = data[key].usd.toString();
68
+ }
69
+
70
+ this.mainnetPrices["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"] =
71
+ ethResponse.data.ethereum.usd.toString();
72
+ } catch (error) { }
73
+
74
+ fs.writeFileSync(mainnetPricesFilePath, JSON.stringify(this.mainnetPrices));
75
+ fs.writeFileSync(networkTokenPricesFilePath, JSON.stringify(this.networkTokenPrices));
76
+
77
+ return this.mainnetPrices;
78
+ }
79
+
80
+ static getMainnetPrices() {
81
+ return this.mainnetPrices;
82
+ }
83
+
84
+ static getNetworkTokenPrices() {
85
+ return this.networkTokenPrices;
86
+ }
87
+ }
88
+
89
+ export default Prices;
@@ -0,0 +1 @@
1
+ export { default as Prices } from './Prices';
@@ -5,12 +5,18 @@ import abi from "@/abi";
5
5
  import { Transaction } from "@/db";
6
6
  import {
7
7
  buildSignatureBytes,
8
+ chainIdToName,
9
+ generateGnosisSignatureMessage,
8
10
  generateGnosisTransaction,
9
- generateInteropTransactionHash,
11
+ getChainIdNativeSymbol,
10
12
  getContract,
13
+ getExplorerUrl,
11
14
  getRpcProviderUrl,
12
- LiquidityError,
13
15
  Signature,
16
+ validateChains,
17
+ validateLiquidityCap,
18
+ validateSourceLiquidity,
19
+ getGnosisSignatureAddress,
14
20
  } from "@/utils";
15
21
  import { addresses, blockConfirmations } from "@/constants";
16
22
  import { ChainId } from "@/types";
@@ -22,9 +28,13 @@ import { buildGnosisAction } from "@/gnosis";
22
28
  import { peerPool, protocol } from "@/net";
23
29
  import { LogDescription } from "ethers/lib/utils";
24
30
  import wait from "waait";
31
+ import { LiquidityError, UnsupportedChaindIdError } from "@/errors";
32
+ import { BigNumber } from "bignumber.js";
33
+ import dedent from "dedent";
34
+ import { JsonRpcRetryProvider } from "@/providers";
25
35
 
26
- class ProcessSubmitSubmitEvents extends BaseTask {
27
- sourceProvider: ethers.providers.JsonRpcProvider;
36
+ export default class ProcessSubmitEvents extends BaseTask {
37
+ sourceProvider: JsonRpcRetryProvider;
28
38
  sourceGnosisContract: GnosisSafe;
29
39
  sourceWallet: Wallet;
30
40
  chainId: ChainId;
@@ -33,7 +43,7 @@ class ProcessSubmitSubmitEvents extends BaseTask {
33
43
 
34
44
  constructor({ chainId }: { chainId: ChainId }) {
35
45
  super({
36
- logger: new Logger("InteropX::ProcessSubmitSubmitEvents"),
46
+ logger: new Logger("InteropX::ProcessSubmitEvents"),
37
47
  });
38
48
  this.chainId = chainId;
39
49
  }
@@ -73,8 +83,50 @@ class ProcessSubmitSubmitEvents extends BaseTask {
73
83
  transaction.sourceStatus = "proccessing";
74
84
  await transaction.save();
75
85
 
76
- const ownersThreshold = await this.sourceGnosisContract.getThreshold();
77
- await wait(10000);
86
+ const { submitEvent: { position, sourceChainId, targetChainId, sourceDsaId } } = transaction;
87
+ try {
88
+ validateChains({ sourceChainId, targetChainId });
89
+ } catch (error) {
90
+ transaction.sourceErrors = [error.message];
91
+ transaction.sourceStatus = "failed";
92
+ transaction.targetStatus = "failed";
93
+ transaction.status = "failed";
94
+ await transaction.save();
95
+ return;
96
+ }
97
+
98
+ const walletBalance = (await this.sourceWallet.getBalance()).toString();
99
+ const currentGasPrice = (await this.sourceWallet.getGasPrice()).toString()
100
+
101
+ const minBalanceRequired = new BigNumber(currentGasPrice)
102
+ .multipliedBy(4_000_000)
103
+ .multipliedBy(2) // 2x balance
104
+
105
+ if (
106
+ new BigNumber(walletBalance).isLessThan(minBalanceRequired)
107
+ ) {
108
+ console.log(
109
+ dedent`Not enough balance in wallet ${getExplorerUrl(sourceChainId, '/address/' + this.sourceWallet.address)} on ${chainIdToName(sourceChainId)}
110
+ Balance: ${ethers.utils.parseEther(walletBalance)} ${getChainIdNativeSymbol(sourceChainId)}
111
+ Required Balance: ${ethers.utils.parseEther(minBalanceRequired.toString())}
112
+ Require more: ${ethers.utils.parseEther(minBalanceRequired.minus(walletBalance).toString())}`
113
+ );
114
+ transaction.sourceDelayUntil = moment().add({ minutes: 5 }).toDate();
115
+ transaction.sourceStatus = "pending";
116
+ await transaction.save();
117
+ return;
118
+ }
119
+
120
+ try {
121
+ await validateLiquidityCap(position, sourceChainId, targetChainId);
122
+ } catch (error) {
123
+ transaction.sourceErrors = [error.message];
124
+ transaction.sourceStatus = "failed";
125
+ transaction.targetStatus = "failed";
126
+ transaction.status = "failed";
127
+ await transaction.save();
128
+ return;
129
+ }
78
130
 
79
131
  this.logger.debug(`Build gnosis action for ${transaction.transactionHash}`);
80
132
 
@@ -105,6 +157,38 @@ class ProcessSubmitSubmitEvents extends BaseTask {
105
157
  return;
106
158
  }
107
159
 
160
+ try {
161
+ await validateSourceLiquidity({
162
+ position,
163
+ sourceChainId,
164
+ sourceDsaId,
165
+ sourceProvider: this.sourceProvider,
166
+ });
167
+ } catch (error) {
168
+ if (error instanceof UnsupportedChaindIdError) {
169
+ console.log(`Dropping transaction ${transaction.transactionHash}`);
170
+
171
+ transaction.sourceErrors = [error.message];
172
+ transaction.sourceStatus = "failed";
173
+ transaction.targetStatus = "failed";
174
+ transaction.status = "failed";
175
+ await transaction.save();
176
+ } else {
177
+ transaction.sourceStatus = "pending";
178
+ transaction.sourceErrors = [error.message];
179
+ transaction.sourceDelayUntil = moment().add({ minutes: 5 }).toDate();
180
+ await transaction.save();
181
+
182
+ console.log("[validateSourceLiquidity][Warning]", error.message);
183
+ return;
184
+ }
185
+ }
186
+
187
+ const ownersThreshold = await this.sourceGnosisContract.getThreshold();
188
+ await wait(10000);
189
+
190
+
191
+
108
192
  this.logger.debug(
109
193
  `Generating gnosis tx for ${transaction.transactionHash}`
110
194
  );
@@ -126,20 +210,37 @@ class ProcessSubmitSubmitEvents extends BaseTask {
126
210
  this.sourceGnosisContract
127
211
  );
128
212
 
129
- const owners = await this.sourceGnosisContract
130
- .getOwners()
131
- .then((owners) => owners.map((owner) => owner.toLowerCase()));
132
213
 
133
- const ownerPeerIds = peerPool.activePeers
134
- .filter((peer) => owners.includes(peer.publicAddress.toLowerCase()))
135
- .map((peer) => peer.id);
214
+ async function getGnosisOwnerPeerIds({
215
+ gnosisContract
216
+ }) {
217
+ const owners = await gnosisContract
218
+ .getOwners()
219
+ .then((owners) => owners.map((owner) => owner.toLowerCase()));
220
+
221
+ return peerPool.activePeers
222
+ .filter((peer) => owners.includes(peer.publicAddress.toLowerCase()))
223
+ .map((peer) => peer.id);
224
+ }
225
+
226
+ const ownerPeerIds = await getGnosisOwnerPeerIds({
227
+ gnosisContract: this.sourceGnosisContract,
228
+ });
136
229
 
137
230
  console.log(
138
- `Collecting signatures for execution ${transaction.transactionHash}`
231
+ `Collecting signatures for execution ${transaction.transactionHash} `
139
232
  );
140
233
 
141
234
  console.log(ownerPeerIds);
142
235
 
236
+ const message = generateGnosisSignatureMessage({
237
+ to: addresses[this.chainId].multisend,
238
+ data,
239
+ chainId: this.chainId,
240
+ safeTxGas: gnosisTx.safeTxGas,
241
+ nonce: gnosisTx.safeNonce,
242
+ });
243
+
143
244
  const signatures = await protocol.requestSignatures(
144
245
  {
145
246
  type: "source",
@@ -151,9 +252,27 @@ class ProcessSubmitSubmitEvents extends BaseTask {
151
252
  ownerPeerIds
152
253
  );
153
254
 
154
- const validSignatures = signatures.filter(
155
- (s) => !!s.data && s.data !== "0x"
156
- ) as Signature[];
255
+ const validSignatures = signatures
256
+ .filter(
257
+ (s) => !!s.data && s.data !== "0x"
258
+ )
259
+ .filter((s) => {
260
+
261
+ try {
262
+
263
+ const address = getGnosisSignatureAddress({
264
+ message,
265
+ signature: s.data!,
266
+ chainId: this.chainId,
267
+ })
268
+
269
+ return address?.toLowerCase() === s.signer.toLowerCase();
270
+
271
+ } catch (error) {
272
+ return false
273
+ }
274
+
275
+ }) as Signature[];
157
276
 
158
277
  console.log({
159
278
  signatures,
@@ -172,7 +291,7 @@ class ProcessSubmitSubmitEvents extends BaseTask {
172
291
  await transaction.save();
173
292
  const errorMessage = signatures.find((s) => !!s.error)?.error;
174
293
  throw new Error(
175
- `Not enough signatures` + (errorMessage ? `: ${errorMessage}` : "")
294
+ `Not enough signatures` + (errorMessage ? `: ${errorMessage} ` : "")
176
295
  );
177
296
  }
178
297
 
@@ -220,7 +339,7 @@ class ProcessSubmitSubmitEvents extends BaseTask {
220
339
  receipt.logs.forEach((log) => {
221
340
  try {
222
341
  parsedLogs.push(this.sourceGnosisContract.interface.parseLog(log));
223
- } catch (e) {}
342
+ } catch (e) { }
224
343
  });
225
344
 
226
345
  if (parsedLogs.find((e) => e.name === "ExecutionSuccess")) {
@@ -247,7 +366,7 @@ class ProcessSubmitSubmitEvents extends BaseTask {
247
366
  async start(): Promise<void> {
248
367
  this.blockConfirmationsCount = blockConfirmations[this.chainId] + 1;
249
368
 
250
- this.sourceProvider = new ethers.providers.JsonRpcProvider(
369
+ this.sourceProvider = new JsonRpcRetryProvider(
251
370
  getRpcProviderUrl(this.chainId)
252
371
  );
253
372
 
@@ -265,5 +384,3 @@ class ProcessSubmitSubmitEvents extends BaseTask {
265
384
  await super.start();
266
385
  }
267
386
  }
268
-
269
- export default ProcessSubmitSubmitEvents;
@@ -5,11 +5,12 @@ import abi from "@/abi";
5
5
  import { Transaction } from "@/db";
6
6
  import {
7
7
  buildSignatureBytes,
8
+ generateGnosisSignatureMessage,
8
9
  generateGnosisTransaction,
9
- generateInteropTransactionHash,
10
10
  getContract,
11
+ getGnosisOwnerPeerIds,
12
+ getGnosisSignatureAddress,
11
13
  getRpcProviderUrl,
12
- LiquidityError,
13
14
  Signature,
14
15
  } from "@/utils";
15
16
  import { addresses, blockConfirmations } from "@/constants";
@@ -22,9 +23,11 @@ import { buildGnosisAction } from "@/gnosis";
22
23
  import { peerPool, protocol } from "@/net";
23
24
  import { LogDescription } from "ethers/lib/utils";
24
25
  import wait from "waait";
26
+ import { LiquidityError } from "@/errors";
27
+ import { JsonRpcRetryProvider } from "@/providers";
25
28
 
26
- class ProcessValidateEvents extends BaseTask {
27
- sourceProvider: ethers.providers.JsonRpcProvider;
29
+ export default class ProcessValidateEvents extends BaseTask {
30
+ sourceProvider: JsonRpcRetryProvider;
28
31
  chainId: ChainId;
29
32
  leadNodeOnly: boolean = true;
30
33
  blockConfirmationsCount: number = 12;
@@ -75,7 +78,7 @@ class ProcessValidateEvents extends BaseTask {
75
78
 
76
79
  const { sourceChainId, targetChainId } = transaction.validateEvent
77
80
 
78
- const targetProvider = new ethers.providers.JsonRpcProvider(
81
+ const targetProvider = new JsonRpcRetryProvider(
79
82
  getRpcProviderUrl(targetChainId as ChainId)
80
83
  );
81
84
 
@@ -141,13 +144,9 @@ class ProcessValidateEvents extends BaseTask {
141
144
  targetGnosisContract
142
145
  );
143
146
 
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);
147
+ const ownerPeerIds = await getGnosisOwnerPeerIds({
148
+ gnosisContract: targetGnosisContract,
149
+ });
151
150
 
152
151
  console.log(
153
152
  `Collecting signatures for execution ${transaction.transactionHash}`
@@ -155,6 +154,14 @@ class ProcessValidateEvents extends BaseTask {
155
154
 
156
155
  console.log(ownerPeerIds);
157
156
 
157
+ const message = generateGnosisSignatureMessage({
158
+ to: addresses[targetChainId].multisend,
159
+ data,
160
+ chainId: targetChainId as ChainId,
161
+ safeTxGas: gnosisTx.safeTxGas,
162
+ nonce: gnosisTx.safeNonce,
163
+ });
164
+
158
165
  const signatures = await protocol.requestSignatures(
159
166
  {
160
167
  type: "target",
@@ -166,9 +173,27 @@ class ProcessValidateEvents extends BaseTask {
166
173
  ownerPeerIds
167
174
  );
168
175
 
169
- const validSignatures = signatures.filter(
170
- (s) => !!s.data && s.data !== "0x"
171
- ) as Signature[];
176
+ const validSignatures = signatures
177
+ .filter(
178
+ (s) => !!s.data && s.data !== "0x"
179
+ )
180
+ .filter((s) => {
181
+
182
+ try {
183
+
184
+ const address = getGnosisSignatureAddress({
185
+ message,
186
+ signature: s.data!,
187
+ chainId: targetChainId as ChainId,
188
+ })
189
+
190
+ return address?.toLowerCase() === s.signer.toLowerCase();
191
+
192
+ } catch (error) {
193
+ return false
194
+ }
195
+
196
+ }) as Signature[];
172
197
 
173
198
  console.log({
174
199
  signatures,
@@ -263,12 +288,10 @@ class ProcessValidateEvents extends BaseTask {
263
288
  async start(): Promise<void> {
264
289
  this.blockConfirmationsCount = blockConfirmations[this.chainId] + 1;
265
290
 
266
- this.sourceProvider = new ethers.providers.JsonRpcProvider(
291
+ this.sourceProvider = new JsonRpcRetryProvider(
267
292
  getRpcProviderUrl(this.chainId)
268
293
  );
269
294
 
270
295
  await super.start();
271
296
  }
272
- }
273
-
274
- export default ProcessValidateEvents;
297
+ }
@@ -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 transaction: ${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: ethers.providers.JsonRpcProvider;
19
+ provider: JsonRpcRetryProvider;
19
20
  contract: InteropX;
20
21
  chainId: ChainId;
21
22
 
@@ -109,7 +110,7 @@ class SyncLogSubmitEvents extends BaseTask {
109
110
  },
110
111
  });
111
112
 
112
- this.logger.info(`New InteropX tranaction: ${transactionHash} `);
113
+ this.logger.info(`New InteropX transaction: ${transactionHash} `);
113
114
  } catch (error) {
114
115
  this.logger.error(error);
115
116
  }
@@ -122,7 +123,7 @@ class SyncLogSubmitEvents extends BaseTask {
122
123
  async start(): Promise<void> {
123
124
  this.contractAddress = addresses[this.chainId].interopX;
124
125
 
125
- this.provider = new ethers.providers.JsonRpcProvider(
126
+ this.provider = new JsonRpcRetryProvider(
126
127
  getRpcProviderUrl(this.chainId)
127
128
  );
128
129
 
@@ -134,6 +135,4 @@ class SyncLogSubmitEvents extends BaseTask {
134
135
 
135
136
  await super.start();
136
137
  }
137
- }
138
-
139
- export default SyncLogSubmitEvents;
138
+ }