add datatoken mapping and handlers

This commit is contained in:
ssallam 2020-11-26 07:38:08 +01:00
parent 49461245d4
commit 316dbeb9ad
8 changed files with 19456 additions and 84 deletions

4577
abis/DTFactory.json Normal file

File diff suppressed because one or more lines are too long

14594
abis/DataTokenTemplate.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -42,10 +42,8 @@ type Pool @entity {
type PoolToken @entity {
id: ID! # poolId + token address
poolId: Pool!
symbol: String
name: String
decimals: Int!
address: String!
tokenId: Datatoken
address: String
balance: BigDecimal!
denormWeight: BigDecimal!
}
@ -60,8 +58,12 @@ type PoolShare @entity {
type User @entity {
id: ID!
sharesOwned: [PoolShare!] @derivedFrom(field: "userAddress")
txs: [Transaction!] @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 {
@ -83,7 +85,7 @@ type Swap @entity {
timestamp: Int!
}
type Transaction @entity {
type PoolTransaction @entity {
id: ID! # Log ID
tx: Bytes!
event: String
@ -107,6 +109,51 @@ type TokenPrice @entity {
poolTokenId: String
}
type OceanDatatokens @entity {
id: ID!
tokenCount: Int! # Number of datatokens
datatokens: [Datatoken!] @derivedFrom(field: "factoryID")
txCount: BigInt! # Number of txs
}
type Datatoken @entity {
id: ID! # token address
factoryID: OceanDatatokens!
symbol: String
name: String
decimals: Int!
address: String!
cap: BigDecimal!
supply: BigDecimal!
minter: User!
publisher: User!
balances: [TokenBalance!] @derivedFrom(field: "datatokenId")
createTime: Int! # Block time datatoken was created
holdersCount: BigInt! # Number of addresses holding a balance of datatoken
tx: Bytes # Datatoken creation transaction id
}
type TokenBalance @entity {
id: ID! # datatokenId + userAddress
userAddress: User!
datatokenId: Datatoken!
balance: BigDecimal!
}
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
}
enum SwapType {
swapExactAmountIn,
swapExactAmountOut,

99
src/mappings/datatoken.ts Normal file
View File

@ -0,0 +1,99 @@
import { BigInt, Address, Bytes, store, 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
} from '../types/schema'
import {
hexToDecimal,
bigIntToDecimal,
tokenToDecimal,
createTokenBalanceEntity,
updateDatatokenBalance,
saveTransaction,
ZERO_BD, createPoolShareEntity, createUserEntity
} from './helpers'
/************************************
********** Pool Controls ***********
************************************/
export function handleTransfer(event: Transfer): void {
let tokenId = event.address.toHex()
let ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
let isMint = event.params.from.toHex() == ZERO_ADDRESS
let isBurn = event.params.to.toHex() == ZERO_ADDRESS
let amount = tokenToDecimal(event.params.value.toBigDecimal(), 18)
let tokenShareFrom = event.params.from.toHex()
let tokenShareTo = event.params.to.toHex()
let tokenBalanceFromId = tokenId.concat('-').concat(event.params.from.toHex())
let tokenBalanceToId = tokenId.concat('-').concat(event.params.to.toHex())
let tokenBalanceFrom = TokenBalance.load(tokenBalanceFromId)
let tokenBalanceTo = TokenBalance.load(tokenBalanceToId)
let oldBalanceFrom = 0
let oldBalanceTo = 0
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
} 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
} else {
createTokenBalanceEntity(tokenBalanceFromId, tokenId, tokenShareFrom)
let userFrom = User.load(tokenShareFrom)
tokenBalanceFrom = TokenBalance.load(tokenBalanceFromId)
oldBalanceFrom = tokenBalanceFrom.balance
tokenBalanceFrom.balance -= amount
tokenBalanceFrom.save()
createTokenBalanceEntity(tokenBalanceToId, tokenId, tokenShareTo)
let userTo = User.load(tokenShareTo)
tokenBalanceTo = TokenBalance.load(tokenBalanceToId)
oldBalanceTo = tokenBalanceTo.balance
tokenBalanceTo.balance += amount
tokenBalanceTo.save()
}
if (
tokenBalanceTo !== null
&& tokenBalanceTo.balance.notEqual(ZERO_BD)
&& oldBalanceTo.equals(ZERO_BD)
) {
datatoken.holdersCount += BigInt.fromI32(1)
}
if (
tokenBalanceFrom !== null
&& tokenBalanceFrom.balance.equals(ZERO_BD)
&& oldBalanceFrom.notEqual(ZERO_BD)
) {
datatoken.holdersCount -= BigInt.fromI32(1)
}
datatoken.save()
}
export function handleOrderStarted(event: OrderStarted): void {
}

35
src/mappings/dtfactory.ts Normal file
View File

@ -0,0 +1,35 @@
import { Address, BigInt, BigDecimal } from '@graphprotocol/graph-ts'
import { TokenRegistered } from '../types/DTFactory/DTFactory'
import { OceanDatatokens, Datatoken } from '../types/schema'
import { Datatoken as DatatokenContract } from '../types/templates'
import {
ZERO_BD,
} from './helpers'
import { log } from '@graphprotocol/graph-ts'
export function handleNewToken(event: TokenRegistered): void {
let factory = OceanDatatokens.load('1')
// if no factory yet, set up blank initial
if (factory == null) {
factory = new OceanDatatokens('1')
factory.tokenCount = 0
factory.txCount = BigInt.fromI32(0)
}
let datatoken = new Datatoken(event.params.tokenAddress.toHexString())
log.error('************************ handleNewToken: datatokenId {}', [datatoken.id.toString()])
datatoken.minter = event.params.registeredBy
datatoken.publisher = event.params.registeredBy
datatoken.supply = ZERO_BD
datatoken.createTime = event.block.timestamp.toI32()
datatoken.holdersCount = BigInt.fromI32(0)
datatoken.factoryID = event.address.toHexString()
datatoken.tx = event.transaction.hash
datatoken.save()
factory.tokenCount = factory.tokenCount + 1
factory.save()
DatatokenContract.create(event.params.tokenAddress)
}

View File

@ -13,7 +13,7 @@ import {
PoolShare,
TokenPrice,
Transaction,
OceanPools
OceanPools, Datatoken, TokenBalance
} from '../types/schema'
import { BToken } from '../types/templates/Pool/BToken'
import { log } from '@graphprotocol/graph-ts'
@ -55,51 +55,12 @@ export function createPoolShareEntity(id: string, pool: string, user: string): v
}
export function createPoolTokenEntity(id: string, pool: string, address: string): void {
let token = BToken.bind(Address.fromString(address))
let symbol = ''
let name = ''
let decimals = 18
// COMMENT THE LINES BELOW OUT FOR LOCAL DEV ON KOVAN
let symbolCall = token.try_symbol()
let nameCall = token.try_name()
if (!symbolCall.reverted) {
symbol = symbolCall.value
}
if (!nameCall.reverted) {
name = nameCall.value
}
// COMMENT THE LINES ABOVE OUT FOR LOCAL DEV ON KOVAN
// !!! COMMENT THE LINES BELOW OUT FOR NON-LOCAL DEPLOYMENT
// This code allows Symbols to be added when testing on local Kovan
/*
if(address == '0xd0a1e359811322d97991e03f863a0c30c2cf029c')
symbol = 'WETH';
else if(address == '0x1528f3fcc26d13f7079325fb78d9442607781c8c')
symbol = 'DAI'
else if(address == '0xef13c0c8abcaf5767160018d268f9697ae4f5375')
symbol = 'MKR'
else if(address == '0x2f375e94fc336cdec2dc0ccb5277fe59cbf1cae5')
symbol = 'USDC'
else if(address == '0x1f1f156e0317167c11aa412e3d1435ea29dc3cce')
symbol = 'BAT'
else if(address == '0x86436bce20258a6dcfe48c9512d4d49a30c4d8c4')
symbol = 'SNX'
else if(address == '0x8c9e6c40d3402480ace624730524facc5482798c')
symbol = 'REP'
*/
// !!! COMMENT THE LINES ABOVE OUT FOR NON-LOCAL DEPLOYMENT
let datatoken = Datatoken.load(address)
let poolToken = new PoolToken(id)
poolToken.poolId = pool
poolToken.tokenId = datatoken ? datatoken.id: null
poolToken.address = address
poolToken.name = name
poolToken.symbol = symbol
poolToken.decimals = decimals
poolToken.balance = ZERO_BD
poolToken.denormWeight = ZERO_BD
poolToken.save()
@ -110,30 +71,27 @@ export function updatePoolLiquidity(id: string): void {
let tokensList: Array<Bytes> = pool.tokensList
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 poolLiquidity = ZERO_BD
let poolOcnLiquidity = ZERO_BD
let poolDTLiquidity = ZERO_BD
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 = wethTokenPrice.price.times(poolToken.balance).div(poolToken.denormWeight).times(pool.totalWeight)
hasPrice = true
}
// if (tokensList.includes(Address.fromString(OCEAN))) {
// let oceanPoolTokenId = id.concat('-').concat(OCEAN)
// let oceanPoolToken = PoolToken.load(oceanPoolTokenId)
// poolLiquidity = oceanPoolToken.balance.div(oceanPoolToken.denormWeight).times(pool.totalWeight)
// hasPrice = true
// hasOceanPrice = true
// } else {
// let DT = tokensList[1].toHexString()
// let dtTokenPrice = TokenPrice.load(DT)
// if (dtTokenPrice !== null) {
// let poolTokenId = id.concat('-').concat(DT)
// let poolToken = PoolToken.load(poolTokenId)
// poolLiquidity = wethTokenPrice.price.times(poolToken.balance).div(poolToken.denormWeight).times(pool.totalWeight)
// hasPrice = true
// }
// }
//
// // Create or update token price
//
// if (hasPrice) {
@ -228,3 +186,18 @@ export function createUserEntity(address: string): void {
user.save()
}
}
export function createTokenBalanceEntity(id: string, token: string, user: string): void {
if (TokenBalance.load(id) != null) return
let tokenBalance = new TokenBalance(id)
createUserEntity(user)
tokenBalance.userAddress = user
tokenBalance.datatokenId = token
tokenBalance.balance = ZERO_BD
tokenBalance.save()
}
export function updateDatatokenBalance(): void {
}

View File

@ -1,6 +1,6 @@
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 { 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'
@ -10,7 +10,7 @@ import {
PoolToken,
PoolShare,
Swap,
TokenPrice
TokenPrice, Datatoken
} from '../types/schema'
import {
hexToDecimal,
@ -136,7 +136,9 @@ export function _handleRebind(event: LOG_CALL, poolId: string, tokenAddress: str
}
}
let balance = hexToDecimal(balanceStr, poolToken.decimals)
let datatoken = poolToken.tokenId != null ? Datatoken.load(poolToken.tokenId) : null
let decimals = datatoken == null ? BigInt.fromI32(18).toI32() : datatoken.decimals
let balance = hexToDecimal(balanceStr, decimals)
poolToken.balance = balance
poolToken.denormWeight = denormWeight
@ -182,8 +184,9 @@ export function handleJoinPool(event: LOG_JOIN): void {
if (!poolToken) {
return
}
poolToken.decimals = BigInt.fromI32(18).toI32()
let tokenAmountIn = tokenToDecimal(event.params.tokenAmountIn.toBigDecimal(), poolToken.decimals)
let datatoken = poolToken.tokenId != null ? Datatoken.load(poolToken.tokenId) : null
let decimals = datatoken == null ? BigInt.fromI32(18).toI32() : datatoken.decimals
let tokenAmountIn = tokenToDecimal(event.params.tokenAmountIn.toBigDecimal(), decimals)
poolToken.balance = poolToken.balance.plus(tokenAmountIn)
poolToken.save()
@ -200,7 +203,9 @@ export function handleExitPool(event: LOG_EXIT): void {
if (!poolToken) {
return
}
let tokenAmountOut = tokenToDecimal(event.params.tokenAmountOut.toBigDecimal(), poolToken.decimals)
let datatoken = poolToken.tokenId != null ? Datatoken.load(poolToken.tokenId) : null
let decimals = datatoken == null ? BigInt.fromI32(18).toI32() : datatoken.decimals
let tokenAmountOut = tokenToDecimal(event.params.tokenAmountOut.toBigDecimal(), decimals)
let newAmount = poolToken.balance.minus(tokenAmountOut)
poolToken.balance = newAmount
poolToken.save()

View File

@ -24,6 +24,26 @@ dataSources:
eventHandlers:
- event: BPoolRegistered(address,indexed address)
handler: handleNewPool
- kind: ethereum/contract
name: DTFactory
network: mainnet
source:
address: "0x57317f97E9EA49eBd19f7c9bB7c180b8cDcbDeB9"
abi: DTFactory
startBlock: 11105560
mapping:
kind: ethereum/events
apiVersion: 0.0.4
language: wasm/assemblyscript
file: ./src/mappings/dtfactory.ts
entities:
- OceanDatatokens
abis:
- name: DTFactory
file: ./abis/DTFactory.json
eventHandlers:
- event: TokenRegistered(indexed address,string,string,uint256,indexed address,indexed string)
handler: handleNewToken
templates:
- kind: ethereum/contract
name: Pool
@ -74,3 +94,25 @@ templates:
handler: handleSwap
- event: Transfer(indexed address,indexed address,uint256)
handler: handleTransfer
- kind: ethereum/contract
name: Datatoken
network: mainnet
source:
abi: Datatoken
mapping:
kind: ethereum/events
apiVersion: 0.0.4
language: wasm/assemblyscript
file: ./src/mappings/datatoken.ts
entities:
- Datatoken
- OceanDatatokens
abis:
- name: Datatoken
file: ./abis/DataTokenTemplate.json
eventHandlers:
- event: Transfer(indexed address,indexed address,uint256)
handler: handleTransfer
- event: OrderStarted(indexed address,indexed address,uint256,uint256,uint256,indexed address,uint256)
handler: handleOrderStarted