xiongzhu hace 2 años
padre
commit
ff39204764

+ 2 - 0
src/task/enums/task-type.enum.ts

@@ -5,6 +5,8 @@ export enum TaskType {
     orbiter2eth = 'orbiter2eth',
     orbiter2eth = 'orbiter2eth',
     swapUsdc = 'swapUsdc',
     swapUsdc = 'swapUsdc',
     swapEth = 'swapEth',
     swapEth = 'swapEth',
+    syncSwapUsdc = 'syncSwapUsdc',
+    syncSwapEth = 'syncSwapEth',
     addLiquidity = 'addLiquidity',
     addLiquidity = 'addLiquidity',
     removeLiquidity = 'removeLiquidity',
     removeLiquidity = 'removeLiquidity',
     mint = 'mint'
     mint = 'mint'

+ 26 - 0
src/task/task.service.ts

@@ -174,6 +174,32 @@ export class TaskService implements OnModuleInit {
                                 'usdc'
                                 'usdc'
                             )
                             )
                             break
                             break
+                        case TaskType.syncSwapUsdc:
+                            web3Result = await this.web3Service.swapSyncSwap(
+                                accountId,
+                                taskItem.amountType === 'amount'
+                                    ? randomAmount(taskItem.amount.min, taskItem.amount.max)
+                                    : randomBalancePercent(
+                                          await this.accountsService.getZkBalance(account),
+                                          taskItem.percent.min,
+                                          taskItem.percent.max
+                                      ),
+                                'eth'
+                            )
+                            break
+                        case TaskType.syncSwapEth:
+                            web3Result = await this.web3Service.swapSyncSwap(
+                                accountId,
+                                taskItem.amountType === 'amount'
+                                    ? randomAmount(taskItem.amount.min, taskItem.amount.max)
+                                    : randomBalancePercent(
+                                          await this.accountsService.getUsdcBalance(account),
+                                          taskItem.percent.min,
+                                          taskItem.percent.max
+                                      ),
+                                'usdc'
+                            )
+                            break
                         case TaskType.addLiquidity:
                         case TaskType.addLiquidity:
                             web3Result = await this.web3Service.addLiquidity(
                             web3Result = await this.web3Service.addLiquidity(
                                 accountId,
                                 accountId,

+ 924 - 0
src/web3/abi/SyncSwapClassicPool.json

@@ -0,0 +1,924 @@
+[
+    {
+      "inputs": [],
+      "stateMutability": "nonpayable",
+      "type": "constructor"
+    },
+    {
+      "inputs": [],
+      "name": "Expired",
+      "type": "error"
+    },
+    {
+      "inputs": [],
+      "name": "InsufficientLiquidityMinted",
+      "type": "error"
+    },
+    {
+      "inputs": [],
+      "name": "InvalidSignature",
+      "type": "error"
+    },
+    {
+      "inputs": [],
+      "name": "Overflow",
+      "type": "error"
+    },
+    {
+      "anonymous": false,
+      "inputs": [
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "owner",
+          "type": "address"
+        },
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "spender",
+          "type": "address"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount",
+          "type": "uint256"
+        }
+      ],
+      "name": "Approval",
+      "type": "event"
+    },
+    {
+      "anonymous": false,
+      "inputs": [
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "sender",
+          "type": "address"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount0",
+          "type": "uint256"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount1",
+          "type": "uint256"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "liquidity",
+          "type": "uint256"
+        },
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "to",
+          "type": "address"
+        }
+      ],
+      "name": "Burn",
+      "type": "event"
+    },
+    {
+      "anonymous": false,
+      "inputs": [
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "sender",
+          "type": "address"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount0",
+          "type": "uint256"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount1",
+          "type": "uint256"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "liquidity",
+          "type": "uint256"
+        },
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "to",
+          "type": "address"
+        }
+      ],
+      "name": "Mint",
+      "type": "event"
+    },
+    {
+      "anonymous": false,
+      "inputs": [
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "sender",
+          "type": "address"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount0In",
+          "type": "uint256"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount1In",
+          "type": "uint256"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount0Out",
+          "type": "uint256"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount1Out",
+          "type": "uint256"
+        },
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "to",
+          "type": "address"
+        }
+      ],
+      "name": "Swap",
+      "type": "event"
+    },
+    {
+      "anonymous": false,
+      "inputs": [
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "reserve0",
+          "type": "uint256"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "reserve1",
+          "type": "uint256"
+        }
+      ],
+      "name": "Sync",
+      "type": "event"
+    },
+    {
+      "anonymous": false,
+      "inputs": [
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "from",
+          "type": "address"
+        },
+        {
+          "indexed": true,
+          "internalType": "address",
+          "name": "to",
+          "type": "address"
+        },
+        {
+          "indexed": false,
+          "internalType": "uint256",
+          "name": "amount",
+          "type": "uint256"
+        }
+      ],
+      "name": "Transfer",
+      "type": "event"
+    },
+    {
+      "inputs": [],
+      "name": "DOMAIN_SEPARATOR",
+      "outputs": [
+        {
+          "internalType": "bytes32",
+          "name": "",
+          "type": "bytes32"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "",
+          "type": "address"
+        }
+      ],
+      "name": "allowance",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "_spender",
+          "type": "address"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_amount",
+          "type": "uint256"
+        }
+      ],
+      "name": "approve",
+      "outputs": [
+        {
+          "internalType": "bool",
+          "name": "",
+          "type": "bool"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "",
+          "type": "address"
+        }
+      ],
+      "name": "balanceOf",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "bytes",
+          "name": "_data",
+          "type": "bytes"
+        },
+        {
+          "internalType": "address",
+          "name": "_sender",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "_callback",
+          "type": "address"
+        },
+        {
+          "internalType": "bytes",
+          "name": "_callbackData",
+          "type": "bytes"
+        }
+      ],
+      "name": "burn",
+      "outputs": [
+        {
+          "components": [
+            {
+              "internalType": "address",
+              "name": "token",
+              "type": "address"
+            },
+            {
+              "internalType": "uint256",
+              "name": "amount",
+              "type": "uint256"
+            }
+          ],
+          "internalType": "struct IPool.TokenAmount[]",
+          "name": "_amounts",
+          "type": "tuple[]"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "bytes",
+          "name": "_data",
+          "type": "bytes"
+        },
+        {
+          "internalType": "address",
+          "name": "_sender",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "_callback",
+          "type": "address"
+        },
+        {
+          "internalType": "bytes",
+          "name": "_callbackData",
+          "type": "bytes"
+        }
+      ],
+      "name": "burnSingle",
+      "outputs": [
+        {
+          "components": [
+            {
+              "internalType": "address",
+              "name": "token",
+              "type": "address"
+            },
+            {
+              "internalType": "uint256",
+              "name": "amount",
+              "type": "uint256"
+            }
+          ],
+          "internalType": "struct IPool.TokenAmount",
+          "name": "_tokenAmount",
+          "type": "tuple"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "decimals",
+      "outputs": [
+        {
+          "internalType": "uint8",
+          "name": "",
+          "type": "uint8"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "_tokenOut",
+          "type": "address"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_amountOut",
+          "type": "uint256"
+        },
+        {
+          "internalType": "address",
+          "name": "_sender",
+          "type": "address"
+        }
+      ],
+      "name": "getAmountIn",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "_amountIn",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "_tokenIn",
+          "type": "address"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_amountIn",
+          "type": "uint256"
+        },
+        {
+          "internalType": "address",
+          "name": "_sender",
+          "type": "address"
+        }
+      ],
+      "name": "getAmountOut",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "_amountOut",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "getAssets",
+      "outputs": [
+        {
+          "internalType": "address[]",
+          "name": "assets",
+          "type": "address[]"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "getProtocolFee",
+      "outputs": [
+        {
+          "internalType": "uint24",
+          "name": "_protocolFee",
+          "type": "uint24"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "getReserves",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "_reserve0",
+          "type": "uint256"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_reserve1",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "_sender",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "_tokenIn",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "_tokenOut",
+          "type": "address"
+        },
+        {
+          "internalType": "bytes",
+          "name": "data",
+          "type": "bytes"
+        }
+      ],
+      "name": "getSwapFee",
+      "outputs": [
+        {
+          "internalType": "uint24",
+          "name": "_swapFee",
+          "type": "uint24"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "invariantLast",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "master",
+      "outputs": [
+        {
+          "internalType": "address",
+          "name": "",
+          "type": "address"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "bytes",
+          "name": "_data",
+          "type": "bytes"
+        },
+        {
+          "internalType": "address",
+          "name": "_sender",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "_callback",
+          "type": "address"
+        },
+        {
+          "internalType": "bytes",
+          "name": "_callbackData",
+          "type": "bytes"
+        }
+      ],
+      "name": "mint",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "name",
+      "outputs": [
+        {
+          "internalType": "string",
+          "name": "",
+          "type": "string"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "",
+          "type": "address"
+        }
+      ],
+      "name": "nonces",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "_owner",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "_spender",
+          "type": "address"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_amount",
+          "type": "uint256"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_deadline",
+          "type": "uint256"
+        },
+        {
+          "internalType": "uint8",
+          "name": "_v",
+          "type": "uint8"
+        },
+        {
+          "internalType": "bytes32",
+          "name": "_r",
+          "type": "bytes32"
+        },
+        {
+          "internalType": "bytes32",
+          "name": "_s",
+          "type": "bytes32"
+        }
+      ],
+      "name": "permit",
+      "outputs": [],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "_owner",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "_spender",
+          "type": "address"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_amount",
+          "type": "uint256"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_deadline",
+          "type": "uint256"
+        },
+        {
+          "internalType": "bytes",
+          "name": "_signature",
+          "type": "bytes"
+        }
+      ],
+      "name": "permit2",
+      "outputs": [],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "poolType",
+      "outputs": [
+        {
+          "internalType": "uint16",
+          "name": "",
+          "type": "uint16"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "reserve0",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "reserve1",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "bytes4",
+          "name": "interfaceID",
+          "type": "bytes4"
+        }
+      ],
+      "name": "supportsInterface",
+      "outputs": [
+        {
+          "internalType": "bool",
+          "name": "",
+          "type": "bool"
+        }
+      ],
+      "stateMutability": "pure",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "bytes",
+          "name": "_data",
+          "type": "bytes"
+        },
+        {
+          "internalType": "address",
+          "name": "_sender",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "_callback",
+          "type": "address"
+        },
+        {
+          "internalType": "bytes",
+          "name": "_callbackData",
+          "type": "bytes"
+        }
+      ],
+      "name": "swap",
+      "outputs": [
+        {
+          "components": [
+            {
+              "internalType": "address",
+              "name": "token",
+              "type": "address"
+            },
+            {
+              "internalType": "uint256",
+              "name": "amount",
+              "type": "uint256"
+            }
+          ],
+          "internalType": "struct IPool.TokenAmount",
+          "name": "_tokenAmount",
+          "type": "tuple"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "symbol",
+      "outputs": [
+        {
+          "internalType": "string",
+          "name": "",
+          "type": "string"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "token0",
+      "outputs": [
+        {
+          "internalType": "address",
+          "name": "",
+          "type": "address"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "token1",
+      "outputs": [
+        {
+          "internalType": "address",
+          "name": "",
+          "type": "address"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "totalSupply",
+      "outputs": [
+        {
+          "internalType": "uint256",
+          "name": "",
+          "type": "uint256"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "_to",
+          "type": "address"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_amount",
+          "type": "uint256"
+        }
+      ],
+      "name": "transfer",
+      "outputs": [
+        {
+          "internalType": "bool",
+          "name": "",
+          "type": "bool"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [
+        {
+          "internalType": "address",
+          "name": "_from",
+          "type": "address"
+        },
+        {
+          "internalType": "address",
+          "name": "_to",
+          "type": "address"
+        },
+        {
+          "internalType": "uint256",
+          "name": "_amount",
+          "type": "uint256"
+        }
+      ],
+      "name": "transferFrom",
+      "outputs": [
+        {
+          "internalType": "bool",
+          "name": "",
+          "type": "bool"
+        }
+      ],
+      "stateMutability": "nonpayable",
+      "type": "function"
+    },
+    {
+      "inputs": [],
+      "name": "vault",
+      "outputs": [
+        {
+          "internalType": "address",
+          "name": "",
+          "type": "address"
+        }
+      ],
+      "stateMutability": "view",
+      "type": "function"
+    }
+  ]

+ 4 - 1
src/web3/types.ts

@@ -15,5 +15,8 @@ declare interface Web3Config {
     orbiterEthAddress: string
     orbiterEthAddress: string
     orbiterZkAddress: string
     orbiterZkAddress: string
     orbiterIdCodeZk: number
     orbiterIdCodeZk: number
-    orbiterIdCodeEth: number
+    orbiterIdCodeEth: number,
+    syncSwapPoolFactoryAddress: string,
+    syncSwapRouterAddress: string,
+    syncSwapWethAddress: string
 }
 }

+ 137 - 111
src/web3/web3.service.ts

@@ -48,6 +48,9 @@ import { FileService } from 'src/file/file.service'
 import axios from 'axios'
 import axios from 'axios'
 import * as randomString from 'randomstring'
 import * as randomString from 'randomstring'
 import { Account } from '../accounts/entities/account.entity'
 import { Account } from '../accounts/entities/account.entity'
+import SyncSwapPoolFactoryAbi from './abi/SyncSwapClassicPoolFactory.json'
+import SyncSwapPoolAbi from './abi/SyncSwapClassicPool.json'
+import SyncSwapRouterAbi from './abi/SyncSwapRouter.json'
 
 
 @Injectable()
 @Injectable()
 export class Web3Service {
 export class Web3Service {
@@ -287,128 +290,87 @@ export class Web3Service {
 
 
     async addLiquiditySyncSwap(accountId, amount) {
     async addLiquiditySyncSwap(accountId, amount) {
         const account = await this.accountService.findById(accountId)
         const account = await this.accountService.findById(accountId)
-        const chainId =
-            web3Config[account.network].ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
-        const provider = new Provider(web3Config[account.network].zksyncRpcUrl)
+        const config = web3Config[account.network]
+        const provider = new Provider(config.zksyncRpcUrl)
         const zkWallet = new Wallet(account.privateKey).connect(provider)
         const zkWallet = new Wallet(account.privateKey).connect(provider)
-        const chain = initialChainTable[chainId]
-        const web3 = new Web3(new Web3.providers.HttpProvider(web3Config[account.network].zksyncRpcUrl))
-        Logger.log(`address: ${zkWallet.address}`, 'addLiquidity')
-
-        const liquidityManagerContract = getLiquidityManagerContract(
-            web3Config[account.network].liquidityManagerAddress,
-            web3 as any
-        )
+        const web3 = new Web3(new Web3.providers.HttpProvider(config.zksyncRpcUrl))
 
 
-        const tokenA = getGasToken(chainId)
-        Logger.log(`tokenA: ${JSON.stringify(tokenA, null, 4)}`, 'addLiquidity')
-        const tokenB = await fetchToken(web3Config[account.network].zkUsdcAddress, chain, web3 as any)
-        Logger.log(`tokenB: ${JSON.stringify(tokenB, null, 4)}`, 'addLiquidity')
-
-        await this.approve(
-            tokenB.address,
-            web3Config[account.network].liquidityManagerAddress,
-            zkWallet,
-            account.network
+        Logger.log(`amount: ${amount}`, 'addLiquiditySyncSwap')
+        const poolFactory = new web3.eth.Contract(SyncSwapPoolFactoryAbi, config.syncSwapPoolFactoryAddress)
+        // @ts-ignore
+        const poolAddress = await poolFactory.methods.getPool(config.syncSwapWethAddress, config.zkUsdcAddress).call()
+        Logger.log(`poolAddress: ${poolAddress}`, 'addLiquiditySyncSwap')
+
+        const router = new web3.eth.Contract(SyncSwapRouterAbi, config.syncSwapRouterAddress)
+        const addLiquidity = router.methods.addLiquidity2(
+            // @ts-ignore
+            poolAddress,
+            [
+                [ethers.constants.AddressZero, ethers.utils.parseEther(amount).toString()],
+                [config.zkUsdcAddress, ethers.utils.parseUnits('0', 6).toString()]
+            ],
+            //encode abi
+            ethers.utils.defaultAbiCoder.encode(['uint256'], [zkWallet.address]),
+            0,
+            ethers.constants.AddressZero,
+            '0x'
         )
         )
 
 
-        const fee = 2000 // 2000 means 0.2%
-        const poolAddress = await getPoolAddress(liquidityManagerContract, tokenA, tokenB, fee)
-        Logger.log(`poolAddress: ${poolAddress}`, 'addLiquidity')
-
-        const poolContract = getPoolContract(poolAddress, web3 as any)
-        const state = await getPoolState(poolContract)
-        const currentPrice = point2PriceDecimal(tokenA, tokenB, state.currentPoint)
-        Logger.log(`current point: ${state.currentPoint}`, 'addLiquidity')
-
-        const point1 = priceDecimal2Point(tokenA, tokenB, currentPrice * 0.98, PriceRoundingType.PRICE_ROUNDING_NEAREST)
-        const point2 = priceDecimal2Point(tokenA, tokenB, currentPrice * 1.02, PriceRoundingType.PRICE_ROUNDING_NEAREST)
-        Logger.log(`point range: ${point1} - ${point2}`, 'addLiquidity')
-        let leftPoint = Math.min(point1, point2)
-        let rightPoint = Math.max(point1, point2)
-        const pointDelta = await getPointDelta(poolContract)
-        Logger.log(`point delta: ${pointDelta}`, 'addLiquidity')
-        leftPoint = pointDeltaRoundingDown(leftPoint, pointDelta)
-        rightPoint = pointDeltaRoundingUp(rightPoint, pointDelta)
-
-        const maxTestA = new BigNumber(amount).times(10 ** tokenA.decimal)
-        const maxTestB = calciZiLiquidityAmountDesired(
-            leftPoint,
-            rightPoint,
-            state.currentPoint,
-            maxTestA,
-            true,
-            tokenA,
-            tokenB
-        )
-        const mintParams = {
-            tokenA: tokenA,
-            tokenB: tokenB,
-            fee,
-            leftPoint,
-            rightPoint,
-            maxAmountA: maxTestA.toFixed(0),
-            maxAmountB: maxTestB.toFixed(0),
-            minAmountA: maxTestA.times(0.985).toFixed(0),
-            minAmountB: maxTestB.times(0.985).toFixed(0)
-        }
+        const gasLimit = await addLiquidity.estimateGas({
+            from: zkWallet.address,
+            value: ethers.utils.parseEther(amount).toString()
+        })
+        const tx = await zkWallet.sendTransaction({
+            // from: wallet.address,
+            to: config.syncSwapRouterAddress,
+            data: addLiquidity.encodeABI(),
+            value: ethers.utils.parseEther(amount).toString(),
+            gasLimit
+        })
+        Logger.log(`transaction sent: ${tx.hash}`, 'addLiquiditySyncSwap')
+        return new Web3Result(account.address, tx.hash, config, true)
+    }
 
 
-        Logger.log(
-            `tokenAtoPay: ${amount2Decimal(new BigNumber(maxTestA), tokenA)}, tokenBtoPay: ${amount2Decimal(
-                new BigNumber(maxTestB),
-                tokenB
-            )}, price: ${point2PriceDecimal(tokenA, tokenB, state.currentPoint)}`,
-            'addLiquidity'
-        )
-        const balanceA = await zkWallet.getBalance()
-        const balanceB = await zkWallet.getBalance(tokenB.address)
-        if (new BigNumber(balanceA.toString()).lt(maxTestA)) {
-            throw new InternalServerErrorException(
-                `${tokenA.symbol}余额不足, 需要${ethers.utils.formatUnits(
-                    maxTestA.toString(),
-                    tokenA.decimal
-                )}, 当前${ethers.utils.formatUnits(balanceA, tokenA.decimal)}`
-            )
-        }
-        if (new BigNumber(balanceB.toString()).lt(maxTestB)) {
-            throw new InternalServerErrorException(
-                `${tokenB.symbol}余额不足, 需要${ethers.utils.formatUnits(
-                    maxTestB.toString(),
-                    tokenB.decimal
-                )}, 当前${ethers.utils.formatUnits(balanceB, tokenB.decimal)}`
-            )
-        }
+    async removeLiquiditySyncSwap(accountId) {
+        const account = await this.accountService.findById(accountId)
+        const config = web3Config[account.network]
+        const provider = new Provider(config.zksyncRpcUrl)
+        const zkWallet = new Wallet(account.privateKey).connect(provider)
+        const web3 = new Web3(new Web3.providers.HttpProvider(config.zksyncRpcUrl))
 
 
-        Logger.log(`mintParams: ${JSON.stringify(mintParams, null, 4)}`, 'addLiquidity')
+        const poolFactory = new web3.eth.Contract(SyncSwapPoolFactoryAbi, config.syncSwapPoolFactoryAddress)
+        // @ts-ignore
+        const poolAddress = await poolFactory.methods.getPool(config.syncSwapWethAddress, config.zkUsdcAddress).call()
+        Logger.log(`poolAddress: ${poolAddress}`, 'removeLiquiditySyncSwap')
 
 
-        const gasPrice = await web3.eth.getGasPrice()
-        const { mintCalling, options } = getMintCall(
-            liquidityManagerContract,
-            zkWallet.address,
-            chain,
-            mintParams,
-            gasPrice.toString()
+        const pool = new web3.eth.Contract(SyncSwapPoolAbi, poolAddress as unknown as string)
+        // @ts-ignore
+        const liquidity = await pool.methods.balanceOf(zkWallet.address).call()
+        Logger.log(`liquidity: ${liquidity}`, 'removeLiquiditySyncSwap')
+
+        const router = new web3.eth.Contract(SyncSwapRouterAbi, config.syncSwapRouterAddress)
+        const burnLiquiditySingle = router.methods.burnLiquiditySingle(
+            // @ts-ignore
+            poolAddress,
+            liquidity,
+            ethers.utils.defaultAbiCoder.encode(
+                ['uint256', 'uint256', 'uint8'],
+                [ethers.constants.AddressZero, zkWallet.address, '0']
+            ),
+            '0',
+            ethers.constants.AddressZero,
+            '0x'
         )
         )
-        let calling = mintCalling
-        if (calling instanceof Array) {
-            calling = liquidityManagerContract.methods.multicall(mintCalling)
-        }
-        const gasLimit = await calling.estimateGas({ from: zkWallet.address })
-        Logger.log(`gas limit: ${gasLimit}`, 'addLiquidity')
-
-        // sign transaction
+        const gasLimit = await burnLiquiditySingle.estimateGas({
+            from: zkWallet.address
+        })
         const tx = await zkWallet.sendTransaction({
         const tx = await zkWallet.sendTransaction({
-            from: options.from,
-            value: Web3.utils.numberToHex(options.value),
-            to: web3Config[account.network].liquidityManagerAddress,
-            data: calling.encodeABI(),
+            to: config.syncSwapRouterAddress,
+            data: burnLiquiditySingle.encodeABI(),
             gasLimit
             gasLimit
         })
         })
-        Logger.log(`tx hash: ${tx.hash}`, 'addLiquidity')
-        account.addLiuidityNum = (account.addLiuidityNum || 0) + 1
-        account.lastAddLiuidity = new Date()
-        await this.accountService.save([account])
-        return new Web3Result(account.address, tx.hash, web3Config[account.network], true)
+        Logger.log(`transaction sent: ${tx.hash}`, 'removeLiquiditySyncSwap')
+        return new Web3Result(account.address, tx.hash, config, true)
     }
     }
 
 
     async removeLiquidity(accountId) {
     async removeLiquidity(accountId) {
@@ -673,6 +635,70 @@ export class Web3Service {
         return new Web3Result(account.address, tx.hash, web3Config[account.network], true)
         return new Web3Result(account.address, tx.hash, web3Config[account.network], true)
     }
     }
 
 
+    async swapSyncSwap(accountId, amount, inputToken: 'eth' | 'usdc' = 'usdc') {
+        const account = await this.accountService.findById(accountId)
+        const config = web3Config[account.network]
+        const provider = new Provider(config.zksyncRpcUrl)
+        const zkWallet = new Wallet(account.privateKey).connect(provider)
+        const web3 = new Web3(new Web3.providers.HttpProvider(config.zksyncRpcUrl))
+
+        if (inputToken === 'usdc') {
+            await this.approve(config.zkUsdcAddress, config.syncSwapRouterAddress, zkWallet, account.network)
+        }
+
+        Logger.log(`inputToken: ${inputToken}, amounnt=${amount}`, 'swapSyncSwap')
+        const poolFactory = new web3.eth.Contract(SyncSwapPoolFactoryAbi, config.syncSwapPoolFactoryAddress)
+        // @ts-ignore
+        const poolAddress = await poolFactory.methods.getPool(config.syncSwapWethAddress, config.zkUsdcAddress).call()
+        Logger.log(`poolAddress: ${poolAddress}`, 'addLiquiditySyncSwap')
+
+        const router = new web3.eth.Contract(SyncSwapRouterAbi, config.syncSwapRouterAddress)
+        const value =
+            inputToken === 'eth'
+                ? ethers.utils.parseEther(amount).toString()
+                : ethers.utils.parseUnits(amount, 6).toString()
+        const swap = router.methods.swap(
+            // @ts-ignore
+            [
+                [
+                    [
+                        [
+                            poolAddress,
+                            ethers.utils.defaultAbiCoder.encode(
+                                ['address', 'address', 'uint8'],
+                                [
+                                    inputToken === 'eth' ? config.syncSwapWethAddress : config.zkUsdcAddress,
+                                    zkWallet.address,
+                                    1
+                                ]
+                            ),
+                            ethers.constants.AddressZero,
+                            '0x'
+                        ]
+                    ],
+                    inputToken === 'eth' ? ethers.constants.AddressZero : config.zkUsdcAddress,
+                    value
+                ]
+            ],
+            0,
+            ethers.constants.AddressZero,
+            '0x'
+        )
+
+        const gasLimit = await swap.estimateGas({
+            from: zkWallet.address
+        })
+        const tx = await zkWallet.sendTransaction({
+            // from: wallet.address,
+            to: config.syncSwapRouterAddress,
+            data: swap.encodeABI(),
+            value: value,
+            gasLimit
+        })
+        Logger.log(`transaction sent: ${tx.hash}`, 'swapSyncSwap')
+        return new Web3Result(account.address, tx.hash, config, true)
+    }
+
     async mint(accountId) {
     async mint(accountId) {
         // const { data: buffer } = await axios.get('https://cataas.com/cat', {
         // const { data: buffer } = await axios.get('https://cataas.com/cat', {
         //     responseType: 'arraybuffer'
         //     responseType: 'arraybuffer'

+ 8 - 2
src/web3/web3config.ts

@@ -14,7 +14,10 @@ const web3Config: { [key: string]: Web3Config } = {
         orbiterEthAddress: '0x4eAF936c172b5e5511959167e8Ab4f7031113Ca3',
         orbiterEthAddress: '0x4eAF936c172b5e5511959167e8Ab4f7031113Ca3',
         orbiterIdCodeZk: 9514,
         orbiterIdCodeZk: 9514,
         orbiterZkAddress: '0x4eAF936c172b5e5511959167e8Ab4f7031113Ca3',
         orbiterZkAddress: '0x4eAF936c172b5e5511959167e8Ab4f7031113Ca3',
-        orbiterIdCodeEth: 9005
+        orbiterIdCodeEth: 9005,
+        syncSwapPoolFactoryAddress: '0xf2FD2bc2fBC12842aAb6FbB8b1159a6a83E72006',
+        syncSwapRouterAddress: '0xB3b7fCbb8Db37bC6f572634299A58f51622A847e',
+        syncSwapWethAddress: '0x20b28b1e4665fff290650586ad76e977eab90c5d'
     },
     },
     mainnet: {
     mainnet: {
         ethereumNetwork: 'mainnet',
         ethereumNetwork: 'mainnet',
@@ -31,7 +34,10 @@ const web3Config: { [key: string]: Web3Config } = {
         orbiterEthAddress: '0xee73323912a4e3772B74eD0ca1595a152b0ef282',
         orbiterEthAddress: '0xee73323912a4e3772B74eD0ca1595a152b0ef282',
         orbiterIdCodeZk: 9014,
         orbiterIdCodeZk: 9014,
         orbiterZkAddress: '0xee73323912a4e3772B74eD0ca1595a152b0ef282',
         orbiterZkAddress: '0xee73323912a4e3772B74eD0ca1595a152b0ef282',
-        orbiterIdCodeEth: 9001
+        orbiterIdCodeEth: 9001,
+        syncSwapPoolFactoryAddress: '0xf2DAd89f2788a8CD54625C60b55cD3d2D0ACa7Cb',
+        syncSwapRouterAddress: '0x2da10A1e27bF85cEdD8FFb1AbBe97e53391C0295',
+        syncSwapWethAddress: '0x5aea5775959fbc2557cc8789bc1bf90a239d9a91'
     }
     }
 }
 }
 export { web3Config }
 export { web3Config }