update schema to support pool reserve/price history and data token transaction history and balance history.

This commit is contained in:
ssallam 2020-12-02 11:07:09 +01:00
parent 53ac1a573a
commit 7184969ece
9 changed files with 324 additions and 409 deletions

2
package-lock.json generated
View File

@ -1,5 +1,5 @@
{
"name": "oceanpools",
"name": "ocean-subgraph",
"version": "0.1.0",
"lockfileVersion": 1,
"requires": true,

View File

@ -1,13 +1,13 @@
{
"name": "oceanpools",
"name": "ocean-subgraph",
"version": "0.1.0",
"scripts": {
"create": "graph create oceanprotocol/ocean-subgraph --node https://api.thegraph.com/deploy/",
"create:local": "graph create oceanprotocol/ocean-subgraph --node http://127.0.0.1:8020",
"codegen": "graph codegen --output-dir src/types/",
"build": "graph build",
"deploy": "graph deploy oceanprotocol/oceanpools --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
"deploy:beta": "graph deploy oceanprotocol/oceanpools-beta --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
"deploy": "graph deploy oceanprotocol/ocean-subgraph --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
"deploy:beta": "graph deploy oceanprotocol/ocean-subgraph-beta --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
"deploy:local": "graph deploy oceanprotocol/ocean-subgraph subgraph.yaml --debug --ipfs http://localhost:5001 --node http://127.0.0.1:8020"
},
"devDependencies": {

View File

@ -1,17 +1,20 @@
type OceanPools @entity {
type PoolFactory @entity {
id: ID!
color: String! # Bronze, Silver, Gold
poolCount: Int! # Number of pools
finalizedPoolCount: Int! # Number of finalized pools
pools: [Pool!] @derivedFrom(field: "factoryID")
txCount: BigInt! # Number of txs
totalLiquidity: BigDecimal! # All the pools liquidity value in Ocean
totalSwapVolume: BigDecimal! # All the swap volume in Ocean
totalSwapFee: BigDecimal! # All the swap fee in Ocean
poolCount: Int! # Number of pools
finalizedPoolCount: Int! # Number of finalized pools
txCount: BigInt! # Number of txs
pools: [Pool!] @derivedFrom(field: "factoryID")
}
type Pool @entity {
id: ID! # Pool address
factoryID: PoolFactory!
controller: Bytes! # Controller address
publicSwap: Boolean! # isPublicSwap
finalized: Boolean! # isFinalized
@ -20,30 +23,37 @@ type Pool @entity {
cap: BigInt # Maximum supply if any
active: Boolean! # isActive
swapFee: BigDecimal! # Swap Fees
totalWeight: BigDecimal!
totalShares: BigDecimal! # Total pool token shares
totalSwapVolume: BigDecimal! # Total swap volume in OCEAN
totalSwapFee: BigDecimal! # Total swap fee in OCEAN
liquidity: BigDecimal! # Pool liquidity value in OCEAN
tokensList: [Bytes!]! # Temp workaround until graph supports filtering on derived field
datatokenReserve: BigDecimal! # Total pool reserve of Datatoken
oceanReserve: BigDecimal! # Total pool reserve of OCEAN
spotPrice: BigDecimal!
consumePrice: BigDecimal!
tokenCount: BigInt! # Number of tokens in the pool
holderCount: BigInt! # Number of addresses holding a positive balance of pool shares
joinCount: BigInt! # liquidity has been added
exitCount: BigInt! # liquidity has been removed
swapCount: BigInt!
datatokenAddress: String!
createTime: Int! # Block time pool was created
tx: Bytes # Pool creation transaction id
tokens: [PoolToken!] @derivedFrom(field: "poolId")
shares: [PoolShare!] @derivedFrom(field: "poolId")
createTime: Int! # Block time pool was created
tokensCount: BigInt! # Number of tokens in the pool
holdersCount: BigInt! # Number of addresses holding a positive balance of BPT
joinsCount: BigInt! # liquidity has been added
exitsCount: BigInt! # liquidity has been removed
swapsCount: BigInt!
factoryID: OceanPools!
tx: Bytes # Pool creation transaction id
swaps: [Swap!] @derivedFrom(field: "poolAddress")
transactions: [PoolTransaction!] @derivedFrom(field: "poolAddress")
}
type PoolToken @entity {
id: ID! # poolId + token address
poolId: Pool!
tokenId: Datatoken
address: String
tokenAddress: String
balance: BigDecimal!
denormWeight: BigDecimal!
}
@ -55,70 +65,49 @@ type PoolShare @entity {
balance: BigDecimal!
}
type User @entity {
id: ID!
sharesOwned: [PoolShare!] @derivedFrom(field: "userAddress")
tokenBalancesOwned: [TokenBalance!] @derivedFrom(field: "userAddress")
tokensOwned: [Datatoken!] @derivedFrom(field: "minter")
poolTxs: [PoolTransaction!] @derivedFrom(field: "userAddress")
tokenTxs: [TokenTransaction!] @derivedFrom(field: "userAddress")
swaps: [Swap!] @derivedFrom(field: "userAddress")
}
type Swap @entity {
id: ID! #
caller: Bytes! #
tokenIn: Bytes! #
tokenInSym: String! #
tokenOut: Bytes! #
tokenOutSym: String! #
tokenAmountIn: BigDecimal! #
tokenAmountOut: BigDecimal! #
poolAddress: Pool
userAddress: User # User address that initiates the swap
value: BigDecimal! # Swap value in OCEAN
type PoolTransactionTokenValues @entity {
id: ID! # pool tx + tokenAddress
txId: PoolTransaction!
poolToken: PoolToken!
value: BigDecimal!
tokenReserve: BigDecimal!
feeValue: BigDecimal! # Swap fee value in OCEAN
poolTotalSwapVolume: BigDecimal! # Total pool swap volume in OCEAN
poolTotalSwapFee: BigDecimal! # Total pool swap fee in OCEAN
poolLiquidity: BigDecimal! # Pool liquidity value in OCEAN
timestamp: Int!
type: String!
}
type PoolTransaction @entity {
id: ID! # Log ID
id: ID! # pool tx
poolAddress: Pool
userAddress: User # User address that initiates the swap
sharesTransferAmount: BigDecimal! #
sharesBalance: BigDecimal!
spotPrice: BigDecimal!
consumePrice: BigDecimal!
tx: Bytes!
event: String
block: Int!
timestamp: Int!
gasUsed: BigDecimal!
gasPrice: BigDecimal!
poolAddress: Pool
userAddress: User
action: SwapType
sender: Bytes
tokens: [PoolTransactionTokenValues!] @derivedFrom(field: "txId")
}
type TokenPrice @entity {
type DatatokenFactory @entity {
id: ID!
symbol: String
name: String
decimals: Int!
price: BigDecimal!
poolLiquidity: BigDecimal!
poolTokenId: String
}
type OceanDatatokens @entity {
id: ID!
tokenCount: Int! # Number of datatokens
datatokens: [Datatoken!] @derivedFrom(field: "factoryID")
txCount: BigInt! # Number of txs
datatokens: [Datatoken!] @derivedFrom(field: "factoryID")
}
type Datatoken @entity {
id: ID! # token address
factoryID: OceanDatatokens!
factoryID: DatatokenFactory!
symbol: String
name: String
decimals: Int!
@ -127,24 +116,30 @@ type Datatoken @entity {
supply: BigDecimal!
minter: User!
publisher: User!
holderCount: BigInt! # Number of addresses holding a balance of datatoken
orderCount: BigInt! # Number of orders executed for this dataset
createTime: Int! # Block time datatoken was created
tx: Bytes # Datatoken creation transaction id
balances: [TokenBalance!] @derivedFrom(field: "datatokenId")
orders: [TokenOrder!] @derivedFrom(field: "datatokenId")
createTime: Int! # Block time datatoken was created
holdersCount: BigInt! # Number of addresses holding a balance of datatoken
orderCount: BigInt! # Number of orders executed for this dataset
tx: Bytes # Datatoken creation transaction id
}
type TokenOrder @entity {
id: ID! # datatokenId + userAddress + tx
datatokenId: Datatoken!
consumer: User!
payer: User!
amount: BigDecimal!
serviceId: Int!
timestamp: Int!
marketFeeCollector: User
marketFee: BigDecimal!
timestamp: Int!
tx: Bytes
}
@ -157,23 +152,25 @@ type TokenBalance @entity {
type TokenTransaction @entity {
id: ID! # Log ID
tx: Bytes!
event: String
block: Int!
timestamp: Int!
gasUsed: BigDecimal!
gasPrice: BigDecimal!
datatokenAddress: Datatoken
userAddress: User
sender: Bytes
block: Int!
gasUsed: BigDecimal!
gasPrice: BigDecimal!
timestamp: Int!
tx: Bytes!
}
enum SwapType {
swapExactAmountIn,
swapExactAmountOut,
joinswapExternAmountIn,
joinswapPoolAmountOut,
exitswapPoolAmountIn,
exitswapExternAmountOut
type User @entity {
id: ID!
sharesOwned: [PoolShare!] @derivedFrom(field: "userAddress")
tokenBalancesOwned: [TokenBalance!] @derivedFrom(field: "userAddress")
tokensOwned: [Datatoken!] @derivedFrom(field: "minter")
poolTransactions: [PoolTransaction!] @derivedFrom(field: "userAddress")
tokenTransactions: [TokenTransaction!] @derivedFrom(field: "userAddress")
orders: [TokenOrder!] @derivedFrom(field: "payer")
}

View File

@ -1,21 +1,16 @@
import { BigInt, Address, Bytes, store, BigDecimal } from '@graphprotocol/graph-ts'
import { BigInt, BigDecimal } from '@graphprotocol/graph-ts'
import { OrderStarted, Transfer } from '../types/templates/Datatoken/Datatoken'
import { Datatoken as DatatokenTemplate } from '../types/templates/Datatoken/Datatoken'
import { log } from '@graphprotocol/graph-ts'
import {
OceanDatatokens,
Datatoken, PoolShare, Pool, User, TokenBalance, TokenOrder
Datatoken, TokenBalance, TokenOrder
} from '../types/schema'
import {
hexToDecimal,
bigIntToDecimal,
tokenToDecimal,
createTokenBalanceEntity,
updateDatatokenBalance,
saveTokenTransaction,
ZERO_BD, createPoolShareEntity, createUserEntity
updateTokenBalance,
ZERO_BD,
MINUS_1, saveTokenTransaction
} from './helpers'
/************************************
@ -43,36 +38,27 @@ export function handleTransfer(event: Transfer): void {
let datatoken = Datatoken.load(tokenId)
if (isMint) {
createTokenBalanceEntity(tokenBalanceToId, tokenId, tokenShareTo)
tokenBalanceTo = TokenBalance.load(tokenBalanceToId)
let user = User.load(tokenShareTo)
oldBalanceTo = tokenBalanceTo.balance
tokenBalanceTo.balance += amount
tokenBalanceTo.save()
datatoken.supply += amount
oldBalanceTo = (tokenBalanceTo == null) ? ZERO_BD : tokenBalanceTo.balance
datatoken.supply = datatoken.supply.plus(amount)
updateTokenBalance(tokenBalanceToId, tokenId, tokenShareTo, amount)
} else if (isBurn) {
createTokenBalanceEntity(tokenBalanceFromId, tokenId, tokenShareFrom)
tokenBalanceFrom = TokenBalance.load(tokenBalanceFromId)
let user = User.load(tokenShareFrom)
oldBalanceFrom = tokenBalanceFrom.balance
tokenBalanceFrom.balance -= amount
tokenBalanceFrom.save()
datatoken.supply -= amount
oldBalanceFrom = (tokenBalanceFrom == null) ? ZERO_BD : tokenBalanceFrom.balance
datatoken.supply = datatoken.supply.minus(amount)
updateTokenBalance(tokenBalanceFromId, tokenId, tokenShareFrom, amount.times(MINUS_1))
} else {
createTokenBalanceEntity(tokenBalanceFromId, tokenId, tokenShareFrom)
let userFrom = User.load(tokenShareFrom)
tokenBalanceFrom = TokenBalance.load(tokenBalanceFromId)
oldBalanceFrom = tokenBalanceFrom.balance
tokenBalanceFrom.balance -= amount
tokenBalanceFrom.save()
oldBalanceFrom = (tokenBalanceFrom == null) ? ZERO_BD : tokenBalanceFrom.balance
datatoken.supply = datatoken.supply.minus(amount)
updateTokenBalance(tokenBalanceFromId, tokenId, tokenShareFrom, amount.times(MINUS_1))
createTokenBalanceEntity(tokenBalanceToId, tokenId, tokenShareTo)
let userTo = User.load(tokenShareTo)
tokenBalanceTo = TokenBalance.load(tokenBalanceToId)
oldBalanceTo = tokenBalanceTo.balance
tokenBalanceTo.balance += amount
tokenBalanceTo.save()
oldBalanceTo = (tokenBalanceTo == null) ? ZERO_BD : tokenBalanceTo.balance
datatoken.supply = datatoken.supply.plus(amount)
updateTokenBalance(tokenBalanceToId, tokenId, tokenShareTo, amount)
}
if (
@ -80,7 +66,7 @@ export function handleTransfer(event: Transfer): void {
&& tokenBalanceTo.balance.notEqual(ZERO_BD)
&& oldBalanceTo.equals(ZERO_BD)
) {
datatoken.holdersCount += BigInt.fromI32(1)
datatoken.holderCount = datatoken.holderCount.plus(BigInt.fromI32(1))
}
if (
@ -88,10 +74,11 @@ export function handleTransfer(event: Transfer): void {
&& tokenBalanceFrom.balance.equals(ZERO_BD)
&& oldBalanceFrom.notEqual(ZERO_BD)
) {
datatoken.holdersCount -= BigInt.fromI32(1)
datatoken.holderCount = datatoken.holderCount.minus(BigInt.fromI32(1))
}
datatoken.save()
saveTokenTransaction(event, 'Transfer')
}
export function handleOrderStarted(event: OrderStarted): void {
@ -100,7 +87,6 @@ export function handleOrderStarted(event: OrderStarted): void {
let datatoken = Datatoken.load(tokenId)
if (datatoken == null) return
let payer = event.params.payer.toHex()
// let feeCollector = event.params.mrktFeeCollector
// let marketFee = event.params.marketFee
@ -123,6 +109,9 @@ export function handleOrderStarted(event: OrderStarted): void {
order.tx = tx
order.save()
datatoken.orderCount = datatoken.orderCount + BigInt.fromI32(1)
datatoken.orderCount = datatoken.orderCount.plus(BigInt.fromI32(1))
datatoken.save()
saveTokenTransaction(event, 'OrderStarted')
}

View File

@ -1,6 +1,6 @@
import { Address, BigInt, BigDecimal } from '@graphprotocol/graph-ts'
import { BigInt } from '@graphprotocol/graph-ts'
import { TokenRegistered } from '../types/DTFactory/DTFactory'
import { OceanDatatokens, Datatoken } from '../types/schema'
import { DatatokenFactory, Datatoken } from '../types/schema'
import { Datatoken as DatatokenContract } from '../types/templates'
import {
tokenToDecimal,
@ -9,11 +9,11 @@ import {
import { log } from '@graphprotocol/graph-ts'
export function handleNewToken(event: TokenRegistered): void {
let factory = OceanDatatokens.load('1')
let factory = DatatokenFactory.load('1')
// if no factory yet, set up blank initial
if (factory == null) {
factory = new OceanDatatokens('1')
factory = new DatatokenFactory('1')
factory.tokenCount = 0
factory.txCount = BigInt.fromI32(0)
}
@ -22,6 +22,7 @@ export function handleNewToken(event: TokenRegistered): void {
log.error('************************ handleNewToken: datatokenId {}', [datatoken.id.toString()])
datatoken.factoryID = event.address.toHexString()
datatoken.symbol = event.params.tokenSymbol
datatoken.name = event.params.tokenName
datatoken.decimals = 18
@ -30,9 +31,11 @@ export function handleNewToken(event: TokenRegistered): void {
datatoken.supply = ZERO_BD
datatoken.minter = event.params.registeredBy.toHex()
datatoken.publisher = event.params.registeredBy.toHex()
datatoken.createTime = event.block.timestamp.toI32()
datatoken.holdersCount = BigInt.fromI32(0)
datatoken.holderCount = BigInt.fromI32(0)
datatoken.orderCount = BigInt.fromI32(0)
datatoken.createTime = event.block.timestamp.toI32()
datatoken.tx = event.transaction.hash
datatoken.save()

View File

@ -1,6 +1,6 @@
import { Address, BigInt, BigDecimal } from '@graphprotocol/graph-ts'
import { BPoolRegistered } from '../types/Factory/Factory'
import { OceanPools, Pool } from '../types/schema'
import { PoolFactory, Pool } from '../types/schema'
import { Pool as PoolContract } from '../types/templates'
import {
ZERO_BD,
@ -8,41 +8,54 @@ import {
import { log } from '@graphprotocol/graph-ts'
export function handleNewPool(event: BPoolRegistered): void {
let factory = OceanPools.load('1')
let factory = PoolFactory.load('1')
// if no factory yet, set up blank initial
if (factory == null) {
factory = new OceanPools('1')
factory.color = 'Bronze'
factory.poolCount = 0
factory.finalizedPoolCount = 0
factory.txCount = BigInt.fromI32(0)
factory = new PoolFactory('1')
factory.totalLiquidity = ZERO_BD
factory.totalSwapVolume = ZERO_BD
factory.totalSwapFee = ZERO_BD
factory.poolCount = 0
factory.finalizedPoolCount = 0
factory.txCount = BigInt.fromI32(0)
}
let pool = new Pool(event.params.bpoolAddress.toHexString())
log.error('************************ handleNewPool: poolId {}', [pool.id.toString()])
pool.factoryID = event.address.toHexString()
pool.controller = event.params.registeredBy
pool.publicSwap = false
pool.finalized = false
pool.symbol = ''
pool.name = ''
// pool.cap =
pool.active = true
pool.swapFee = BigDecimal.fromString('0.000001')
pool.totalWeight = ZERO_BD
pool.totalShares = ZERO_BD
pool.totalSwapVolume = ZERO_BD
pool.totalSwapFee = ZERO_BD
pool.liquidity = ZERO_BD
pool.datatokenReserve = ZERO_BD
pool.oceanReserve = ZERO_BD
pool.spotPrice = ZERO_BD //: BigDecimal!
pool.consumePrice = ZERO_BD //: BigDecimal!
pool.tokenCount = BigInt.fromI32(0)
pool.holderCount = BigInt.fromI32(0)
pool.joinCount = BigInt.fromI32(0)
pool.exitCount = BigInt.fromI32(0)
pool.swapCount = BigInt.fromI32(0)
pool.datatokenAddress = ''
pool.createTime = event.block.timestamp.toI32()
pool.tokensCount = BigInt.fromI32(0)
pool.holdersCount = BigInt.fromI32(0)
pool.joinsCount = BigInt.fromI32(0)
pool.exitsCount = BigInt.fromI32(0)
pool.swapsCount = BigInt.fromI32(0)
pool.factoryID = event.address.toHexString()
pool.tokensList = []
pool.tx = event.transaction.hash
pool.save()
factory.poolCount = factory.poolCount + 1

View File

@ -1,6 +1,5 @@
import {
BigDecimal,
Address,
BigInt,
Bytes,
dataSource,
@ -11,14 +10,18 @@ import {
User,
PoolToken,
PoolShare,
TokenPrice,
PoolTransaction,
OceanPools, Datatoken, TokenBalance, TokenTransaction
PoolFactory,
Datatoken,
TokenBalance,
TokenTransaction,
PoolTransactionTokenValues
} from '../types/schema'
import { BToken } from '../types/templates/Pool/BToken'
import { log } from '@graphprotocol/graph-ts'
export let ZERO_BD = BigDecimal.fromString('0')
export let ZERO_BD = BigDecimal.fromString('0.0')
export let MINUS_1 = BigDecimal.fromString('-1.0')
export let ONE = BigDecimal.fromString('1.0')
let network = dataSource.network()
@ -60,127 +63,107 @@ export function createPoolTokenEntity(id: string, pool: string, address: string)
let poolToken = new PoolToken(id)
poolToken.poolId = pool
poolToken.tokenId = datatoken ? datatoken.id: ''
poolToken.address = address
poolToken.tokenAddress = address
poolToken.balance = ZERO_BD
poolToken.denormWeight = ZERO_BD
poolToken.save()
}
export function updatePoolLiquidity(id: string): void {
let pool = Pool.load(id)
let tokensList: Array<Bytes> = pool.tokensList
export function updatePoolTransactionToken(
poolTx: string, poolTokenId: string, amount: BigDecimal,
balance: BigDecimal, feeValue: BigDecimal
): void {
if (!tokensList || pool.tokensCount.lt(BigInt.fromI32(2)) || !pool.publicSwap) return
if (tokensList[0] != Address.fromString(OCEAN)) return
// Find pool liquidity
let hasPrice = false
let hasOceanPrice = false
let poolOcnLiquidity = ZERO_BD
let poolDTLiquidity = ZERO_BD
return
let oceanPoolTokenId = id.concat('-').concat(OCEAN)
let oceanPoolToken = PoolToken.load(oceanPoolTokenId)
poolOcnLiquidity = oceanPoolToken.balance.div(oceanPoolToken.denormWeight).times(pool.totalWeight)
let DT = tokensList[1].toHexString()
let dtTokenPrice = TokenPrice.load(DT)
if (dtTokenPrice !== null) {
let poolTokenId = id.concat('-').concat(DT)
let poolToken = PoolToken.load(poolTokenId)
poolDTLiquidity = TokenPrice.price.times(poolToken.balance).div(poolToken.denormWeight).times(pool.totalWeight)
hasPrice = true
let ptxTokenValuesId = poolTx.concat('-').concat(poolToken.tokenAddress)
let ptxTokenValues = PoolTransactionTokenValues.load(ptxTokenValuesId)
if (ptxTokenValues == null) {
ptxTokenValues = new PoolTransactionTokenValues(ptxTokenValuesId)
}
ptxTokenValues.txId = poolTx
ptxTokenValues.poolToken = poolTokenId
ptxTokenValues.value = amount
ptxTokenValues.tokenReserve = balance.plus(amount)
ptxTokenValues.feeValue = feeValue
if (amount.lt(ZERO_BD)) {
ptxTokenValues.type = 'out'
} else {
ptxTokenValues.type = 'in'
}
// // Create or update token price
//
// if (hasPrice) {
// for (let i: i32 = 0; i < tokensList.length; i++) {
// let tokenPriceId = tokensList[i].toHexString()
// let tokenPrice = TokenPrice.load(tokenPriceId)
// if (tokenPrice == null) {
// tokenPrice = new TokenPrice(tokenPriceId)
// tokenPrice.poolTokenId = ''
// tokenPrice.poolLiquidity = ZERO_BD
// }
//
// let poolTokenId = id.concat('-').concat(tokenPriceId)
// let poolToken = PoolToken.load(poolTokenId)
//
// if (
// (tokenPrice.poolTokenId == poolTokenId || poolLiquidity.gt(tokenPrice.poolLiquidity)) &&
// (tokenPriceId != WETH.toString() || (pool.tokensCount.equals(BigInt.fromI32(2)) && hasUsdPrice))
// ) {
// tokenPrice.price = ZERO_BD
//
// if (poolToken.balance.gt(ZERO_BD)) {
// tokenPrice.price = poolLiquidity.div(pool.totalWeight).times(poolToken.denormWeight).div(poolToken.balance)
// }
//
// tokenPrice.symbol = poolToken.symbol
// tokenPrice.name = poolToken.name
// tokenPrice.decimals = poolToken.decimals
// tokenPrice.poolLiquidity = poolLiquidity
// tokenPrice.poolTokenId = poolTokenId
// tokenPrice.save()
// }
// }
// }
// Update pool liquidity
let liquidity = ZERO_BD
let denormWeight = ZERO_BD
for (let i: i32 = 0; i < tokensList.length; i++) {
let tokenPriceId = tokensList[i].toHexString()
let tokenPrice = TokenPrice.load(tokenPriceId)
if (tokenPrice !== null) {
let poolTokenId = id.concat('-').concat(tokenPriceId)
let poolToken = PoolToken.load(poolTokenId)
if (poolToken.denormWeight.gt(denormWeight)) {
denormWeight = poolToken.denormWeight
liquidity = tokenPrice.price.times(poolToken.balance).div(poolToken.denormWeight).times(pool.totalWeight)
}
}
ptxTokenValues.save()
}
let factory = OceanPools.load('1')
factory.totalLiquidity = factory.totalLiquidity.minus(pool.liquidity).plus(liquidity)
factory.save()
export function createPoolTransaction(event: ethereum.Event, event_type: string, userAddress: string): void {
let poolId = event.address.toHex()
let pool = Pool.load(poolId)
pool.liquidity = liquidity
pool.save()
let ptx = event.transaction.hash.toHexString()
let ocnToken = PoolToken.load(poolId.concat('-').concat(OCEAN))
let dtToken = PoolToken.load(poolId.concat('-').concat(pool.datatokenAddress))
if (ocnToken == null || dtToken == null) return
let poolTx = PoolTransaction.load(ptx)
if (poolTx == null) {
poolTx = new PoolTransaction(ptx)
}
poolTx.poolAddress = poolId
poolTx.userAddress = userAddress
poolTx.sharesTransferAmount = ZERO_BD
poolTx.sharesBalance = ZERO_BD
// poolTx.spotPrice = ZERO_BD
poolTx.spotPrice = calcSpotPrice(
ocnToken.denormWeight, dtToken.denormWeight, ocnToken.balance, dtToken.balance, pool.swapFee)
// poolTx.consumePrice = calcInGivenOut(
// ocnToken.denormWeight, dtToken.denormWeight, ocnToken.balance, dtToken.balance,
// ONE, pool.swapFee)
poolTx.consumePrice = ZERO_BD
poolTx.tx = event.transaction.hash
poolTx.event = event_type
poolTx.block = event.block.number.toI32()
poolTx.timestamp = event.block.timestamp.toI32()
poolTx.gasUsed = event.transaction.gasUsed.toBigDecimal()
poolTx.gasPrice = event.transaction.gasPrice.toBigDecimal()
poolTx.save()
}
export function calcSpotPrice(
wIn: BigDecimal, wOut: BigDecimal,
balanceIn: BigDecimal, balanceOut: BigDecimal,
swapFee: BigDecimal
): BigDecimal {
let numer = balanceIn.div(wIn)
let denom = balanceOut.div(wOut)
let ratio = numer.div(denom)
let scale = ONE.div(ONE.minus(swapFee))
return ratio.times(scale)
}
// export function calcInGivenOut(
// wIn: BigDecimal, wOut: BigDecimal, balanceIn: BigDecimal, balanceOut: BigDecimal,
// amountOut: BigDecimal, swapFee: BigDecimal): BigDecimal {
//
// let weightRatio = wOut.div(wIn)
// let diff = balanceOut.minus(amountOut)
// let y = balanceOut.div(diff)
// y.toString()
//
// let foo = BigDecimal.fromString(Math.pow(y, weightRatio).toString()) - ONE
// return balanceIn.times(foo / (ONE - swapFee))
// }
export function decrPoolCount(finalized: boolean): void {
let factory = OceanPools.load('1')
let factory = PoolFactory.load('1')
factory.poolCount -= 1
if (finalized) factory.finalizedPoolCount -= 1
factory.save()
}
export function savePoolTransaction(event: ethereum.Event, eventName: string): void {
let tx = event.transaction.hash.toHexString().concat('-').concat(event.logIndex.toString())
let userAddress = event.transaction.from.toHex()
let transaction = PoolTransaction.load(tx)
if (transaction == null) {
transaction = new PoolTransaction(tx)
}
transaction.event = eventName
transaction.poolAddress = event.address.toHex()
transaction.userAddress = userAddress
transaction.gasUsed = event.transaction.gasUsed.toBigDecimal()
transaction.gasPrice = event.transaction.gasPrice.toBigDecimal()
transaction.tx = event.transaction.hash
transaction.timestamp = event.block.timestamp.toI32()
transaction.block = event.block.number.toI32()
transaction.save()
createUserEntity(userAddress)
}
export function saveTokenTransaction(event: ethereum.Event, eventName: string): void {
let tx = event.transaction.hash.toHexString().concat('-').concat(event.logIndex.toString())
let userAddress = event.transaction.from.toHex()
@ -208,17 +191,16 @@ export function createUserEntity(address: string): void {
}
}
export function createTokenBalanceEntity(id: string, token: string, user: string): void {
if (TokenBalance.load(id) != null) return
let tokenBalance = new TokenBalance(id)
export function updateTokenBalance(id: string, token: string, user: string, amount: BigDecimal): void {
let tokenBalance = TokenBalance.load(id)
if (tokenBalance == null) {
tokenBalance = new TokenBalance(id)
createUserEntity(user)
tokenBalance.userAddress = user
tokenBalance.datatokenId = token
tokenBalance.balance = ZERO_BD
}
tokenBalance.balance = tokenBalance.balance.plus(amount)
tokenBalance.save()
}
export function updateDatatokenBalance(): void {
}

View File

@ -1,27 +1,25 @@
import { BigInt, Address, Bytes, store, BigDecimal } from '@graphprotocol/graph-ts'
import {BigInt, Address, BigDecimal} from '@graphprotocol/graph-ts'
import { LOG_CALL, LOG_JOIN, LOG_EXIT, LOG_SWAP, Transfer } from '../types/templates/Pool/Pool'
import { Pool as BPool } from '../types/templates/Pool/Pool'
import { log } from '@graphprotocol/graph-ts'
import {
OceanPools,
PoolFactory,
Pool,
PoolToken,
PoolShare,
Swap,
TokenPrice, Datatoken
Datatoken, PoolTransaction, PoolTransactionTokenValues
} from '../types/schema'
import {
hexToDecimal,
bigIntToDecimal,
tokenToDecimal,
createPoolShareEntity,
createPoolTokenEntity,
updatePoolLiquidity,
savePoolTransaction,
ZERO_BD,
decrPoolCount
MINUS_1,
decrPoolCount,
updatePoolTransactionToken,
createPoolTransaction, OCEAN,
} from './helpers'
/************************************
@ -36,18 +34,13 @@ export function handleSetSwapFee(event: LOG_CALL, swapFeeStr: string=null): void
}
pool.swapFee = hexToDecimal(swapFeeStr, 18)
pool.save()
// savePoolTransaction(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.controller = Address.fromString(event.params.data.toHexString().slice(-40))
pool.save()
// savePoolTransaction(event, 'setController')
}
export function handleSetPublicSwap(event: LOG_CALL): void {
@ -55,36 +48,19 @@ export function handleSetPublicSwap(event: LOG_CALL): void {
let pool = Pool.load(poolId)
pool.publicSwap = event.params.data.toHexString().slice(-1) == '1'
pool.save()
// savePoolTransaction(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')
let factory = PoolFactory.load('1')
factory.finalizedPoolCount = factory.finalizedPoolCount + 1
factory.save()
// savePoolTransaction(event, 'finalize')
}
export function handleSetup(event: LOG_CALL): void {
@ -107,30 +83,24 @@ export function handleSetup(event: LOG_CALL): void {
let baseTokenAmount = data.slice(266,330) // (74+(3*64),74+(4*64))
let baseTokenWeight = data.slice(330,394) // (74+(4*64),74+(5*64))
let swapFee = data.slice(394) // (74+(5*64), END)
// log.error('handleSetup: ##{}, {}, {}, {}, {}, {}, {}##, \nDATA=##{} ##\n lenData={}',
// [dataTokenAddress, dataTokenAmount, dataTokenWeight, baseTokenAddress, baseTokenAmount, baseTokenWeight, swapFee, data, BigInt.fromI32(data.length).toString()])
_handleRebind(event, poolId, dataTokenAddress, dataTokenAmount, dataTokenWeight)
_handleRebind(event, poolId, baseTokenAddress, baseTokenAmount, baseTokenWeight)
handleSetSwapFee(event, swapFee)
handleFinalize(event)
savePoolTransaction(event, 'setup')
}
export function _handleRebind(event: LOG_CALL, poolId: string, tokenAddress: string, balanceStr: string, denormWeightStr: string): void {
let pool = Pool.load(poolId)
let decimals = BigInt.fromI32(18).toI32()
let tokenBytes = Bytes.fromHexString(tokenAddress) as Bytes
let tokensList = pool.tokensList || []
if (tokensList.indexOf(tokenBytes) == -1 ) {
tokensList.push(tokenBytes)
if (tokenAddress != OCEAN ) {
pool.datatokenAddress = tokenAddress
}
pool.tokensList = tokensList
pool.tokensCount = BigInt.fromI32(tokensList.length)
pool.tokenCount = BigInt.fromI32(2)
let address = Address.fromString(tokenAddress)
let denormWeight = hexToDecimal(denormWeightStr, decimals)
let poolTokenId = poolId.concat('-').concat(address.toHexString())
let poolToken = PoolToken.load(poolTokenId)
if (poolToken == null) {
@ -146,9 +116,9 @@ export function _handleRebind(event: LOG_CALL, poolId: string, tokenAddress: str
}
}
let balance = hexToDecimal(balanceStr, decimals)
poolToken.balance = balance
poolToken.denormWeight = denormWeight
poolToken.save()
if (balance.equals(ZERO_BD)) {
@ -156,8 +126,6 @@ export function _handleRebind(event: LOG_CALL, poolId: string, tokenAddress: str
pool.active = false
}
pool.save()
updatePoolLiquidity(poolId)
}
export function handleRebind(event: LOG_CALL): void {
@ -169,9 +137,6 @@ export function handleRebind(event: LOG_CALL): void {
event.params.data.toHexString().slice(74,138),
event.params.data.toHexString().slice(138)
)
savePoolTransaction(event, 'rebind')
}
/************************************
@ -182,13 +147,17 @@ 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))
if (pool.finalized == false){
return
}
pool.joinCount = pool.joinCount.plus(BigInt.fromI32(1))
pool.save()
let address = event.params.tokenIn.toHex()
let poolTokenId = poolId.concat('-').concat(address.toString())
let poolTokenId = poolId.concat('-').concat(address)
let poolToken = PoolToken.load(poolTokenId)
if (!poolToken) {
if (poolToken == null) {
return
}
@ -199,8 +168,12 @@ export function handleJoinPool(event: LOG_JOIN): void {
poolToken.balance = poolToken.balance.plus(tokenAmountIn)
poolToken.save()
updatePoolLiquidity(poolId)
savePoolTransaction(event, 'join')
createPoolTransaction(event, 'join', event.params.caller.toHexString())
updatePoolTransactionToken(
event.transaction.hash.toHexString(), poolTokenId,
tokenAmountIn, poolToken.balance,
tokenAmountIn.times(pool.swapFee)
)
}
export function handleExitPool(event: LOG_EXIT): void {
@ -222,15 +195,19 @@ export function handleExitPool(event: LOG_EXIT): void {
poolToken.save()
let pool = Pool.load(poolId)
pool.exitsCount = pool.exitsCount.plus(BigInt.fromI32(1))
pool.exitCount = pool.exitCount.plus(BigInt.fromI32(1))
if (newAmount.equals(ZERO_BD)) {
decrPoolCount(pool.finalized)
pool.active = false
}
pool.save()
updatePoolLiquidity(poolId)
savePoolTransaction(event, 'exit')
createPoolTransaction(event, 'exit', event.params.caller.toHexString())
updatePoolTransactionToken(
event.transaction.hash.toHexString(), poolTokenId,
tokenAmountOut.times(MINUS_1), poolToken.balance,
tokenAmountOut.times(pool.swapFee)
)
}
/************************************
@ -239,6 +216,7 @@ export function handleExitPool(event: LOG_EXIT): void {
export function handleSwap(event: LOG_SWAP): void {
let poolId = event.address.toHex()
let ptx = event.transaction.hash.toHexString()
let tokenIn = event.params.tokenIn.toHex()
let poolTokenInId = poolId.concat('-').concat(tokenIn.toString())
@ -261,84 +239,22 @@ export function handleSwap(event: LOG_SWAP): void {
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<Bytes> = 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)
pool.swapCount += 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 = (dtIn == null) ? 'OCEAN' : dtIn.symbol
swap.tokenOut = event.params.tokenOut
swap.tokenOutSym = (dtOut == null) ? 'OCEAN' : dtOut.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()
savePoolTransaction(event, 'swap')
createPoolTransaction(event, 'swap', event.params.caller.toHexString())
updatePoolTransactionToken(
ptx, poolTokenIn.id, tokenAmountIn, poolTokenIn.balance,
tokenAmountIn.times(pool.swapFee))
updatePoolTransactionToken(
ptx, poolTokenOut.id, tokenAmountOut.times(MINUS_1), poolTokenOut.balance,
BigDecimal.fromString('0.0'))
}
/************************************
@ -362,36 +278,47 @@ export function handleSwap(event: LOG_SWAP): void {
let poolShareToBalance = poolShareTo == null ? ZERO_BD : poolShareTo.balance
let pool = Pool.load(poolId)
let poolTx = PoolTransaction.load(event.transaction.hash.toHexString())
let value = tokenToDecimal(event.params.value.toBigDecimal(), 18)
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.balance += value
poolShareTo.save()
pool.totalShares += tokenToDecimal(event.params.value.toBigDecimal(), 18)
pool.totalShares += value
if (poolTx != null) {
poolTx.sharesTransferAmount = value
poolTx.sharesBalance = poolShareTo.balance
}
} 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.balance -= value
poolShareFrom.save()
pool.totalShares -= tokenToDecimal(event.params.value.toBigDecimal(), 18)
pool.totalShares -= value
if (poolTx != null) {
poolTx.sharesTransferAmount = -value
poolTx.sharesBalance = poolShareFrom.balance
}
} else {
if (poolShareTo == null) {
createPoolShareEntity(poolShareToId, poolId, event.params.to.toHex())
poolShareTo = PoolShare.load(poolShareToId)
}
poolShareTo.balance += tokenToDecimal(event.params.value.toBigDecimal(), 18)
poolShareTo.balance += value
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.balance -= value
poolShareFrom.save()
}
@ -400,7 +327,7 @@ export function handleSwap(event: LOG_SWAP): void {
&& poolShareTo.balance.notEqual(ZERO_BD)
&& poolShareToBalance.equals(ZERO_BD)
) {
pool.holdersCount += BigInt.fromI32(1)
pool.holderCount += BigInt.fromI32(1)
}
if (
@ -408,7 +335,11 @@ export function handleSwap(event: LOG_SWAP): void {
&& poolShareFrom.balance.equals(ZERO_BD)
&& poolShareFromBalance.notEqual(ZERO_BD)
) {
pool.holdersCount -= BigInt.fromI32(1)
pool.holderCount -= BigInt.fromI32(1)
}
if (poolTx != null) {
poolTx.save()
}
pool.save()

View File

@ -17,7 +17,7 @@ dataSources:
language: wasm/assemblyscript
file: ./src/mappings/factory.ts
entities:
- OceanPools
- PoolFactory
abis:
- name: Factory
file: ./abis/BFactory.json
@ -37,7 +37,7 @@ dataSources:
language: wasm/assemblyscript
file: ./src/mappings/dtfactory.ts
entities:
- OceanDatatokens
- DatatokenFactory
abis:
- name: DTFactory
file: ./abis/DTFactory.json
@ -57,7 +57,7 @@ templates:
file: ./src/mappings/pool.ts
entities:
- Pool
- OceanPools
- PoolFactory
- Swap
abis:
- name: Pool
@ -107,7 +107,7 @@ templates:
file: ./src/mappings/datatoken.ts
entities:
- Datatoken
- OceanDatatokens
- DatatokenFactory
abis:
- name: Datatoken
file: ./abis/DataTokenTemplate.json