소스 검색

新lp构造程序OK

skyfffire 3 년 전
부모
커밋
a57ec3921e
2개의 변경된 파일644개의 추가작업 그리고 343개의 파일을 삭제
  1. 298 343
      scripts/lp/lpGenerate.ts
  2. 346 0
      scripts/path/level2Maintenance.ts

+ 298 - 343
scripts/lp/lpGenerate.ts

@@ -1,343 +1,298 @@
-// import { web3 } from "hardhat";
-// import History from "../interface/history";
-// import contracts from "../../config/contracts";
-// import logger from "../../utils/logger";
-// import {BigNumber} from "ethers";
-// import {replaceAll} from "hardhat/internal/util/strings";
-// import swapPath from "../interface/swapPath";
-// import history from "../interface/history";
-// const ierc20abi = require('../../abi/IERC20_ABI.json')
-//
-// export class PullAndPush {
-//   fromHead: boolean = false
-//   isFirst: boolean = false
-//   tokenInstance: any = {}
-//   maxMemoryOfByte: number = 0
-//
-//   constructor (_fromHead: boolean, _isFirst: boolean) {
-//     this.fromHead = _fromHead
-//     this.isFirst = _isFirst
-//   }
-//
-//   async handlePosition(routerObj: any) {
-//     const block = routerObj.type === 'univ2' ? 'UNIV2DEX' : 'UNIV3DEX'
-//     const hash = routerObj.type === 'univ2' ? routerObj.factory : routerObj.router + '_router'
-//
-//     try {
-//       // 拉取当前pull状态信息
-//       const pullState = await History.findByHashOrBlockOrDataVague(block, hash, '', 0, 200)
-//       let nowPosition = 0
-//
-//       // 没有状态信息的情况
-//       if (pullState.data.length == 0) {
-//         await History.appendOrUpdate(block, hash, {"now": nowPosition})
-//       } else {
-//         nowPosition = pullState.data[0].dataObj.now
-//       }
-//
-//       return nowPosition
-//     } catch (e) {
-//       logger.error(`Pull state error, router: ${routerObj.router}, factory: ${routerObj.factory}`)
-//       logger.error(e)
-//     }
-//
-//     return 0
-//   }
-//
-//   async getV2PoolByPosition(routerObj: any, position: number, v2ToolBy410: any) {
-//     try {
-//       const info = await v2ToolBy410.methods.getPairIdInfo(routerObj.factory, position).call()
-//
-//       const symbol0 = info['2'].replace(/[^A-Za-z0-9]+/g, '').substring(0, 10)
-//       const symbol1 = info['6'].replace(/[^A-Za-z0-9]+/g, '').substring(0, 10)
-//       const name = `${routerObj.name}_${symbol0}_${symbol1}`
-//       const sum2 = replaceAll(BigNumber.from(info['1']).add(BigNumber.from(info['5']))._hex, '0x0', '0x')
-//
-//       const lp = {
-//         LP: info['0'],
-//         decimals0: info['3'],
-//         decimals1: info['7'],
-//         factory: routerObj.factory,
-//         feei: routerObj.fee,
-//         id: position,
-//         name: name,
-//         r0: info['4'],
-//         r1: info['8'],
-//         router: routerObj.router,
-//         sum2: sum2,
-//         symbol0: symbol0,
-//         symbol1: symbol1,
-//         token0: info['1'],
-//         token1: info['5'],
-//         isEthW: routerObj.type == 'ETHW'
-//       }
-//
-//       // 更新一次position
-//       await History.appendOrUpdate('UNIV2DEX', routerObj.factory, {"now": position + 1})
-//
-//       return lp
-//     } catch (e) {}
-//
-//     return undefined
-//   }
-//
-//   async getV3Pool(routerObj: any, position: number, v3Tool: any, positionManager: any) {
-//     try {
-//       const positionInfo = await positionManager.methods.positions(position).call()
-//       const info = await v3Tool.methods.getMoreInfo(positionInfo.token0, positionInfo.token1, positionInfo.fee).call()
-//
-//       const symbol0 = info.symbol0.replace(/[^A-Za-z0-9 ]+/g, '').substring(0, 10)
-//       const symbol1 = info.symbol1.replace(/[^A-Za-z0-9 ]+/g, '').substring(0, 10)
-//       const name = `${routerObj.router.slice(2, 4) + routerObj.router.slice(-2)}_${symbol0}_${symbol1}`
-//       const sum2 = replaceAll(BigNumber.from(positionInfo.token0).add(BigNumber.from(positionInfo.token1))._hex, '0x0', '0x')
-//
-//       const lp = {
-//         LP: info.lp,
-//         decimals0: info.decimals0,
-//         decimals1: info.decimals1,
-//         factory: routerObj.factory,
-//         feei: positionInfo.fee,
-//         id: position,
-//         name: name,
-//         r0: info.r0,
-//         r1: info.r1,
-//         router: routerObj.router,
-//         sum2: sum2,
-//         symbol0: symbol0,
-//         symbol1: symbol1,
-//         token0: positionInfo.token0,
-//         token1: positionInfo.token1
-//       }
-//
-//       await History.appendOrUpdate('UNIV3DEX', routerObj.router + '_router', {"now": position + 1})
-//
-//       return lp
-//     } catch (e) {}
-//
-//     return undefined
-//   }
-//
-//   async saveLpToSwapPath(lp: any) {
-//     const lpSum2Query = await swapPath.findBySumValueAndLevel(lp.sum2, '2')
-//     let lpSum2List = []
-//
-//     if (!this.isFirst && lpSum2Query.state) {
-//       lpSum2List = JSON.parse(lpSum2Query.data.data)
-//     }
-//
-//
-//     lpSum2List.push(lp)
-//
-//     // const insertRst = await swapPath.appendOrUpdate(lp.sum2, '2', lpSum2List)
-//     // logger.debug(`save path: ${lp.name}: ${insertRst.msg}`)
-//     await swapPath.appendOrUpdate(lp.sum2, '2', lpSum2List)
-//     // free
-//     lpSum2List.length = 0
-//   }
-//
-//   async handleToken(pool: any, zero: boolean) {
-//     const token = {
-//       'address': zero ? pool.token0 : pool.token1,
-//       'symbol': zero ? pool.symbol0 : pool.symbol1,
-//       'decimals': zero ? pool.decimals0 : pool.decimals1,
-//       'name': 'xxxxxxxx'
-//     }
-//
-//     let tokenObj = this.tokenInstance[token.address]
-//     if (!tokenObj) {
-//       tokenObj = new web3.eth.Contract(ierc20abi, token.address)
-//       this.tokenInstance[token.address] = tokenObj
-//     }
-//
-//     token.name = await tokenObj.methods.name().call()
-//     token.name = token.name.replace(/[^A-Za-z0-9 ]+/g, '').substring(0, 37)
-//
-//     return token
-//   }
-//
-//   async saveToken(lp: any, type='token') {
-//     try {
-//       const token = await this.handleToken(lp, true)
-//
-//       // const saveRst = await history.appendOrUpdate(type, token.address, token)
-//       // logger.debug(`${token.name} ${saveRst.msg}`)
-//       await history.appendOrUpdate(type, token.address, token)
-//     } catch (e) {}
-//
-//     try {
-//       const token = await this.handleToken(lp, false)
-//
-//       // const saveRst = await history.appendOrUpdate(type, token.address, token)
-//       // logger.debug(`${token.name} ${saveRst.msg}`)
-//       await history.appendOrUpdate(type, token.address, token)
-//     } catch (e) {}
-//   }
-//
-//   async saveLp(lp: any, type='0') {
-//     // const insertRst = await History.appendOrUpdate(type, lp.LP, lp)
-//     // logger.debug(`insert lp:${insertRst.msg}, hash: ${lp.LP}.}`)
-//     await History.appendOrUpdate(type, lp.LP, lp)
-//   }
-//
-//   async filterLp(lp: any) {
-//     if (lp.token0.toLowerCase() === '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') {
-//       return parseInt(lp.r0) > 20 * 1e18
-//     } else if (lp.token1.toLowerCase() === '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') {
-//       return parseInt(lp.r1) > 20 * 1e18
-//     }
-//
-//     return true
-//   }
-//
-//   parseFactory(router: any, factoryAbi: any, factoryAddress: string) {
-//     if (router.factoryObj == null) {
-//       router.factoryObj = new web3.eth.Contract(factoryAbi, factoryAddress)
-//     }
-//
-//     return router.factoryObj
-//   }
-//
-//   parsePositionManager(router: any, positionManagerAbi: any) {
-//     if (router.positionManager == null) {
-//       router.positionManager = new web3.eth.Contract(positionManagerAbi, router.position)
-//     }
-//
-//     return router.positionManager
-//   }
-//
-//   async checkPosition(pm: any, position: any) {
-//     try {
-//       await pm.methods.positions(position).call()
-//
-//       return true
-//     } catch (e) {
-//       return false
-//     }
-//   }
-//
-//   // 二分法查length
-//   async getPositionLength(pm: any) {
-//     let low = 300_000
-//     let high = 1_000_000
-//     let lastLow = low
-//     let lastHigh = high
-//
-//     let checkNumber = low
-//
-//
-//     // while (true) {
-//     //
-//     // }
-//
-//     return checkNumber
-//   }
-//
-//   async handleLp(position: number, pairsLength: number,
-//                  routerObj: any, v2ToolBy410: any, v3Tool: any, v3PositionManager: any) {
-//     // 1. 获取lp
-//     let lp = undefined
-//     if (routerObj.type === 'univ2') {
-//       lp = await this.getV2PoolByPosition(routerObj, position, v2ToolBy410)
-//     } else if (routerObj.type === 'univ3') {
-//       // v3是从1开始
-//       lp = await this.getV3Pool(routerObj, position + 1, v3Tool, v3PositionManager)
-//     }
-//     if (lp) {
-//       // 2. 保存Lp信息
-//       await this.saveLp(lp, '0')
-//       // 3. 保存Lp的Token到Token表
-//       await this.saveToken(lp, 'token')
-//       // 4. 过滤Lp
-//       if (await this.filterLp(lp)) {
-//         // 5. 将过滤后的Lp保存到二阶表
-//         // await this.saveLpToSwapPath(lp)
-//         // 6. 保存筛选之后的的Token到TopToken表
-//         await this.saveToken(lp, 'topToken')
-//         // 7. 保存过滤后的Lp到TopLp
-//         await this.saveLp(lp, 'topLp')
-//       }
-//     }
-//
-//     const memoryUsage = process.memoryUsage()
-//     if (this.maxMemoryOfByte < memoryUsage.rss) {
-//       this.maxMemoryOfByte = memoryUsage.rss
-//     }
-//     if (lp) {
-//       logger.debug(`${position + 1} / ${pairsLength}, ${lp.name}-${lp.LP}-${routerObj.chain}`
-//         + `  ${this.format(memoryUsage.rss)}/${this.format(this.maxMemoryOfByte)}`)
-//     } else {
-//       logger.debug(`lp get filed. ${position + 1} / ${pairsLength}, ${routerObj.name}-${routerObj.router}-${routerObj.chain}`
-//         + `  ${this.format(memoryUsage.rss)}/${this.format(this.maxMemoryOfByte)}`)
-//     }
-//   }
-//
-//   format (bytes: any) {
-//     return (bytes / 1024 / 1024).toFixed(2) + ' MB';
-//   }
-//
-//   async run() {
-//     logger.debug('Pull lp start.')
-//
-//     // 初始化410 v2工具箱
-//     const v2ToolBy410Abi = require('../../abi/410_V2_TOOLS.json')
-//     const v2ToolBy410 = new web3.eth.Contract(v2ToolBy410Abi, contracts.V2_TOOLS_BY_410)
-//     const v2FactoryAbi = require('../../abi/UNIV2_FACTORY_ABI.json')
-//     // 初始化v3相关
-//     const positionManagerAbi = require('../../abi/UNIV3_POSITION_MANAGER_ABI.json')
-//     const v3ToolAbi = require('../../artifacts/contracts/V3Tool.sol/V3Tool.json').abi
-//     const v3Tool = new web3.eth.Contract(v3ToolAbi, contracts.V3_TOOLS)
-//     // router
-//     const routerList: Array<any> = require('../../config/router-list.json')
-//
-//     while (true) {
-//       for (const routerObj of routerList) {
-//         let pairsLength = 0
-//
-//         const factoryAddress = routerObj.factory
-//         // 获取当前pull状态
-//         let position = this.fromHead ? routerObj.fromPosition : await this.handlePosition(routerObj)
-//         let v2Factory = undefined
-//         let v3PositionManager = undefined
-//         // v2,v3分开处理
-//         if (routerObj.type === 'univ2') {
-//           // 获取工厂实例
-//           v2Factory = this.parseFactory(routerObj, v2FactoryAbi, factoryAddress)
-//           // 获取当前pairsLength
-//           pairsLength = await v2Factory.methods.allPairsLength().call()
-//         } else if (routerObj.type === 'univ3') {
-//           // 获取positionManager
-//           v3PositionManager = this.parsePositionManager(routerObj, positionManagerAbi)
-//           pairsLength = await this.getPositionLength(v3PositionManager)
-//         }
-//         // 如果有未获取的池子
-//         const haveNewLp = position < pairsLength
-//
-//         // 打印信息
-//         if (haveNewLp) {
-//           logger.debug(`Router address: ${routerObj.router}`)
-//           if (routerObj.type === 'univ2') {
-//             logger.debug(`factory: ${factoryAddress}, ${position + 1} / ${pairsLength}.`)
-//           } else {
-//             logger.debug(`position: ${routerObj.position}, ${position + 1} / ${pairsLength}.`)
-//           }
-//         }
-//
-//         // 挨个处理lp信息
-//         for (; position < pairsLength; position++) {
-//           await this.handleLp(position, pairsLength, routerObj, v2ToolBy410, v3Tool, v3PositionManager)
-//         }
-//
-//         if (haveNewLp) {
-//           logger.debug('')
-//           logger.debug('')
-//           logger.debug('')
-//         }
-//       }
-//
-//       if (this.fromHead && this.isFirst) {
-//         this.isFirst = false
-//         this.fromHead = false
-//       }
-//     }
-//   }
-// }
+import { web3 } from "hardhat";
+import History from "../interface/history";
+import contracts from "../../config/contracts";
+import logger from "../../utils/logger";
+import {BigNumber} from "ethers";
+import {replaceAll} from "hardhat/internal/util/strings";
+import swapPath from "../interface/swapPath";
+import history from "../interface/history";
+import {LpMaintenance} from "./lpMaintenance";
+const ierc20abi = require('../../abi/IERC20_ABI.json')
+
+export class LpGenerate {
+  tokenInstance: any = {}
+  maxMemoryOfByte: number = 0
+
+  async handlePosition(routerObj: any) {
+    const block = routerObj.type === 'univ2' ? 'UNIV2DEX' : 'UNIV3DEX'
+    const hash = routerObj.type === 'univ2' ? routerObj.factory : routerObj.router + '_router'
+
+    try {
+      // 拉取当前pull状态信息
+      const pullState = await History.findByHashOrBlockOrDataVague(block, hash, '', 0, 200)
+      let nowPosition = 0
+
+      // 没有状态信息的情况
+      if (pullState.data.length == 0) {
+        await History.appendOrUpdate(block, hash, {"now": nowPosition})
+      } else {
+        nowPosition = pullState.data[0].dataObj.now
+      }
+
+      return nowPosition
+    } catch (e) {
+      logger.error(`Pull state error, router: ${routerObj.router}, factory: ${routerObj.factory}`)
+      logger.error(e)
+    }
+
+    return 0
+  }
+
+  async getV2PoolByPosition(routerObj: any, position: number, v2ToolBy410: any) {
+    try {
+      const info = await v2ToolBy410.methods.getPairIdInfo(routerObj.factory, position).call()
+
+      const symbol0 = info['2'].replace(/[^A-Za-z0-9]+/g, '').substring(0, 10)
+      const symbol1 = info['6'].replace(/[^A-Za-z0-9]+/g, '').substring(0, 10)
+      const name = `${routerObj.name}_${symbol0}_${symbol1}`
+      const sum2 = replaceAll(BigNumber.from(info['1']).add(BigNumber.from(info['5']))._hex, '0x0', '0x')
+
+      const lp = {
+        LP: info['0'],
+        decimals0: info['3'],
+        decimals1: info['7'],
+        factory: routerObj.factory,
+        feei: routerObj.fee,
+        id: position,
+        name: name,
+        r0: info['4'],
+        r1: info['8'],
+        router: routerObj.router,
+        sum2: sum2,
+        symbol0: symbol0,
+        symbol1: symbol1,
+        token0: info['1'],
+        token1: info['5'],
+        isEthW: routerObj.type == 'ETHW'
+      }
+
+      return lp
+    } catch (e) {}
+
+    return undefined
+  }
+
+  async getV3Pool(routerObj: any, position: number, v3Tool: any, positionManager: any) {
+    try {
+      const positionInfo = await positionManager.methods.positions(position).call()
+      const info = await v3Tool.methods.getMoreInfo(positionInfo.token0, positionInfo.token1, positionInfo.fee).call()
+
+      const symbol0 = info.symbol0.replace(/[^A-Za-z0-9 ]+/g, '').substring(0, 10)
+      const symbol1 = info.symbol1.replace(/[^A-Za-z0-9 ]+/g, '').substring(0, 10)
+      const name = `${routerObj.router.slice(2, 4) + routerObj.router.slice(-2)}_${symbol0}_${symbol1}`
+      const sum2 = replaceAll(BigNumber.from(positionInfo.token0).add(BigNumber.from(positionInfo.token1))._hex, '0x0', '0x')
+
+      const lp = {
+        LP: info.lp,
+        decimals0: info.decimals0,
+        decimals1: info.decimals1,
+        factory: routerObj.factory,
+        feei: positionInfo.fee,
+        id: position,
+        name: name,
+        r0: info.r0,
+        r1: info.r1,
+        router: routerObj.router,
+        sum2: sum2,
+        symbol0: symbol0,
+        symbol1: symbol1,
+        token0: positionInfo.token0,
+        token1: positionInfo.token1
+      }
+
+      return lp
+    } catch (e) {}
+
+    return undefined
+  }
+
+  async handleToken(pool: any, zero: boolean) {
+    const token = {
+      'address': zero ? pool.token0 : pool.token1,
+      'symbol': zero ? pool.symbol0 : pool.symbol1,
+      'decimals': zero ? pool.decimals0 : pool.decimals1,
+      'name': 'xxxxxxxx'
+    }
+
+    let tokenObj = this.tokenInstance[token.address]
+    if (!tokenObj) {
+      tokenObj = new web3.eth.Contract(ierc20abi, token.address)
+      this.tokenInstance[token.address] = tokenObj
+    }
+
+    token.name = await tokenObj.methods.name().call()
+    token.name = token.name.replace(/[^A-Za-z0-9 ]+/g, '').substring(0, 37)
+
+    return token
+  }
+
+  async saveToken(lp: any, type='token') {
+    try {
+      const token = await this.handleToken(lp, true)
+
+      await history.appendOrUpdate(type, token.address, token)
+    } catch (e) {}
+
+    try {
+      const token = await this.handleToken(lp, false)
+
+      await history.appendOrUpdate(type, token.address, token)
+    } catch (e) {}
+  }
+
+  async saveLp(lp: any, type='0') {
+    await History.appendOrUpdate(type, lp.LP, lp)
+  }
+
+  parseFactory(router: any, factoryAbi: any, factoryAddress: string) {
+    if (router.factoryObj == null) {
+      router.factoryObj = new web3.eth.Contract(factoryAbi, factoryAddress)
+    }
+
+    return router.factoryObj
+  }
+
+  parsePositionManager(router: any, positionManagerAbi: any) {
+    if (router.positionManager == null) {
+      router.positionManager = new web3.eth.Contract(positionManagerAbi, router.position)
+    }
+
+    return router.positionManager
+  }
+
+  async checkPosition(pm: any, position: any) {
+    try {
+      await pm.methods.positions(position).call()
+
+      return true
+    } catch (e) {
+      return false
+    }
+  }
+
+  // 二分法查length
+  async getPositionLength(pm: any) {
+    let low = 300_000
+    let high = 1_000_000
+    let lastLow = low
+    let lastHigh = high
+
+    let checkNumber = low
+
+
+    // while (true) {
+    //
+    // }
+
+    return checkNumber
+  }
+
+  async handleLp(position: number, pairsLength: number,
+                 routerObj: any, v2ToolBy410: any, v3Tool: any, v3PositionManager: any) {
+    // 1. 获取lp
+    let lp = undefined
+    if (routerObj.type === 'univ2') {
+      lp = await this.getV2PoolByPosition(routerObj, position, v2ToolBy410)
+    } else if (routerObj.type === 'univ3') {
+      // v3是从1开始
+      lp = await this.getV3Pool(routerObj, position + 1, v3Tool, v3PositionManager)
+    }
+    if (lp) {
+      // 2. 保存Lp信息
+      await this.saveLp(lp, '0')
+      // 3. 保存Lp的Token到Token表
+      await this.saveToken(lp, 'token')
+    }
+
+    const memoryUsage = process.memoryUsage()
+    if (this.maxMemoryOfByte < memoryUsage.rss) {
+      this.maxMemoryOfByte = memoryUsage.rss
+    }
+    if (lp) {
+      logger.debug(`${position + 1} / ${pairsLength}, ${lp.name}-${lp.LP}-${routerObj.chain}`
+        + `  ${this.format(memoryUsage.rss)}/${this.format(this.maxMemoryOfByte)}`)
+    } else {
+      logger.debug(`lp get filed. ${position + 1} / ${pairsLength}, ${routerObj.name}-${routerObj.router}-${routerObj.chain}`
+        + `  ${this.format(memoryUsage.rss)}/${this.format(this.maxMemoryOfByte)}`)
+    }
+  }
+
+  format (bytes: any) {
+    return (bytes / 1024 / 1024).toFixed(2) + ' MB';
+  }
+
+  async run() {
+    logger.debug('Pull lp start.')
+
+    // 初始化410 v2工具箱
+    const v2ToolBy410Abi = require('../../abi/410_V2_TOOLS.json')
+    const v2ToolBy410 = new web3.eth.Contract(v2ToolBy410Abi, contracts.V2_TOOLS_BY_410)
+    const v2FactoryAbi = require('../../abi/UNIV2_FACTORY_ABI.json')
+    // 初始化v3相关
+    const positionManagerAbi = require('../../abi/UNIV3_POSITION_MANAGER_ABI.json')
+    const v3ToolAbi = require('../../artifacts/contracts/V3Tool.sol/V3Tool.json').abi
+    const v3Tool = new web3.eth.Contract(v3ToolAbi, contracts.V3_TOOLS)
+    // router
+    const routerList: Array<any> = require('../../config/router-list.json')
+
+    while (true) {
+      for (const routerObj of routerList) {
+        let pairsLength = 0
+
+        const factoryAddress = routerObj.factory
+        // 获取当前pull状态
+        let position = await this.handlePosition(routerObj)
+        let v2Factory = undefined
+        let v3PositionManager = undefined
+        // v2,v3分开处理
+        if (routerObj.type === 'univ2') {
+          // 获取工厂实例
+          v2Factory = this.parseFactory(routerObj, v2FactoryAbi, factoryAddress)
+          // 获取当前pairsLength
+          pairsLength = await v2Factory.methods.allPairsLength().call()
+        } else if (routerObj.type === 'univ3') {
+          // 获取positionManager
+          v3PositionManager = this.parsePositionManager(routerObj, positionManagerAbi)
+          pairsLength = await this.getPositionLength(v3PositionManager)
+        }
+        // 如果有未获取的池子
+        const haveNewLp = position < pairsLength
+
+        // 打印信息
+        if (haveNewLp) {
+          logger.debug(`Router address: ${routerObj.router}`)
+          if (routerObj.type === 'univ2') {
+            logger.debug(`factory: ${factoryAddress}, ${position + 1} / ${pairsLength}.`)
+          } else {
+            logger.debug(`position: ${routerObj.position}, ${position + 1} / ${pairsLength}.`)
+          }
+        }
+
+        // 挨个处理lp信息
+        for (; position < pairsLength; position++) {
+          await this.handleLp(position, pairsLength, routerObj, v2ToolBy410, v3Tool, v3PositionManager)
+        }
+
+        if (haveNewLp) {
+          if (routerObj.type === 'univ2') {
+            await History.appendOrUpdate('UNIV2DEX', routerObj.factory, {"now": position + 1})
+          } else if (routerObj.type === 'univ3') {
+            await History.appendOrUpdate('UNIV3DEX', routerObj.router + '_router', {"now": position + 1})
+          }
+          logger.debug('')
+          logger.debug('')
+          logger.debug('')
+        }
+      }
+    }
+  }
+}
+
+async function main() {
+  await new LpGenerate().run()
+}
+
+main().catch((error) => {
+  console.error(error);
+  process.exitCode = 1;
+})

