Parcourir la source

究极无敌超级厉害的lp分类系统

龚成明 il y a 3 ans
Parent
commit
807c37aa03
1 fichiers modifiés avec 112 ajouts et 29 suppressions
  1. 112 29
      scripts/lp/lpMaintenance.ts

+ 112 - 29
scripts/lp/lpMaintenance.ts

@@ -2,6 +2,7 @@ import { web3 } from "hardhat";
 import History from "../interface/history";
 import contracts from "../../config/contracts";
 import logger from "../../utils/logger";
+import {BigNumber} from "ethers";
 
 // 初始化410 v2工具箱
 const v2ToolBy410Abi = require('../../abi/410_V2_TOOLS.json')
@@ -19,53 +20,84 @@ export class LpMaintenance {
   maxMemoryOfByte: number = 0
   maxMemoryChanged: boolean = true
 
+  // 计算价格要用
+  allMaxValueLpGroupBySum: any = {}
+  baseTokenConvertEthValueMap: any = {}
+
   async saveLp(lp: any, type='0') {
     await History.appendOrUpdate(type, lp.LP, lp)
   }
 
+  getLpEthValue(lp: any) {
+    const token0 = lp.token0.toLowerCase()
+    const token1 = lp.token1.toLowerCase()
+
+    // 1.两token之一能直接与ethw或wethw做直接池子的
+    // 2.两token之一能直接与baseToken做池子的
+    // 这两种情况直接带入baseTokenConvertEthValueMap计算
+    for (const baseTokenAddress of baseTokenAddressList) {
+      const token0AndBaseTokenLp = this.allMaxValueLpGroupBySum[this.getHexSum(token0, baseTokenAddress.toLowerCase())]
+      if (token0AndBaseTokenLp) {
+        if (ethTokenAddressList.indexOf(baseTokenAddress.toLowerCase()) == -1) {
+          logger.debug(`${lp}`)
+          logger.debug(`0, ${token0AndBaseTokenLp.zeroToOnePrice}, ${this.baseTokenConvertEthValueMap[baseTokenAddress]}`)
+        }
+
+        return {
+          '0': token0AndBaseTokenLp.zeroToOnePrice * this.baseTokenConvertEthValueMap[baseTokenAddress],
+          '1': 1 / token0AndBaseTokenLp.zeroToOnePrice * this.baseTokenConvertEthValueMap[baseTokenAddress]
+        }
+      }
+
+      const token1AndBaseTokenLp = this.allMaxValueLpGroupBySum[this.getHexSum(token1, baseTokenAddress.toLowerCase())]
+      if (token1AndBaseTokenLp) {
+        if (ethTokenAddressList.indexOf(baseTokenAddress.toLowerCase()) == -1) {
+          logger.debug(`${lp}`)
+          logger.debug(`1, ${token0AndBaseTokenLp.zeroToOnePrice}, ${this.baseTokenConvertEthValueMap[baseTokenAddress]}`)
+        }
+
+        return {
+          '0': 1 / token1AndBaseTokenLp.oneToZeroPrice * this.baseTokenConvertEthValueMap[baseTokenAddress],
+          '1': token1AndBaseTokenLp.oneToZeroPrice * this.baseTokenConvertEthValueMap[baseTokenAddress]
+        }
+      }
+    }
+
+    // 3.两token都不能与baseToken做池子的
+    // 这种情况则视为lp类型池子
+    return {'0': 0, '1': 0}
+  }
+
   async checkLpType(lp: any) {
     // lp过滤后类型表
     const filterTypeList = [
-      { type: 'topLp', limit: 10 },
-      { type: 'normalLp', limit: 1 },
+      { type: 'topLp', limit: 1 },
+      { type: 'normalLp', limit: 0.1 },
       { type: 'lp', limit: 0 },
     ]
     // token折合成eth的价格
-    let tokenConvertEthPrice = 1
-
-    // token0和token1都不是baseToken的。视为lp
-    if (baseTokenAddressList.indexOf(lp.token0.toLowerCase()) == -1
-      && baseTokenAddressList.indexOf(lp.token1.toLowerCase()) == -1) {
-      return 'lp'
+    let tokenConvertEthPrice: any = {
+      '0': 1,
+      '1': 1
     }
 
-    // token0和token1都不是eth的,视为usdx
+    // token0和token1都不是eth的,分三种情况探讨
     if (ethTokenAddressList.indexOf(lp.token0.toLowerCase()) == -1
       && ethTokenAddressList.indexOf(lp.token1.toLowerCase()) == -1) {
-      tokenConvertEthPrice = 0.142
+      tokenConvertEthPrice = this.getLpEthValue(lp)
     }
 
     // 从高到低遍历过滤条件
+    const decimals0 = parseInt(lp.decimals0)
+    const decimals1 = parseInt(lp.decimals0)
+    const realAmount0 = parseInt(lp.r0) * tokenConvertEthPrice['0'] / Math.pow(10, -decimals0)
+    const realAmount1 = parseInt(lp.r1) * tokenConvertEthPrice['1'] / Math.pow(10, -decimals1)
+
     for (const filterType of filterTypeList) {
-      // 从头到尾搜索baseToken
-      for (const baseTokenAddress of baseTokenAddressList) {
-        const baseToken = baseTokenMap[baseTokenAddress]
-        const amountLimit = filterType.limit * Math.pow(10, baseToken.decimals)
-
-        // 如果是token0是baseToken,则将token1根据价格折合成eth数量计算
-        if (lp.token0.toLowerCase() === baseTokenAddress) {
-          const convertedEthAmount = parseInt(lp.r0) * tokenConvertEthPrice
-          if (convertedEthAmount >= amountLimit) {
-            return filterType.type
-          }
-        }
-        // 如果是token1是baseToken,则将token1根据价格折合成eth数量计算
-        if (lp.token1.toLowerCase() === baseTokenAddress) {
-          const convertedEthAmount = parseInt(lp.r1) * tokenConvertEthPrice
-          if (convertedEthAmount >= amountLimit) {
-            return filterType.type
-          }
-        }
+      const amountLimit = filterType.limit
+
+      if (realAmount0 >= amountLimit || realAmount1 >= amountLimit) {
+        return filterType.type
       }
     }
   }
@@ -123,6 +155,53 @@ export class LpMaintenance {
     }
   }
 
+  putAllLpGroupBySum(lpList: any) {
+    this.allMaxValueLpGroupBySum = {}
+
+    for (const lpDbObj of lpList) {
+      const lp = lpDbObj.dataObj
+
+      const notExist = !this.allMaxValueLpGroupBySum[lp.sum2]
+      const moreValueThanNowMax = !notExist && (parseInt(lp.r0) > this.allMaxValueLpGroupBySum[lp.sum2].r0)
+      if (notExist || moreValueThanNowMax) {
+        // 计算0换1的价格和1换0的价格
+        lp.zeroToOnePrice = parseInt(lp.r1) / parseInt(lp.r0) // 一个token0 = zeroToOnePrice个token1
+        lp.oneToZeroPrice = parseInt(lp.r0) / parseInt(lp.r1) // 一个token1 = oneForZeroPrice个token0
+
+        this.allMaxValueLpGroupBySum[lp.sum2] = lp
+      }
+    }
+  }
+
+  calcBaseTokenCovertEthValue() {
+    for (const baseTokenAddress of baseTokenAddressList) {
+      const isEthToken = ethTokenAddressList.indexOf(baseTokenAddress) != -1
+      // eth兑换eth价格当然是1:1啦
+      if (isEthToken) {
+        this.baseTokenConvertEthValueMap[baseTokenAddress] = 1
+      } else {
+        // 在ETH token中查找适合兑换的
+        for (const ethTokenAddress of ethTokenAddressList) {
+          const maxValueLp = this.allMaxValueLpGroupBySum[this.getHexSum(baseTokenAddress, ethTokenAddress)]
+          if (!maxValueLp) continue
+
+          const token0 = maxValueLp.token0.toLowerCase()
+          const token1 = maxValueLp.token1.toLowerCase()
+
+          if (baseTokenAddress.toLowerCase() == token0) {
+            this.baseTokenConvertEthValueMap[baseTokenAddress] = maxValueLp.zeroToOnePrice
+          } else if (baseTokenAddress.toLowerCase() == token1) {
+            this.baseTokenConvertEthValueMap[baseTokenAddress] = maxValueLp.oneToZeroPrice
+          }
+        }
+      }
+    }
+  }
+
+  getHexSum(hex0: string, hex1: string) {
+    return BigNumber.from(hex0).add(BigNumber.from(hex1))._hex
+  }
+
   async run() {
     logger.debug('LP maintenance start.')
     while (true) {
@@ -141,6 +220,8 @@ export class LpMaintenance {
 
         const allTypeLpList: any = topLpList.concat(lpList).concat(normalLpList)
         const lpAddressList: any = this.generateAddressListByLpList(allTypeLpList)
+        // lp按sum分类
+        this.putAllLpGroupBySum(allTypeLpList)
         // logger.debug(`${lpAddressList.length}`)
 
         // 集中拉取r0,r1并更新本地的
@@ -154,6 +235,8 @@ export class LpMaintenance {
           this.updateLocalLpListR0R1(allTypeLpList.slice(from, from + size), r0s, r1s)
         }
 
+        this.calcBaseTokenCovertEthValue()
+
         // 将lp类型有变动的全部更新
         for (const lpDbObj of allTypeLpList) {
           await this.handleLp(lpDbObj.dataObj, lpDbObj.block)