|
|
@@ -17,24 +17,26 @@ export class PullAndPush {
|
|
|
this.isFirst = _isFirst
|
|
|
}
|
|
|
|
|
|
- async handlePosition(router: String, factory: String) {
|
|
|
+ async handlePosition(routerObj: any) {
|
|
|
+ const block = routerObj.type === 'univ2' ? 'UNIV2DEX' : 'UNIV3DEX'
|
|
|
+
|
|
|
try {
|
|
|
// 拉取当前pull状态信息
|
|
|
- const pullState = await History.findByHashOrBlockOrDataVague('UNIV2DEX', factory, '', 0, 200)
|
|
|
+ const pullState = await History.findByHashOrBlockOrDataVague(block, routerObj.factory, '', 0, 200)
|
|
|
let nowPosition = 0
|
|
|
|
|
|
// 没有状态信息的情况
|
|
|
if (pullState.data.length == 0) {
|
|
|
// const appendRst = await History.appendOrUpdate('UNIV2DEX', factory, {"now": nowPosition})
|
|
|
// logger.debug(appendRst)
|
|
|
- await History.appendOrUpdate('UNIV2DEX', factory, {"now": nowPosition})
|
|
|
+ await History.appendOrUpdate(block, routerObj.factory, {"now": nowPosition})
|
|
|
} else {
|
|
|
nowPosition = pullState.data[0].dataObj.now
|
|
|
}
|
|
|
|
|
|
return nowPosition
|
|
|
} catch (e) {
|
|
|
- logger.error(`Pull state error, router: ${router}, factory: ${factory}`)
|
|
|
+ logger.error(`Pull state error, router: ${routerObj.router}, factory: ${routerObj.factory}`)
|
|
|
logger.error(e)
|
|
|
}
|
|
|
|
|
|
@@ -78,6 +80,42 @@ export class PullAndPush {
|
|
|
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.factory, {"now": position})
|
|
|
+
|
|
|
+ return lp
|
|
|
+ } catch (e) {}
|
|
|
+
|
|
|
+ return undefined
|
|
|
+ }
|
|
|
+
|
|
|
async saveLpToSwapPath(lp: any) {
|
|
|
const lpSum2Query = await swapPath.findBySumValueAndLevel(lp.sum2, '2')
|
|
|
let lpSum2List = []
|
|
|
@@ -143,7 +181,7 @@ export class PullAndPush {
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
- parseFactory(router: any, factoryAbi: any, factoryAddress: any) {
|
|
|
+ parseFactory(router: any, factoryAbi: any, factoryAddress: string) {
|
|
|
if (router.factoryObj == null) {
|
|
|
router.factoryObj = new web3.eth.Contract(factoryAbi, factoryAddress)
|
|
|
}
|
|
|
@@ -151,6 +189,40 @@ export class PullAndPush {
|
|
|
return router.factoryObj
|
|
|
}
|
|
|
|
|
|
+ parsePositionManager(router: any, positionManagerAbi: any, positionManagerAddress: string) {
|
|
|
+ if (router.positionManager == null) {
|
|
|
+ router.positionManager = new web3.eth.Contract(positionManagerAbi, positionManagerAddress)
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 run() {
|
|
|
logger.debug('Pull v2 start.')
|
|
|
|
|
|
@@ -158,33 +230,54 @@ export class PullAndPush {
|
|
|
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
|
|
|
+
|
|
|
if (routerObj.type === 'univ3') continue
|
|
|
|
|
|
- const v2FactoryAddress = routerObj.factory
|
|
|
- // 获取工厂实例
|
|
|
- const v2Factory = this.parseFactory(routerObj, v2FactoryAbi, v2FactoryAddress)
|
|
|
+ const factoryAddress = routerObj.factory
|
|
|
// 获取当前pull状态
|
|
|
- let position = this.fromHead ? routerObj.fromPosition : await this.handlePosition(routerObj.router, v2FactoryAddress)
|
|
|
- // 获取当前pairsLength
|
|
|
- const pairsLength = await v2Factory.methods.allPairsLength().call()
|
|
|
+ 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, contracts.UNIV3_POSITION)
|
|
|
+ pairsLength = await this.getPositionLength(v3PositionManager)
|
|
|
+ }
|
|
|
// 如果有未获取的池子
|
|
|
const haveNewLp = position + 1 < pairsLength
|
|
|
|
|
|
// 打印信息
|
|
|
if (haveNewLp) {
|
|
|
logger.debug(`Router address: ${routerObj.router}`)
|
|
|
- logger.debug(`factory: ${v2FactoryAddress}, ${position + 1} / ${pairsLength}.`)
|
|
|
+ logger.debug(`factory: ${factoryAddress}, ${position + 1} / ${pairsLength}.`)
|
|
|
}
|
|
|
|
|
|
// 挨个处理lp信息
|
|
|
while (position + 1 < pairsLength) {
|
|
|
- logger.debug(`${position + 1} / ${pairsLength}`)
|
|
|
+ logger.debug(`${position + 1} / ${pairsLength}, ${routerObj.name}-${routerObj.router}-${routerObj.chain}`)
|
|
|
// 1. 获取lp
|
|
|
- const lp = await this.getV2PoolByPosition(routerObj, position, v2ToolBy410)
|
|
|
+ let lp = undefined
|
|
|
+ if (routerObj.type === 'univ2') {
|
|
|
+ lp = await this.getV2PoolByPosition(routerObj, position, v2ToolBy410)
|
|
|
+ } else if (routerObj.type === 'univ3') {
|
|
|
+ lp = await this.getV3Pool(routerObj, position, v3Tool, v3PositionManager)
|
|
|
+ }
|
|
|
// 2. 保存Lp信息
|
|
|
await this.saveLp(lp, '0')
|
|
|
// 3. 保存Lp的Token到Token表
|