const logger = require("../../utils/logger"); const BaseModel = require("../../model/base-model"); const V2ToolAbi = require('../../abi/UNIV2_TOOLS_ABI.json') const V3ToolAbi = require('../../abi/UNIV3_TOOLS_ABI.json') module.exports = class LpLib { static LEVEL = { NOT: 'not', DISCARD: 'discard', INIT: 'init', NORMAL: 'normal', TOP: 'top' } constructor(web3, chain, factoryLib, tokenLib) { this.web3 = web3 this.chain = chain this.factoryLib = factoryLib this.tokenLib = tokenLib this.v2LpModel = new BaseModel(this.chain.id, BaseModel.MODULES.V2_LP) this.v3LpModel = new BaseModel(this.chain.id, BaseModel.MODULES.V3_LP) // 初始化V2工具箱 this.v2Tool = new this.web3.eth.Contract(V2ToolAbi, this.chain.v2ToolAddress) // 初始化V3工具箱 this.v3Tool = new this.web3.eth.Contract(V3ToolAbi, this.chain.v3ToolAddress) } async saveLp(factory, lp) { let saveRst = undefined if (factory.version === 'univ2') { saveRst = await this.v2LpModel.appendOrUpdate(lp) } else if (factory.version === 'univ3') { saveRst = await this.v3LpModel.appendOrUpdate(lp) } else { throw Error(`Unknown factory version: ${factory.version}, hash is: ${factory.hash}.`) } if (!saveRst.state) throw Error(saveRst.msg) } getEffectiveLp(factory, position, lp) { // lp对象标准化 lp.symbol0 = this.tokenLib.getEffectiveSymbol(lp.symbol0) lp.symbol1 = this.tokenLib.getEffectiveSymbol(lp.symbol1) lp.name = `${factory.name}_${lp.symbol0}_${lp.symbol1}` lp.router = factory.router lp.factory = factory.hash lp.fee = factory.fee lp.positionId = position lp.r0Str = String(lp.r0) lp.r1Str = String(lp.r1) lp.level = LpLib.LEVEL.INIT // lp各种地址最小化 lp.hash = lp.hash.toLowerCase() lp.token0 = lp.token0.toLowerCase() lp.token1 = lp.token1.toLowerCase() // 字符化数字 lp.decimals0 = parseInt(lp.decimals0) lp.decimals1 = parseInt(lp.decimals1) // 链信息 lp.chainId = this.chain.id return lp } async getV2Pool(factory, position) { const info = await this.v2Tool.methods.getPairIdInfo(factory.hash, position).call() const lp = { hash: info['0'], decimals0: info['3'], decimals1: info['7'], r0: info['4'], r1: info['8'], symbol0: info['2'], symbol1: info['6'], token0: info['1'], token1: info['5'] } return this.getEffectiveLp(factory, position, lp) } async getV3Pool(factory, position) { const positionManager = this.factoryLib.getPositionManager(factory.positionManager) const positionInfo = await positionManager.methods.positions(position).call() const info = await this.v3Tool.methods.getMoreInfo(positionInfo.token0, positionInfo.token1, positionInfo.fee).call() const lp = { hash: info.lp, decimals0: info.decimals0, decimals1: info.decimals1, factory: factory.hash, feei: positionInfo.fee, id: position, r0: info.r0, r1: info.r1, router: factory.router, symbol0: symbol0, symbol1: symbol1, token0: positionInfo.token0, token1: positionInfo.token1 } return this.getEffectiveLp(factory, position, lp) } async getLpByPosition(factory, position) { // 1. 获取lp let lp = undefined if (factory.version === 'univ2') { return await this.getV2Pool(factory, position) } else if (factory.version === 'univ3') { return await this.getV3Pool(factory, position) } else { throw Error(`Unknown factory version: ${factory.version}, hash is: ${factory.hash}.`) } } }