import { BigInt, Address, Bytes, store, BigDecimal } from '@graphprotocol/graph-ts' import { LOG_CALL, LOG_JOIN, LOG_EXIT, LOG_SWAP, Transfer, GulpCall } from '../types/templates/Pool/Pool' import { Pool as BPool } from '../types/templates/Pool/Pool' import { log } from '@graphprotocol/graph-ts' import { OceanPools, Pool, PoolToken, PoolShare, Swap, TokenPrice } from '../types/schema' import { hexToDecimal, bigIntToDecimal, tokenToDecimal, createPoolShareEntity, createPoolTokenEntity, updatePoolLiquidity, saveTransaction, ZERO_BD, decrPoolCount } from './helpers' /************************************ ********** Pool Controls *********** ************************************/ export function handleSetSwapFee(event: LOG_CALL, swapFeeStr: string=null): void { let poolId = event.address.toHex() let pool = Pool.load(poolId) if (!swapFeeStr) { swapFeeStr = event.params.data.toHexString().slice(-40) } pool.swapFee = hexToDecimal(swapFeeStr, 18) pool.save() saveTransaction(event, 'setSwapFee') } export function handleSetController(event: LOG_CALL): void { let poolId = event.address.toHex() let pool = Pool.load(poolId) let controller = Address.fromString(event.params.data.toHexString().slice(-40)) pool.controller = controller pool.save() saveTransaction(event, 'setController') } export function handleSetPublicSwap(event: LOG_CALL): void { let poolId = event.address.toHex() let pool = Pool.load(poolId) let publicSwap = event.params.data.toHexString().slice(-1) == '1' pool.publicSwap = publicSwap pool.save() saveTransaction(event, 'setPublicSwap') } export function handleFinalize(event: LOG_CALL): void { let poolId = event.address.toHex() let pool = Pool.load(poolId) // let balance = BigDecimal.fromString('100') pool.finalized = true pool.symbol = 'BPT' pool.publicSwap = true // pool.totalShares = balance pool.save() /* let poolShareId = poolId.concat('-').concat(event.params.caller.toHex()) let poolShare = PoolShare.load(poolShareId) if (poolShare == null) { createPoolShareEntity(poolShareId, poolId, event.params.caller.toHex()) poolShare = PoolShare.load(poolShareId) } poolShare.balance = balance poolShare.save() */ let factory = OceanPools.load('1') factory.finalizedPoolCount = factory.finalizedPoolCount + 1 factory.save() saveTransaction(event, 'finalize') } export function handleSetup(event: LOG_CALL): void { let poolId = event.address.toHex() let data = event.params.data.toHexString() let dataTokenAddress = data.slice(34,74) let dataTokenAmount = data.slice(98,162) let dataTokenWeight = data.slice(162,226) let baseTokenAddress = data.slice(226, 290-24) let baseTokenAmount = data.slice(290,354) let baseTokenWeight = data.slice(354,418) let swapFee = data.slice(418) _handleRebind(event, poolId, dataTokenAddress, dataTokenAmount, dataTokenWeight) _handleRebind(event, poolId, baseTokenAddress, baseTokenAmount, baseTokenWeight) handleSetSwapFee(event, swapFee) handleFinalize(event) saveTransaction(event, 'setup') } export function _handleRebind(event: LOG_CALL, poolId: string, tokenAddress: string, balanceStr: string, denormWeightStr: string): void { let pool = Pool.load(poolId) let tokenBytes = Bytes.fromHexString(tokenAddress) as Bytes let tokensList = pool.tokensList || [] if (tokensList.indexOf(tokenBytes) == -1 ) { tokensList.push(tokenBytes) } pool.tokensList = tokensList pool.tokensCount = BigInt.fromI32(tokensList.length) let address = Address.fromString(tokenAddress) let denormWeight = hexToDecimal(denormWeightStr, 18) let poolTokenId = poolId.concat('-').concat(address.toHexString()) let poolToken = PoolToken.load(poolTokenId) if (poolToken == null) { createPoolTokenEntity(poolTokenId, poolId, address.toHexString()) poolToken = PoolToken.load(poolTokenId) pool.totalWeight += denormWeight } else { let oldWeight = poolToken.denormWeight if (denormWeight > oldWeight) { pool.totalWeight = pool.totalWeight + (denormWeight - oldWeight) } else { pool.totalWeight = pool.totalWeight - (oldWeight - denormWeight) } } let balance = hexToDecimal(balanceStr, poolToken.decimals) poolToken.balance = balance poolToken.denormWeight = denormWeight poolToken.save() if (balance.equals(ZERO_BD)) { decrPoolCount(pool.finalized) pool.active = false } pool.save() updatePoolLiquidity(poolId) } export function handleRebind(event: LOG_CALL): void { let poolId = event.address.toHex() _handleRebind( event, poolId, event.params.data.toHexString().slice(34,74), event.params.data.toHexString().slice(74,138), event.params.data.toHexString().slice(138) ) saveTransaction(event, 'rebind') } /************************************ ********** JOINS & EXITS *********** ************************************/ export function handleJoinPool(event: LOG_JOIN): void { let poolId = event.address.toHex() let pool = Pool.load(poolId) pool.joinsCount = pool.joinsCount.plus(BigInt.fromI32(1)) pool.save() let address = event.params.tokenIn.toHex() let poolTokenId = poolId.concat('-').concat(address.toString()) let poolToken = PoolToken.load(poolTokenId) if (!poolToken) { return } poolToken.decimals = BigInt.fromI32(18).toI32() let tokenAmountIn = tokenToDecimal(event.params.tokenAmountIn.toBigDecimal(), poolToken.decimals) poolToken.balance = poolToken.balance.plus(tokenAmountIn) poolToken.save() updatePoolLiquidity(poolId) saveTransaction(event, 'join') } export function handleExitPool(event: LOG_EXIT): void { let poolId = event.address.toHex() let address = event.params.tokenOut.toHex() let poolTokenId = poolId.concat('-').concat(address.toString()) let poolToken = PoolToken.load(poolTokenId) if (!poolToken) { return } let tokenAmountOut = tokenToDecimal(event.params.tokenAmountOut.toBigDecimal(), poolToken.decimals) let newAmount = poolToken.balance.minus(tokenAmountOut) poolToken.balance = newAmount poolToken.save() let pool = Pool.load(poolId) pool.exitsCount = pool.exitsCount.plus(BigInt.fromI32(1)) if (newAmount.equals(ZERO_BD)) { decrPoolCount(pool.finalized) pool.active = false } pool.save() updatePoolLiquidity(poolId) saveTransaction(event, 'exit') } /************************************ ************** SWAPS *************** ************************************/ export function handleSwap(event: LOG_SWAP): void { let poolId = event.address.toHex() let tokenIn = event.params.tokenIn.toHex() let poolTokenInId = poolId.concat('-').concat(tokenIn.toString()) let poolTokenIn = PoolToken.load(poolTokenInId) if (!poolTokenIn) { return } let tokenAmountIn = tokenToDecimal(event.params.tokenAmountIn.toBigDecimal(), poolTokenIn.decimals) let newAmountIn = poolTokenIn.balance.plus(tokenAmountIn) poolTokenIn.balance = newAmountIn poolTokenIn.save() let tokenOut = event.params.tokenOut.toHex() let poolTokenOutId = poolId.concat('-').concat(tokenOut.toString()) let poolTokenOut = PoolToken.load(poolTokenOutId) let tokenAmountOut = tokenToDecimal(event.params.tokenAmountOut.toBigDecimal(), poolTokenOut.decimals) let newAmountOut = poolTokenOut.balance.minus(tokenAmountOut) poolTokenOut.balance = newAmountOut poolTokenOut.save() updatePoolLiquidity(poolId) let swapId = event.transaction.hash.toHexString().concat('-').concat(event.logIndex.toString()) let swap = Swap.load(swapId) if (swap == null) { swap = new Swap(swapId) } let pool = Pool.load(poolId) let tokensList: Array = pool.tokensList let tokenOutPriceValue = ZERO_BD let tokenOutPrice = TokenPrice.load(tokenOut) if (tokenOutPrice != null) { tokenOutPriceValue = tokenOutPrice.price } else { for (let i: i32 = 0; i < tokensList.length; i++) { let tokenPriceId = tokensList[i].toHexString() if (!tokenOutPriceValue.gt(ZERO_BD) && tokenPriceId !== tokenOut) { let tokenPrice = TokenPrice.load(tokenPriceId) if (tokenPrice !== null && tokenPrice.price.gt(ZERO_BD)) { let poolTokenId = poolId.concat('-').concat(tokenPriceId) let poolToken = PoolToken.load(poolTokenId) tokenOutPriceValue = tokenPrice.price .times(poolToken.balance) .div(poolToken.denormWeight) .times(poolTokenOut.denormWeight) .div(poolTokenOut.balance) } } } } let totalSwapVolume = pool.totalSwapVolume let totalSwapFee = pool.totalSwapFee let liquidity = pool.liquidity let swapValue = ZERO_BD let swapFeeValue = ZERO_BD if (tokenOutPriceValue.gt(ZERO_BD)) { swapValue = tokenOutPriceValue.times(tokenAmountOut) swapFeeValue = swapValue.times(pool.swapFee) totalSwapVolume = totalSwapVolume.plus(swapValue) totalSwapFee = totalSwapFee.plus(swapFeeValue) let factory = OceanPools.load('1') factory.totalSwapVolume = factory.totalSwapVolume.plus(swapValue) factory.totalSwapFee = factory.totalSwapFee.plus(swapFeeValue) factory.save() pool.totalSwapVolume = totalSwapVolume pool.totalSwapFee = totalSwapFee } pool.swapsCount += BigInt.fromI32(1) if (newAmountIn.equals(ZERO_BD) || newAmountOut.equals(ZERO_BD)) { decrPoolCount(pool.finalized) pool.active = false } pool.save() swap.caller = event.params.caller swap.tokenIn = event.params.tokenIn swap.tokenInSym = poolTokenIn.symbol swap.tokenOut = event.params.tokenOut swap.tokenOutSym = poolTokenOut.symbol swap.tokenAmountIn = tokenAmountIn swap.tokenAmountOut = tokenAmountOut swap.poolAddress = event.address.toHex() swap.userAddress = event.transaction.from.toHex() swap.poolTotalSwapVolume = totalSwapVolume swap.poolTotalSwapFee = totalSwapFee swap.poolLiquidity = liquidity swap.value = swapValue swap.feeValue = swapFeeValue swap.timestamp = event.block.timestamp.toI32() swap.save() saveTransaction(event, 'swap') } /************************************ *********** POOL SHARES ************ ************************************/ export function handleTransfer(event: Transfer): void { let poolId = event.address.toHex() let ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' let isMint = event.params.from.toHex() == ZERO_ADDRESS let isBurn = event.params.to.toHex() == ZERO_ADDRESS let poolShareFromId = poolId.concat('-').concat(event.params.from.toHex()) let poolShareFrom = PoolShare.load(poolShareFromId) let poolShareFromBalance = poolShareFrom == null ? ZERO_BD : poolShareFrom.balance let poolShareToId = poolId.concat('-').concat(event.params.to.toHex()) let poolShareTo = PoolShare.load(poolShareToId) let poolShareToBalance = poolShareTo == null ? ZERO_BD : poolShareTo.balance let pool = Pool.load(poolId) if (isMint) { if (poolShareTo == null) { createPoolShareEntity(poolShareToId, poolId, event.params.to.toHex()) poolShareTo = PoolShare.load(poolShareToId) } poolShareTo.balance += tokenToDecimal(event.params.value.toBigDecimal(), 18) poolShareTo.save() pool.totalShares += tokenToDecimal(event.params.value.toBigDecimal(), 18) } else if (isBurn) { if (poolShareFrom == null) { createPoolShareEntity(poolShareFromId, poolId, event.params.from.toHex()) poolShareFrom = PoolShare.load(poolShareFromId) } poolShareFrom.balance -= tokenToDecimal(event.params.value.toBigDecimal(), 18) poolShareFrom.save() pool.totalShares -= tokenToDecimal(event.params.value.toBigDecimal(), 18) } else { if (poolShareTo == null) { createPoolShareEntity(poolShareToId, poolId, event.params.to.toHex()) poolShareTo = PoolShare.load(poolShareToId) } poolShareTo.balance += tokenToDecimal(event.params.value.toBigDecimal(), 18) poolShareTo.save() if (poolShareFrom == null) { createPoolShareEntity(poolShareFromId, poolId, event.params.from.toHex()) poolShareFrom = PoolShare.load(poolShareFromId) } poolShareFrom.balance -= tokenToDecimal(event.params.value.toBigDecimal(), 18) poolShareFrom.save() } if ( poolShareTo !== null && poolShareTo.balance.notEqual(ZERO_BD) && poolShareToBalance.equals(ZERO_BD) ) { pool.holdersCount += BigInt.fromI32(1) } if ( poolShareFrom !== null && poolShareFrom.balance.equals(ZERO_BD) && poolShareFromBalance.notEqual(ZERO_BD) ) { pool.holdersCount -= BigInt.fromI32(1) } pool.save() }