mirror of
https://github.com/oceanprotocol/ocean-subgraph.git
synced 2024-12-02 05:57:29 +01:00
e25ab73f55
* add EnergyWeb, Moonriver & Celo Alfajores * fix ocean address * add ERC20 abis
620 lines
18 KiB
TypeScript
620 lines
18 KiB
TypeScript
import {
|
|
BigDecimal,
|
|
BigInt,
|
|
Bytes,
|
|
dataSource,
|
|
Address,
|
|
ethereum,
|
|
log
|
|
} from '@graphprotocol/graph-ts'
|
|
|
|
import {
|
|
Pool as PoolEntity,
|
|
User,
|
|
PoolToken,
|
|
PoolShare,
|
|
PoolTransaction,
|
|
PoolFactory,
|
|
Datatoken,
|
|
TokenBalance,
|
|
TokenTransaction,
|
|
PoolTransactionTokenValues,
|
|
Global
|
|
} from './@types/schema'
|
|
|
|
import { Pool } from './@types/templates/Pool/Pool'
|
|
import { ERC20 } from './@types/templates/Pool/ERC20'
|
|
import { ERC20SymbolBytes } from './@types/templates/Pool/ERC20SymbolBytes'
|
|
import { ERC20NameBytes } from './@types/templates/Pool/ERC20NameBytes'
|
|
|
|
export const ZERO_BD = BigDecimal.fromString('0.0')
|
|
export const MINUS_1_BD = BigDecimal.fromString('-1.0')
|
|
export const ONE_BD = BigDecimal.fromString('1.0')
|
|
|
|
export const ONE_BASE_18 = BigInt.fromI32(10).pow(18 as u8)
|
|
export const BONE = BigDecimal.fromString('1000000000000000000')
|
|
|
|
export const ENABLE_DEBUG = true
|
|
|
|
const network = dataSource.network()
|
|
|
|
export function getOceanAddress(): string {
|
|
// switch is not working for some reason
|
|
if (network == 'ropsten') return '0x5e8dcb2afa23844bcc311b00ad1a0c30025aade9'
|
|
if (network == 'rinkeby') return '0x8967bcf84170c91b0d24d4302c2376283b0b3a07'
|
|
if (network == 'polygon') return '0x282d8efce846a88b159800bd4130ad77443fa1a1'
|
|
if (network == 'moonbeamalpha')
|
|
return '0xf6410bf5d773c7a41ebff972f38e7463fa242477'
|
|
if (network == 'gaiaxtestnet')
|
|
return '0x80e63f73cac60c1662f27d2dfd2ea834acddbaa8'
|
|
if (network == 'catenaxtestnet')
|
|
return '0x80e63f73cac60c1662f27d2dfd2ea834acddbaa8'
|
|
if (network == 'mumbai') return '0xd8992ed72c445c35cb4a2be468568ed1079357c8'
|
|
if (network == 'bsc') return '0xdce07662ca8ebc241316a15b611c89711414dd1a'
|
|
if (network == 'celoalfajores')
|
|
return '0xd8992ed72c445c35cb4a2be468568ed1079357c8'
|
|
if (network == 'energyweb')
|
|
return '0x593122aae80a6fc3183b2ac0c4ab3336debee528'
|
|
if (network == 'moonriver')
|
|
return '0x99c409e5f62e4bd2ac142f17cafb6810b8f0baae'
|
|
return '0x967da4048cd07ab37855c090aaf366e4ce1b9f48'
|
|
}
|
|
|
|
export const OCEAN: string = getOceanAddress()
|
|
|
|
export function getGlobalStats(): Global | null {
|
|
let gStats: Global | null = Global.load('1')
|
|
if (gStats == null) {
|
|
gStats = new Global('1')
|
|
gStats.totalOceanLiquidity = ZERO_BD
|
|
gStats.totalSwapVolume = ZERO_BD
|
|
gStats.totalValueLocked = ZERO_BD
|
|
gStats.totalOrderVolume = ZERO_BD
|
|
gStats.orderCount = BigInt.fromI32(0)
|
|
gStats.poolCount = 0
|
|
}
|
|
|
|
return gStats
|
|
}
|
|
|
|
export function _debuglog(
|
|
message: string,
|
|
event: ethereum.Event,
|
|
args: Array<string>
|
|
): void {
|
|
if (event != null) {
|
|
args.push(event.transaction.hash.toHex())
|
|
args.push(event.address.toHex())
|
|
}
|
|
for (let i = 0; i < args.length; i++) {
|
|
message = message.concat(' {}')
|
|
}
|
|
log.debug('@@@@@@ ' + message, args)
|
|
}
|
|
|
|
export function debuglog(
|
|
message: string,
|
|
event: ethereum.Event,
|
|
args: Array<string>
|
|
): void {
|
|
if (!ENABLE_DEBUG) return
|
|
_debuglog(message, event, args)
|
|
}
|
|
|
|
export function hexToDecimal(hexString: string, decimals: i32): BigDecimal {
|
|
const bytes = Bytes.fromHexString(hexString.toString()).reverse() as Bytes
|
|
const bi = BigInt.fromUnsignedBytes(bytes)
|
|
const scale = BigInt.fromI32(10)
|
|
.pow(decimals as u8)
|
|
.toBigDecimal()
|
|
return bi.divDecimal(scale)
|
|
}
|
|
|
|
export function bigIntToDecimal(amount: BigInt, decimals: i32): BigDecimal {
|
|
const scale = BigInt.fromI32(10)
|
|
.pow(decimals as u8)
|
|
.toBigDecimal()
|
|
return amount.toBigDecimal().div(scale)
|
|
}
|
|
|
|
export function tokenToDecimal(amount: BigDecimal, decimals: i32): BigDecimal {
|
|
const scale = BigInt.fromI32(10)
|
|
.pow(decimals as u8)
|
|
.toBigDecimal()
|
|
return amount.div(scale)
|
|
}
|
|
|
|
export function decimalToBigInt(value: BigDecimal): BigInt {
|
|
value.truncate(18)
|
|
const scale = BigInt.fromI32(10).pow((value.exp.toI32() + 18) as u8)
|
|
return value.digits.times(scale)
|
|
}
|
|
|
|
export function isNullEthValue(value: string): boolean {
|
|
return (
|
|
value ==
|
|
'0x0000000000000000000000000000000000000000000000000000000000000001'
|
|
)
|
|
}
|
|
|
|
export function getTokenSymbol(tokenAddress: Address): string {
|
|
const contract = ERC20.bind(tokenAddress)
|
|
const contractSymbolBytes = ERC20SymbolBytes.bind(tokenAddress)
|
|
|
|
// try types string and bytes32 for symbol
|
|
let symbolValue = 'unknown'
|
|
const symbolResult = contract.try_symbol()
|
|
if (symbolResult.reverted) {
|
|
const symbolResultBytes = contractSymbolBytes.try_symbol()
|
|
if (!symbolResultBytes.reverted) {
|
|
// for broken pairs that have no symbol function exposed
|
|
if (!isNullEthValue(symbolResultBytes.value.toHexString())) {
|
|
symbolValue = symbolResultBytes.value.toString()
|
|
}
|
|
}
|
|
} else {
|
|
symbolValue = symbolResult.value
|
|
}
|
|
|
|
return symbolValue
|
|
}
|
|
|
|
export function getTokenName(tokenAddress: Address): string {
|
|
const contract = ERC20.bind(tokenAddress)
|
|
const contractNameBytes = ERC20NameBytes.bind(tokenAddress)
|
|
|
|
// try types string and bytes32 for name
|
|
let nameValue = 'unknown'
|
|
const nameResult = contract.try_name()
|
|
if (nameResult.reverted) {
|
|
const nameResultBytes = contractNameBytes.try_name()
|
|
if (!nameResultBytes.reverted) {
|
|
// for broken exchanges that have no name function exposed
|
|
if (!isNullEthValue(nameResultBytes.value.toHexString())) {
|
|
nameValue = nameResultBytes.value.toString()
|
|
}
|
|
}
|
|
} else {
|
|
nameValue = nameResult.value
|
|
}
|
|
|
|
return nameValue
|
|
}
|
|
|
|
export function getTokenDecimals(tokenAddress: Address): i32 {
|
|
const contract = ERC20.bind(tokenAddress)
|
|
let decimals = 18
|
|
const decimalCall = contract.try_decimals()
|
|
if (!decimalCall.reverted) {
|
|
decimals = decimalCall.value
|
|
}
|
|
return decimals
|
|
}
|
|
|
|
export function updatePoolTokenBalance(
|
|
poolToken: PoolToken,
|
|
balance: BigDecimal,
|
|
source: string
|
|
): void {
|
|
debuglog(
|
|
'########## updating poolToken balance (source, oldBalance, newBalance, poolId) ',
|
|
null,
|
|
[source, poolToken.balance.toString(), balance.toString(), poolToken.poolId]
|
|
)
|
|
if (balance < ZERO_BD || poolToken.balance < ZERO_BD) {
|
|
log.warning(
|
|
'EEEEEEEEEEEEEEEEE poolToken.balance < Zero: pool={}, poolToken={}, oldBalance={}, newBalance={}',
|
|
[
|
|
poolToken.poolId,
|
|
poolToken.address.toString(),
|
|
poolToken.balance.toString(),
|
|
balance.toString()
|
|
]
|
|
)
|
|
}
|
|
|
|
poolToken.balance = balance
|
|
}
|
|
|
|
export function updatePoolSwapVolume(
|
|
pool: Pool,
|
|
swapAmount: BigDecimal
|
|
// source: string
|
|
): void {
|
|
debuglog(
|
|
'########## updating poolToken balance (source, oldBalance, newBalance, poolId) ',
|
|
null,
|
|
[source, pool.totalSwapVolume.toString(), swapAmount.toString(), pool.id]
|
|
)
|
|
if (swapAmount < ZERO_BD || pool.totalSwapVolume < ZERO_BD) {
|
|
log.warning(
|
|
'EEEEEEEEEEEEEEEEE poolToken.balance < Zero: pool={}, poolToken={}, oldBalance={}, newBalance={}',
|
|
[
|
|
pool.id,
|
|
poolToken.tokenAddress.toString(),
|
|
poolToken.balance.toString(),
|
|
swapAmount.toString()
|
|
]
|
|
)
|
|
}
|
|
|
|
poolToken.swapBalanceOcean = poolToken.swapBalanceOcean.plus(swapAmount)
|
|
}
|
|
export function createUserEntity(address: string): void {
|
|
if (User.load(address) == null) {
|
|
const user = new User(address)
|
|
user.nrSales = 0
|
|
user.save()
|
|
}
|
|
}
|
|
|
|
export function createPoolShareEntity(
|
|
id: string,
|
|
pool: string,
|
|
user: string
|
|
): void {
|
|
const poolShare = new PoolShare(id)
|
|
|
|
createUserEntity(user)
|
|
|
|
poolShare.userAddress = user
|
|
poolShare.poolId = pool
|
|
poolShare.balance = ZERO_BD
|
|
poolShare.save()
|
|
}
|
|
|
|
export function createPoolTokenEntity(
|
|
id: string,
|
|
pool: string,
|
|
address: Address
|
|
): void {
|
|
const datatoken = Datatoken.load(address.toHexString())
|
|
|
|
const poolToken = new PoolToken(id)
|
|
poolToken.poolId = pool
|
|
poolToken.isDatatoken = !!datatoken
|
|
poolToken.tokenId = datatoken ? datatoken.id : ''
|
|
poolToken.address = address.toHexString()
|
|
poolToken.balance = ZERO_BD
|
|
poolToken.denormWeight = ZERO_BD
|
|
poolToken.symbol = getTokenSymbol(address)
|
|
poolToken.name = getTokenName(address)
|
|
poolToken.decimals = getTokenDecimals(address)
|
|
poolToken.save()
|
|
}
|
|
|
|
export function updatePoolTransactionToken(
|
|
poolTx: string,
|
|
poolTokenId: string,
|
|
amount: BigDecimal,
|
|
balance: BigDecimal,
|
|
feeValue: BigDecimal
|
|
): void {
|
|
log.warning('WWWWWWWWWW ---- started update ptx with id {}', [poolTx])
|
|
log.warning('updatePoolTransactionToken({}, {} , {} , {} , {}}', [
|
|
poolTx,
|
|
poolTokenId,
|
|
amount.toString(),
|
|
balance.toString(),
|
|
feeValue.toString()
|
|
])
|
|
const ptx = PoolTransaction.load(poolTx)
|
|
const poolToken = PoolToken.load(poolTokenId)
|
|
const pool = PoolEntity.load(poolToken.poolId)
|
|
if (!ptx) {
|
|
log.error('Cannot load PoolTransaction {}', [poolTx])
|
|
return
|
|
}
|
|
if (!poolToken) {
|
|
log.error('Cannot load PoolToken {}', [poolTokenId])
|
|
return
|
|
}
|
|
if (!pool) {
|
|
log.error('Cannot load PoolEntity {}', [poolToken.poolId])
|
|
return
|
|
}
|
|
const ptxTokenValuesId = poolTx.concat('-').concat(poolTokenId)
|
|
let ptxTokenValues = PoolTransactionTokenValues.load(ptxTokenValuesId)
|
|
if (ptxTokenValues == null) {
|
|
ptxTokenValues = new PoolTransactionTokenValues(ptxTokenValuesId)
|
|
log.warning('created PoolTransactionTokenValues for {}', [ptxTokenValuesId])
|
|
}
|
|
|
|
ptxTokenValues.txId = poolTx
|
|
ptxTokenValues.poolToken = poolTokenId
|
|
ptxTokenValues.poolAddress = poolToken.poolId
|
|
ptxTokenValues.userAddress = ptx.userAddress
|
|
ptxTokenValues.tokenAddress = PoolToken.load(poolTokenId).address
|
|
|
|
ptxTokenValues.value = amount
|
|
ptxTokenValues.tokenReserve = balance
|
|
ptxTokenValues.feeValue = feeValue
|
|
if (amount.lt(ZERO_BD)) {
|
|
ptxTokenValues.type = 'out'
|
|
} else {
|
|
ptxTokenValues.type = 'in'
|
|
}
|
|
|
|
ptxTokenValues.save()
|
|
log.warning('ptxTokenValues {} saved {}', [
|
|
ptxTokenValues.id,
|
|
ptxTokenValues.type
|
|
])
|
|
if (ptxTokenValues.tokenAddress == OCEAN) {
|
|
const factory = PoolFactory.load('1')
|
|
|
|
factory.totalOceanLiquidity = factory.totalOceanLiquidity
|
|
.plus(ptxTokenValues.tokenReserve)
|
|
.minus(pool.oceanReserve)
|
|
|
|
const gStats: Global | null = getGlobalStats()
|
|
gStats.totalOceanLiquidity = factory.totalOceanLiquidity
|
|
|
|
gStats.save()
|
|
if (factory.totalOceanLiquidity < ZERO_BD || pool.oceanReserve < ZERO_BD) {
|
|
log.warning(
|
|
'EEEEEEEEEEEEEEEEE totalOceanLiquidity or oceanReserve < Zero: pool={}, totOcnLiq={}, ocnRes={}',
|
|
[
|
|
pool.id,
|
|
factory.totalOceanLiquidity.toString(),
|
|
pool.oceanReserve.toString()
|
|
]
|
|
)
|
|
}
|
|
ptx.oceanReserve = ptxTokenValues.tokenReserve
|
|
pool.oceanReserve = ptxTokenValues.tokenReserve
|
|
factory.save()
|
|
} else {
|
|
ptx.datatokenReserve = ptxTokenValues.tokenReserve
|
|
pool.datatokenReserve = ptxTokenValues.tokenReserve
|
|
}
|
|
// debuglog('########## updatePoolTransactionToken: ', null, [
|
|
// BigInt.fromI32(ptx.block).toString(),
|
|
// BigInt.fromI32(ptx.timestamp).toString(),
|
|
// ptxTokenValues.type,
|
|
// ptxTokenValues.value.toString(),
|
|
// ptxTokenValues.tokenReserve.toString(),
|
|
// poolToken.poolId
|
|
// ])
|
|
log.warning('saving ptx {} ', [ptx.id.toString()])
|
|
ptx.save()
|
|
log.warning('saving pool {} ', [pool.id.toString()])
|
|
pool.save()
|
|
}
|
|
|
|
export function calcSpotPrice(
|
|
balanceIn: BigDecimal,
|
|
wIn: BigDecimal,
|
|
balanceOut: BigDecimal,
|
|
wOut: BigDecimal,
|
|
swapFee: BigDecimal
|
|
): BigDecimal {
|
|
if (balanceIn <= ZERO_BD || balanceOut <= ZERO_BD) return MINUS_1_BD
|
|
debuglog('################ calcSpotPrice', null, [
|
|
balanceIn.toString(),
|
|
wIn.toString(),
|
|
balanceOut.toString(),
|
|
wOut.toString(),
|
|
swapFee.toString()
|
|
])
|
|
|
|
const numer = balanceIn.div(wIn)
|
|
const denom = balanceOut.div(wOut)
|
|
if (denom <= ZERO_BD) return MINUS_1_BD
|
|
|
|
const ratio = numer.div(denom)
|
|
const scale = ONE_BD.div(ONE_BD.minus(swapFee))
|
|
const price = ratio.times(scale)
|
|
price.truncate(18)
|
|
debuglog('################ calcSpotPrice values:', null, [
|
|
numer.toString(),
|
|
denom.toString(),
|
|
ratio.toString(),
|
|
scale.toString(),
|
|
price.toString()
|
|
])
|
|
return price
|
|
}
|
|
|
|
export function createPoolTransaction(
|
|
event: ethereum.Event,
|
|
// eslint-disable-next-line camelcase
|
|
event_type: string,
|
|
userAddress: string
|
|
): void {
|
|
const poolId = event.address.toHex()
|
|
const pool = PoolEntity.load(poolId)
|
|
const ptx = event.transaction.hash.toHexString()
|
|
|
|
const ocnToken = PoolToken.load(poolId.concat('-').concat(OCEAN))
|
|
const dtToken = PoolToken.load(
|
|
poolId.concat('-').concat(pool.datatokenAddress)
|
|
)
|
|
if (ocnToken == null || dtToken == null) {
|
|
return
|
|
}
|
|
|
|
let poolTx = PoolTransaction.load(ptx)
|
|
if (poolTx != null) {
|
|
return
|
|
}
|
|
poolTx = new PoolTransaction(ptx)
|
|
|
|
poolTx.poolAddress = poolId
|
|
poolTx.userAddress = userAddress
|
|
poolTx.poolAddressStr = poolId
|
|
poolTx.userAddressStr = userAddress
|
|
|
|
poolTx.sharesTransferAmount = ZERO_BD
|
|
poolTx.sharesBalance = ZERO_BD
|
|
|
|
// pool.datatokenReserve = dtToken.balance
|
|
// pool.oceanReserve = ocnToken.balance
|
|
// Initial reserve values, will be updated in `updatePoolTransactionToken`
|
|
poolTx.datatokenReserve = dtToken.balance
|
|
poolTx.oceanReserve = ocnToken.balance
|
|
debuglog('poolTX reserves:(dt, ocean)', null, [
|
|
poolTx.datatokenReserve.toString(),
|
|
poolTx.oceanReserve.toString()
|
|
])
|
|
|
|
const p = Pool.bind(Address.fromString(poolId))
|
|
debuglog(
|
|
'createPoolTransaction args sent to calcInGivenOut (ocnBalance, ocnWeight, dtBalance, dtWeight, dtAmount, swapFee)',
|
|
null,
|
|
[
|
|
decimalToBigInt(ocnToken.balance).toString(),
|
|
decimalToBigInt(ocnToken.denormWeight).toString(),
|
|
decimalToBigInt(dtToken.balance).toString(),
|
|
decimalToBigInt(dtToken.denormWeight).toString(),
|
|
ONE_BASE_18.toString(),
|
|
decimalToBigInt(pool.swapFee).toString()
|
|
]
|
|
)
|
|
const priceResult = p.try_calcInGivenOut(
|
|
decimalToBigInt(ocnToken.balance),
|
|
decimalToBigInt(ocnToken.denormWeight),
|
|
decimalToBigInt(dtToken.balance),
|
|
decimalToBigInt(dtToken.denormWeight),
|
|
ONE_BASE_18,
|
|
decimalToBigInt(pool.swapFee)
|
|
)
|
|
debuglog('got results', null, [])
|
|
poolTx.consumePrice = priceResult.reverted
|
|
? MINUS_1_BD
|
|
: bigIntToDecimal(priceResult.value, 18)
|
|
debuglog('calcInGivenOut:', null, [
|
|
priceResult.reverted ? 'failed' : priceResult.value.toString()
|
|
])
|
|
|
|
const priceSpot = p.try_calcSpotPrice(
|
|
decimalToBigInt(ocnToken.balance),
|
|
decimalToBigInt(ocnToken.denormWeight),
|
|
decimalToBigInt(dtToken.balance),
|
|
decimalToBigInt(dtToken.denormWeight),
|
|
decimalToBigInt(pool.swapFee)
|
|
)
|
|
poolTx.spotPrice = priceSpot.reverted
|
|
? ZERO_BD
|
|
: bigIntToDecimal(priceSpot.value, 18)
|
|
debuglog('SpotPrice:', null, [
|
|
priceSpot.reverted ? 'failed' : priceSpot.value.toString()
|
|
])
|
|
|
|
pool.consumePrice = poolTx.consumePrice
|
|
pool.spotPrice = poolTx.spotPrice
|
|
const oldValueLocked = pool.valueLocked
|
|
const spotPrice = pool.spotPrice >= ZERO_BD ? pool.spotPrice : ZERO_BD
|
|
pool.valueLocked = poolTx.oceanReserve.plus(
|
|
poolTx.datatokenReserve.times(spotPrice)
|
|
)
|
|
const factory = PoolFactory.load('1')
|
|
if (oldValueLocked < ZERO_BD || pool.valueLocked < ZERO_BD) {
|
|
log.warning(
|
|
'EEEEEEEEEEEEEEEEE valueLocked < Zero: pool={}, oldVL={}, newVL={}, OCEAN={}, DT={}, spotPrice={}',
|
|
[
|
|
pool.id,
|
|
oldValueLocked.toString(),
|
|
pool.valueLocked.toString(),
|
|
poolTx.oceanReserve.toString(),
|
|
poolTx.datatokenReserve.toString(),
|
|
pool.spotPrice.toString()
|
|
]
|
|
)
|
|
}
|
|
factory.totalValueLocked = factory.totalValueLocked
|
|
.minus(oldValueLocked)
|
|
.plus(pool.valueLocked)
|
|
|
|
const gStats: Global | null = getGlobalStats()
|
|
|
|
gStats.totalValueLocked = factory.totalValueLocked
|
|
gStats.save()
|
|
|
|
pool.transactionCount = pool.transactionCount.plus(BigInt.fromI32(1))
|
|
|
|
pool.save()
|
|
factory.save()
|
|
|
|
debuglog(
|
|
'updated pool reserves (source, dtBalance, ocnBalance, dtReserve, ocnReserve): ',
|
|
event,
|
|
[
|
|
'createPoolTransaction',
|
|
dtToken.balance.toString(),
|
|
ocnToken.balance.toString(),
|
|
pool.datatokenReserve.toString(),
|
|
pool.oceanReserve.toString()
|
|
]
|
|
)
|
|
|
|
poolTx.tx = event.transaction.hash
|
|
// eslint-disable-next-line camelcase
|
|
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()
|
|
|
|
debuglog('####################### poolTransaction: ', event, [
|
|
ptx,
|
|
BigInt.fromI32(poolTx.block).toString(),
|
|
BigInt.fromI32(poolTx.timestamp).toString(),
|
|
pool.oceanReserve.toString()
|
|
])
|
|
|
|
poolTx.save()
|
|
}
|
|
|
|
export function decrPoolCount(finalized: boolean): void {
|
|
const factory = PoolFactory.load('1')
|
|
factory.poolCount -= 1
|
|
if (finalized) factory.finalizedPoolCount -= 1
|
|
factory.save()
|
|
}
|
|
|
|
export function saveTokenTransaction(
|
|
event: ethereum.Event,
|
|
eventName: string
|
|
): void {
|
|
const tx = event.transaction.hash
|
|
.toHexString()
|
|
.concat('-')
|
|
.concat(event.logIndex.toString())
|
|
const userAddress = event.transaction.from.toHex()
|
|
let transaction = TokenTransaction.load(tx)
|
|
if (transaction == null) {
|
|
transaction = new TokenTransaction(tx)
|
|
}
|
|
transaction.event = eventName
|
|
transaction.datatokenAddress = 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 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()
|
|
}
|