lpMaintenance.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import { web3 } from "hardhat";
  2. import History from "../interface/history";
  3. import contracts from "../../config/contracts";
  4. import logger from "../../utils/logger";
  5. import history from "../interface/history";
  6. const ierc20abi = require('../../abi/IERC20_ABI.json')
  7. // 初始化410 v2工具箱
  8. const v2ToolBy410Abi = require('../../abi/410_V2_TOOLS.json')
  9. const v2ToolBy410 = new web3.eth.Contract(v2ToolBy410Abi, contracts.V2_TOOLS_BY_410)
  10. export class LpMaintenance {
  11. tokenInstance: any = {}
  12. maxMemoryOfByte: number = 0
  13. maxMemoryChanged: boolean = true
  14. async saveLp(lp: any, type='0') {
  15. await History.appendOrUpdate(type, lp.LP, lp)
  16. }
  17. async checkLpType(lp: any) {
  18. const ethTokenList = [
  19. '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // WETH
  20. '0xaf3ccfd9b59b36628cc2f659a09d6440795b2520', // ETH
  21. '0x7bf88d2c0e32de92cdaf2d43ccdc23e8edfd5990' // WETHW
  22. ]
  23. const filterTypeList = [
  24. { type: 'topLp', limit: 10 * 1e18 },
  25. { type: 'normalLp', limit: 1 * 1e18 },
  26. { type: 'lp', limit: 0 },
  27. ]
  28. if (ethTokenList.indexOf(lp.token0.toLowerCase()) == -1
  29. && ethTokenList.indexOf(lp.token1.toLowerCase()) == -1) {
  30. return 'normalLp'
  31. }
  32. for (const filterType of filterTypeList) {
  33. if (ethTokenList.indexOf(lp.token0.toLowerCase()) != -1) {
  34. if (parseInt(lp.r0) >= filterType.limit) return filterType.type
  35. } else if (ethTokenList.indexOf(lp.token1.toLowerCase()) != -1) {
  36. if (parseInt(lp.r1) >= filterType.limit) return filterType.type
  37. }
  38. }
  39. }
  40. async handleLp(lp: any, oldType: any) {
  41. // 过滤Lp
  42. let lpType = await this.checkLpType(lp)
  43. // 一共12w个池子,非ethw的垃圾池子就不拉了
  44. if (lpType == 'lp' && !lp.isEthW) {
  45. lpType = 'ethLp'
  46. }
  47. if (lpType != oldType) {
  48. // 保存变更之后的的Token
  49. // await this.saveToken(lp, lpType)
  50. // 保存变更后的Lp
  51. await this.saveLp(lp, lpType)
  52. logger.debug(`lp:${lp.LP},${oldType}->${lpType}.`)
  53. }
  54. }
  55. showMemory (mainInfo: string) {
  56. const memoryUsage = process.memoryUsage()
  57. if (this.maxMemoryOfByte < memoryUsage.rss) {
  58. this.maxMemoryOfByte = memoryUsage.rss
  59. this.maxMemoryChanged = true
  60. }
  61. logger.debug(`${mainInfo} ${this.format(memoryUsage.rss)}/${this.format(this.maxMemoryOfByte)}`)
  62. }
  63. format (bytes: any) {
  64. return (bytes / 1024 / 1024).toFixed(2) + ' MB';
  65. }
  66. generateAddressListByLpList (lpList: any) {
  67. const lpAddressList: any = []
  68. for (const lp of lpList) {
  69. lpAddressList.push(lp.dataObj.LP)
  70. }
  71. return lpAddressList
  72. }
  73. updateLocalLpListR0R1(lpList: any, r0s: any, r1s: any) {
  74. for (let index = 0; index < lpList.length; index++) {
  75. lpList[index].dataObj.r0 = r0s[index]
  76. lpList[index].dataObj.r1 = r1s[index]
  77. }
  78. }
  79. async run() {
  80. logger.debug('LP maintenance start.')
  81. while (true) {
  82. if (this.maxMemoryChanged) {
  83. this.showMemory('a loop...')
  84. }
  85. this.showMemory('a loop...')
  86. this.maxMemoryChanged = false
  87. const topLpPullRst = await history.findByBlock('topLp')
  88. if (!topLpPullRst.state) continue
  89. const topLpList = topLpPullRst.data
  90. const lpPullRst = await history.findByBlock('lp')
  91. if (!lpPullRst.state) continue
  92. const lpList = lpPullRst.data
  93. const normalLpPullRst = await history.findByBlock('normalLp')
  94. if (!normalLpPullRst.state) continue
  95. const normalLpList = normalLpPullRst.data
  96. const zeroLpPullRst = await history.findByBlock('0')
  97. if (!zeroLpPullRst.state) continue
  98. const zeroLpList = zeroLpPullRst.data
  99. const allTypeLpList: any = [].concat(topLpList).concat(lpList).concat(normalLpList).concat(zeroLpList)
  100. const lpAddressList: any = this.generateAddressListByLpList(allTypeLpList)
  101. // logger.debug(`${lpAddressList.length}`)
  102. // 集中拉取r0,r1并更新本地的
  103. const size = 2000
  104. for (let from = 0; from < allTypeLpList.length; from += size) {
  105. // logger.debug(`${from}, ${allTypeLpList.length}`)
  106. const lpR0R1Info: any = await v2ToolBy410.methods.getPairSBalance(lpAddressList.slice(from, from + size)).call()
  107. const r0s = lpR0R1Info.amounts0
  108. const r1s = lpR0R1Info.amounts1
  109. this.updateLocalLpListR0R1(allTypeLpList.slice(from, from + size), r0s, r1s)
  110. }
  111. // 将lp类型有变动的全部更新
  112. for (const lpDbObj of allTypeLpList) {
  113. logger.debug(lpDbObj)
  114. await this.handleLp(lpDbObj.dataObj, lpDbObj.block)
  115. }
  116. }
  117. }
  118. }
  119. async function main() {
  120. await new LpMaintenance().run()
  121. }
  122. main().catch((error) => {
  123. console.error(error);
  124. process.exitCode = 1;
  125. })