mirror of
https://github.com/oceanprotocol/ocean-subgraph.git
synced 2024-12-02 05:57:29 +01:00
add datatoken mapping and handlers
This commit is contained in:
parent
49461245d4
commit
316dbeb9ad
4577
abis/DTFactory.json
Normal file
4577
abis/DTFactory.json
Normal file
File diff suppressed because one or more lines are too long
14594
abis/DataTokenTemplate.json
Normal file
14594
abis/DataTokenTemplate.json
Normal file
File diff suppressed because one or more lines are too long
@ -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
99
src/mappings/datatoken.ts
Normal 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
35
src/mappings/dtfactory.ts
Normal 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)
|
||||
}
|
@ -7,13 +7,13 @@ import {
|
||||
ethereum
|
||||
} from '@graphprotocol/graph-ts'
|
||||
import {
|
||||
Pool,
|
||||
User,
|
||||
PoolToken,
|
||||
PoolShare,
|
||||
TokenPrice,
|
||||
Transaction,
|
||||
OceanPools
|
||||
Pool,
|
||||
User,
|
||||
PoolToken,
|
||||
PoolShare,
|
||||
TokenPrice,
|
||||
Transaction,
|
||||
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 {
|
||||
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
|
||||
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'
|
||||
|
||||
import {
|
||||
OceanPools,
|
||||
Pool,
|
||||
PoolToken,
|
||||
PoolShare,
|
||||
Swap,
|
||||
TokenPrice
|
||||
OceanPools,
|
||||
Pool,
|
||||
PoolToken,
|
||||
PoolShare,
|
||||
Swap,
|
||||
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()
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user