+ 346 - 0
scripts/path/level2Maintenance.ts

@@ -0,0 +1,346 @@
+// import { web3 } from "hardhat";
+// import History from "../interface/history";
+// import contracts from "../../config/contracts";
+// import logger from "../../utils/logger";
+// import {BigNumber} from "ethers";
+// import {replaceAll} from "hardhat/internal/util/strings";
+// import swapPath from "../interface/swapPath";
+// import history from "../interface/history";
+// import {LpMaintenance} from "./lpMaintenance";
+// const ierc20abi = require('../../abi/IERC20_ABI.json')
+//
+// export class LpGenerate {
+//   tokenInstance: any = {}
+//   maxMemoryOfByte: number = 0
+//
+//   async handlePosition(routerObj: any) {
+//     const block = routerObj.type === 'univ2' ? 'UNIV2DEX' : 'UNIV3DEX'
+//     const hash = routerObj.type === 'univ2' ? routerObj.factory : routerObj.router + '_router'
+//
+//     try {
+//       // 拉取当前pull状态信息
+//       const pullState = await History.findByHashOrBlockOrDataVague(block, hash, '', 0, 200)
+//       let nowPosition = 0
+//
+//       // 没有状态信息的情况
+//       if (pullState.data.length == 0) {
+//         await History.appendOrUpdate(block, hash, {"now": nowPosition})
+//       } else {
+//         nowPosition = pullState.data[0].dataObj.now
+//       }
+//
+//       return nowPosition
+//     } catch (e) {
+//       logger.error(`Pull state error, router: ${routerObj.router}, factory: ${routerObj.factory}`)
+//       logger.error(e)
+//     }
+//
+//     return 0
+//   }
+//
+//   async getV2PoolByPosition(routerObj: any, position: number, v2ToolBy410: any) {
+//     try {
+//       const info = await v2ToolBy410.methods.getPairIdInfo(routerObj.factory, position).call()
+//
+//       const symbol0 = info['2'].replace(/[^A-Za-z0-9]+/g, '').substring(0, 10)
+//       const symbol1 = info['6'].replace(/[^A-Za-z0-9]+/g, '').substring(0, 10)
+//       const name = `${routerObj.name}_${symbol0}_${symbol1}`
+//       const sum2 = replaceAll(BigNumber.from(info['1']).add(BigNumber.from(info['5']))._hex, '0x0', '0x')
+//
+//       const lp = {
+//         LP: info['0'],
+//         decimals0: info['3'],
+//         decimals1: info['7'],
+//         factory: routerObj.factory,
+//         feei: routerObj.fee,
+//         id: position,
+//         name: name,
+//         r0: info['4'],
+//         r1: info['8'],
+//         router: routerObj.router,
+//         sum2: sum2,
+//         symbol0: symbol0,
+//         symbol1: symbol1,
+//         token0: info['1'],
+//         token1: info['5'],
+//         isEthW: routerObj.type == 'ETHW'
+//       }
+//
+//       // 更新一次position
+//       // await History.appendOrUpdate('UNIV2DEX', routerObj.factory, {"now": position + 1})
+//
+//       return lp
+//     } catch (e) {}
+//
+//     return undefined
+//   }
+//
+//   async getV3Pool(routerObj: any, position: number, v3Tool: any, positionManager: any) {
+//     try {
+//       const positionInfo = await positionManager.methods.positions(position).call()
+//       const info = await v3Tool.methods.getMoreInfo(positionInfo.token0, positionInfo.token1, positionInfo.fee).call()
+//
+//       const symbol0 = info.symbol0.replace(/[^A-Za-z0-9 ]+/g, '').substring(0, 10)
+//       const symbol1 = info.symbol1.replace(/[^A-Za-z0-9 ]+/g, '').substring(0, 10)
+//       const name = `${routerObj.router.slice(2, 4) + routerObj.router.slice(-2)}_${symbol0}_${symbol1}`
+//       const sum2 = replaceAll(BigNumber.from(positionInfo.token0).add(BigNumber.from(positionInfo.token1))._hex, '0x0', '0x')
+//
+//       const lp = {
+//         LP: info.lp,
+//         decimals0: info.decimals0,
+//         decimals1: info.decimals1,
+//         factory: routerObj.factory,
+//         feei: positionInfo.fee,
+//         id: position,
+//         name: name,
+//         r0: info.r0,
+//         r1: info.r1,
+//         router: routerObj.router,
+//         sum2: sum2,
+//         symbol0: symbol0,
+//         symbol1: symbol1,
+//         token0: positionInfo.token0,
+//         token1: positionInfo.token1
+//       }
+//
+//       // await History.appendOrUpdate('UNIV3DEX', routerObj.router + '_router', {"now": position + 1})
+//
+//       return lp
+//     } catch (e) {}
+//
+//     return undefined
+//   }
+//
+//   async saveLpToSwapPath(lp: any) {
+//     const lpSum2Query = await swapPath.findBySumValueAndLevel(lp.sum2, '2')
+//     let lpSum2List = []
+//
+//     if (!this.isFirst && lpSum2Query.state) {
+//       lpSum2List = JSON.parse(lpSum2Query.data.data)
+//     }
+//
+//
+//     lpSum2List.push(lp)
+//
+//     // const insertRst = await swapPath.appendOrUpdate(lp.sum2, '2', lpSum2List)
+//     // logger.debug(`save path: ${lp.name}: ${insertRst.msg}`)
+//     await swapPath.appendOrUpdate(lp.sum2, '2', lpSum2List)
+//     // free
+//     lpSum2List.length = 0
+//   }
+//
+//   async handleToken(pool: any, zero: boolean) {
+//     const token = {
+//       'address': zero ? pool.token0 : pool.token1,
+//       'symbol': zero ? pool.symbol0 : pool.symbol1,
+//       'decimals': zero ? pool.decimals0 : pool.decimals1,
+//       'name': 'xxxxxxxx'
+//     }
+//
+//     let tokenObj = this.tokenInstance[token.address]
+//     if (!tokenObj) {
+//       tokenObj = new web3.eth.Contract(ierc20abi, token.address)
+//       this.tokenInstance[token.address] = tokenObj
+//     }
+//
+//     token.name = await tokenObj.methods.name().call()
+//     token.name = token.name.replace(/[^A-Za-z0-9 ]+/g, '').substring(0, 37)
+//
+//     return token
+//   }
+//
+//   async saveToken(lp: any, type='token') {
+//     try {
+//       const token = await this.handleToken(lp, true)
+//
+//       // const saveRst = await history.appendOrUpdate(type, token.address, token)
+//       // logger.debug(`${token.name} ${saveRst.msg}`)
+//       await history.appendOrUpdate(type, token.address, token)
+//     } catch (e) {}
+//
+//     try {
+//       const token = await this.handleToken(lp, false)
+//
+//       // const saveRst = await history.appendOrUpdate(type, token.address, token)
+//       // logger.debug(`${token.name} ${saveRst.msg}`)
+//       await history.appendOrUpdate(type, token.address, token)
+//     } catch (e) {}
+//   }
+//
+//   async saveLp(lp: any, type='0') {
+//     // const insertRst = await History.appendOrUpdate(type, lp.LP, lp)
+//     // logger.debug(`insert lp:${insertRst.msg}, hash: ${lp.LP}.}`)
+//     await History.appendOrUpdate(type, lp.LP, lp)
+//   }
+//
+//   async filterLp(lp: any) {
+//     if (lp.token0.toLowerCase() === '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') {
+//       return parseInt(lp.r0) > 20 * 1e18
+//     } else if (lp.token1.toLowerCase() === '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') {
+//       return parseInt(lp.r1) > 20 * 1e18
+//     }
+//
+//     return true
+//   }
+//
+//   parseFactory(router: any, factoryAbi: any, factoryAddress: string) {
+//     if (router.factoryObj == null) {
+//       router.factoryObj = new web3.eth.Contract(factoryAbi, factoryAddress)
+//     }
+//
+//     return router.factoryObj
+//   }
+//
+//   parsePositionManager(router: any, positionManagerAbi: any) {
+//     if (router.positionManager == null) {
+//       router.positionManager = new web3.eth.Contract(positionManagerAbi, router.position)
+//     }
+//
+//     return router.positionManager
+//   }
+//
+//   async checkPosition(pm: any, position: any) {
+//     try {
+//       await pm.methods.positions(position).call()
+//
+//       return true
+//     } catch (e) {
+//       return false
+//     }
+//   }
+//
+//   // 二分法查length
+//   async getPositionLength(pm: any) {
+//     let low = 300_000
+//     let high = 1_000_000
+//     let lastLow = low
+//     let lastHigh = high
+//
+//     let checkNumber = low
+//
+//
+//     // while (true) {
+//     //
+//     // }
+//
+//     return checkNumber
+//   }
+//
+//   async handleLp(position: number, pairsLength: number,
+//                  routerObj: any, v2ToolBy410: any, v3Tool: any, v3PositionManager: any) {
+//     // 1. 获取lp
+//     let lp = undefined
+//     if (routerObj.type === 'univ2') {
+//       lp = await this.getV2PoolByPosition(routerObj, position, v2ToolBy410)
+//     } else if (routerObj.type === 'univ3') {
+//       // v3是从1开始
+//       lp = await this.getV3Pool(routerObj, position + 1, v3Tool, v3PositionManager)
+//     }
+//     if (lp) {
+//       // 2. 保存Lp信息
+//       await this.saveLp(lp, '0')
+//       // 3. 保存Lp的Token到Token表
+//       await this.saveToken(lp, 'token')
+//       // 4. 过滤Lp
+//       if (await this.filterLp(lp)) {
+//         // 5. 将过滤后的Lp保存到二阶表
+//         // await this.saveLpToSwapPath(lp)
+//         // 6. 保存筛选之后的的Token到TopToken表
+//         await this.saveToken(lp, 'topToken')
+//         // 7. 保存过滤后的Lp到TopLp
+//         await this.saveLp(lp, 'topLp')
+//       }
+//     }
+//
+//     const memoryUsage = process.memoryUsage()
+//     if (this.maxMemoryOfByte < memoryUsage.rss) {
+//       this.maxMemoryOfByte = memoryUsage.rss
+//     }
+//     if (lp) {
+//       logger.debug(`${position + 1} / ${pairsLength}, ${lp.name}-${lp.LP}-${routerObj.chain}`
+//         + `  ${this.format(memoryUsage.rss)}/${this.format(this.maxMemoryOfByte)}`)
+//     } else {
+//       logger.debug(`lp get filed. ${position + 1} / ${pairsLength}, ${routerObj.name}-${routerObj.router}-${routerObj.chain}`
+//         + `  ${this.format(memoryUsage.rss)}/${this.format(this.maxMemoryOfByte)}`)
+//     }
+//   }
+//
+//   format (bytes: any) {
+//     return (bytes / 1024 / 1024).toFixed(2) + ' MB';
+//   }
+//
+//   async run() {
+//     logger.debug('Pull lp start.')
+//
+//     // 初始化410 v2工具箱
+//     const v2ToolBy410Abi = require('../../abi/410_V2_TOOLS.json')
+//     const v2ToolBy410 = new web3.eth.Contract(v2ToolBy410Abi, contracts.V2_TOOLS_BY_410)
+//     const v2FactoryAbi = require('../../abi/UNIV2_FACTORY_ABI.json')
+//     // 初始化v3相关
+//     const positionManagerAbi = require('../../abi/UNIV3_POSITION_MANAGER_ABI.json')
+//     const v3ToolAbi = require('../../artifacts/contracts/V3Tool.sol/V3Tool.json').abi
+//     const v3Tool = new web3.eth.Contract(v3ToolAbi, contracts.V3_TOOLS)
+//     // router
+//     const routerList: Array<any> = require('../../config/router-list.json')
+//
+//     while (true) {
+//       for (const routerObj of routerList) {
+//         let pairsLength = 0
+//
+//         const factoryAddress = routerObj.factory
+//         // 获取当前pull状态
+//         let position = this.fromHead ? routerObj.fromPosition : await this.handlePosition(routerObj)
+//         let v2Factory = undefined
+//         let v3PositionManager = undefined
+//         // v2,v3分开处理
+//         if (routerObj.type === 'univ2') {
+//           // 获取工厂实例
+//           v2Factory = this.parseFactory(routerObj, v2FactoryAbi, factoryAddress)
+//           // 获取当前pairsLength
+//           pairsLength = await v2Factory.methods.allPairsLength().call()
+//         } else if (routerObj.type === 'univ3') {
+//           // 获取positionManager
+//           v3PositionManager = this.parsePositionManager(routerObj, positionManagerAbi)
+//           pairsLength = await this.getPositionLength(v3PositionManager)
+//         }
+//         // 如果有未获取的池子
+//         const haveNewLp = position < pairsLength
+//
+//         // 打印信息
+//         if (haveNewLp) {
+//           logger.debug(`Router address: ${routerObj.router}`)
+//           if (routerObj.type === 'univ2') {
+//             logger.debug(`factory: ${factoryAddress}, ${position + 1} / ${pairsLength}.`)
+//           } else {
+//             logger.debug(`position: ${routerObj.position}, ${position + 1} / ${pairsLength}.`)
+//           }
+//         }
+//
+//         // 挨个处理lp信息
+//         for (; position < pairsLength; position++) {
+//           await this.handleLp(position, pairsLength, routerObj, v2ToolBy410, v3Tool, v3PositionManager)
+//         }
+//
+//         if (haveNewLp) {
+//           logger.debug('')
+//           logger.debug('')
+//           logger.debug('')
+//         }
+//       }
+//
+//       if (this.fromHead && this.isFirst) {
+//         this.isFirst = false
+//         this.fromHead = false
+//       }
+//     }
+//   }
+// }
+//
+// async function main() {
+//   await new LpGenerate().run()
+// }
+//
+// main().catch((error) => {
+//   console.error(error);
+//   process.exitCode = 1;
+// })