Skip to content

Commit

Permalink
Merge pull request #200 from Data-Nexus/bsc
Browse files Browse the repository at this point in the history
BSC - Decimal Fix & Graph-ts Upgade
  • Loading branch information
ianlapham authored Feb 26, 2024
2 parents 595b512 + d4054b0 commit b31edef
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 113 deletions.
2 changes: 1 addition & 1 deletion abis/ERC20.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"outputs": [
{
"name": "",
"type": "uint8"
"type": "uint32"
}
],
"payable": false,
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"watch-local": "graph deploy ianlapham/uniswap-v3-bsc --watch --debug --node http://127.0.0.1:8020/ --ipfs http://localhost:5001"
},
"devDependencies": {
"@graphprotocol/graph-cli": "^0.20.0",
"@graphprotocol/graph-ts": "^0.20.0",
"@graphprotocol/graph-cli": "^0.64.1",
"@graphprotocol/graph-ts": "^0.32.0",
"@typescript-eslint/eslint-plugin": "^2.0.0",
"@typescript-eslint/parser": "^2.0.0",
"eslint": "^6.2.2",
Expand Down
88 changes: 43 additions & 45 deletions src/mappings/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,19 @@ import { createTick, feeTierToTickSpacing } from '../utils/tick'
export function handleInitialize(event: Initialize): void {
// update pool sqrt price and tick
let pool = Pool.load(event.address.toHexString())
if (!pool) return
if (!pool) return

pool.sqrtPrice = event.params.sqrtPriceX96
pool.tick = BigInt.fromI32(event.params.tick)
pool.save()

// update token prices
let token0 = Token.load(pool.token0)
let token1 = Token.load(pool.token1)


// update ETH price now that prices could have changed
let bundle = Bundle.load('1')
if (!token0 || !token1 || !bundle) return
if (!token0 || !token1 || !bundle) return

bundle.ethPriceUSD = getEthPriceInUSD()
bundle.save()
Expand All @@ -53,7 +52,6 @@ export function handleInitialize(event: Initialize): void {
token1.save()
}


function updateTickFeeVarsAndSave(tick: Tick, event: ethereum.Event): void {
let poolAddress = event.address
// not all ticks are initialized so obtaining null is expected behavior
Expand All @@ -66,7 +64,6 @@ function updateTickFeeVarsAndSave(tick: Tick, event: ethereum.Event): void {
updateTickDayData(tick, event)
}


export function handleMint(event: MintEvent): void {
let bundle = Bundle.load('1')
let poolAddress = event.address.toHexString()
Expand All @@ -76,7 +73,7 @@ export function handleMint(event: MintEvent): void {

let token0 = Token.load(pool.token0)
let token1 = Token.load(pool.token1)
if (!token0 || !token1) return
if (!token0 || !token1) return

let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)
Expand Down Expand Up @@ -185,8 +182,8 @@ export function handleMint(event: MintEvent): void {
mint.save()

// Update inner tick vars and save the ticks
updateTickFeeVarsAndSave(lowerTick!, event)
updateTickFeeVarsAndSave(upperTick!, event)
updateTickFeeVarsAndSave(lowerTick, event)
updateTickFeeVarsAndSave(upperTick, event)
}

export function handleBurn(event: BurnEvent): void {
Expand All @@ -199,7 +196,7 @@ export function handleBurn(event: BurnEvent): void {
let token0 = Token.load(pool.token0)
let token1 = Token.load(pool.token1)

if (!token0 || !token1) return
if (!token0 || !token1) return

let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)
Expand Down Expand Up @@ -270,7 +267,7 @@ export function handleBurn(event: BurnEvent): void {
let upperTickId = poolAddress + '#' + BigInt.fromI32(event.params.tickUpper).toString()
let lowerTick = Tick.load(lowerTickId)
let upperTick = Tick.load(upperTickId)
if (!lowerTick || !upperTick) return
if (!lowerTick || !upperTick) return

let amount = event.params.amount
lowerTick.liquidityGross = lowerTick.liquidityGross.minus(amount)
Expand All @@ -285,8 +282,8 @@ export function handleBurn(event: BurnEvent): void {
updateTokenDayData(token1 as Token, event)
updateTokenHourData(token0 as Token, event)
updateTokenHourData(token1 as Token, event)
updateTickFeeVarsAndSave(lowerTick!, event)
updateTickFeeVarsAndSave(upperTick!, event)
updateTickFeeVarsAndSave(lowerTick, event)
updateTickFeeVarsAndSave(upperTick, event)

token0.save()
token1.save()
Expand All @@ -304,16 +301,15 @@ function loadTickUpdateFeeVarsAndSave(tickId: i32, event: ethereum.Event): void
.concat(tickId.toString())
)
if (tick !== null) {
updateTickFeeVarsAndSave(tick!, event)
updateTickFeeVarsAndSave(tick, event)
}
}


export function handleSwap(event: SwapEvent): void {
let bundle = Bundle.load('1')
let factory = Factory.load(FACTORY_ADDRESS)
let pool = Pool.load(event.address.toHexString())
if (!factory || !pool || !bundle) return
if (!factory || !pool || !bundle) return

// hot fix for bad pricing
if (pool.id == '0x9663f2ca0454accad3e094448ea6f77443880454') {
Expand All @@ -322,7 +318,7 @@ export function handleSwap(event: SwapEvent): void {

let token0 = Token.load(pool.token0)
let token1 = Token.load(pool.token1)
if (!token0 || !token1) return
if (!token0 || !token1) return

let oldTick = pool.tick

Expand Down Expand Up @@ -509,42 +505,44 @@ export function handleSwap(event: SwapEvent): void {
// Update inner vars of current or crossed ticks
let newTick = pool.tick
let tickSpacing = feeTierToTickSpacing(pool.feeTier)
let modulo = newTick.mod(tickSpacing)
if (modulo.equals(ZERO_BI)) {
// Current tick is initialized and needs to be updated
loadTickUpdateFeeVarsAndSave(newTick.toI32(), event)
}

if (!oldTick) return

let numIters = oldTick
.minus(newTick!)
.abs()
.div(tickSpacing)

if (numIters.gt(BigInt.fromI32(100))) {
// In case more than 100 ticks need to be updated ignore the update in
// order to avoid timeouts. From testing this behavior occurs only upon
// pool initialization. This should not be a big issue as the ticks get
// updated later. For early users this error also disappears when calling
// collect
} else if (newTick.gt(oldTick!)) {
let firstInitialized = oldTick.plus(tickSpacing.minus(modulo))
for (let i = firstInitialized; i.le(newTick!); i = i.plus(tickSpacing)) {
loadTickUpdateFeeVarsAndSave(i.toI32(), event)
if (newTick) {
let modulo = newTick.mod(tickSpacing)
if (modulo.equals(ZERO_BI)) {
// Current tick is initialized and needs to be updated
loadTickUpdateFeeVarsAndSave(newTick.toI32(), event)
}
} else if (newTick.lt(oldTick!)) {
let firstInitialized = oldTick.minus(modulo)
for (let i = firstInitialized; i.ge(newTick!); i = i.minus(tickSpacing)) {
loadTickUpdateFeeVarsAndSave(i.toI32(), event)

if (oldTick) {
let numIters = oldTick
.minus(newTick)
.abs()
.div(tickSpacing)

if (numIters.gt(BigInt.fromI32(100))) {
// In case more than 100 ticks need to be updated ignore the update in
// order to avoid timeouts. From testing this behavior occurs only upon
// pool initialization. This should not be a big issue as the ticks get
// updated later. For early users this error also disappears when calling
// collect
} else if (newTick.gt(oldTick)) {
let firstInitialized = oldTick.plus(tickSpacing.minus(modulo))
for (let i = firstInitialized; i.le(newTick); i = i.plus(tickSpacing)) {
loadTickUpdateFeeVarsAndSave(i.toI32(), event)
}
} else if (newTick.lt(oldTick)) {
let firstInitialized = oldTick.minus(modulo)
for (let i = firstInitialized; i.ge(newTick); i = i.minus(tickSpacing)) {
loadTickUpdateFeeVarsAndSave(i.toI32(), event)
}
}
}
}
}

export function handleFlash(event: FlashEvent): void {
// update fee growth
let pool = Pool.load(event.address.toHexString())
if (!pool) return
if (!pool) return

let poolContract = PoolABI.bind(event.address)
let feeGrowthGlobal0X128 = poolContract.feeGrowthGlobal0X128()
Expand Down
44 changes: 27 additions & 17 deletions src/mappings/position-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,20 @@ export function handleIncreaseLiquidity(event: IncreaseLiquidity): void {
let token0 = Token.load(position.token0)
let token1 = Token.load(position.token1)

let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)
if (token0 && token1) {
let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)

position.liquidity = position.liquidity.plus(event.params.liquidity)
position.depositedToken0 = position.depositedToken0.plus(amount0)
position.depositedToken1 = position.depositedToken1.plus(amount1)
position.liquidity = position.liquidity.plus(event.params.liquidity)
position.depositedToken0 = position.depositedToken0.plus(amount0)
position.depositedToken1 = position.depositedToken1.plus(amount1)
}

updateFeeVars(position!, event, event.params.tokenId)
updateFeeVars(position, event, event.params.tokenId)

position.save()

savePositionSnapshot(position!, event)
savePositionSnapshot(position, event)
}

export function handleDecreaseLiquidity(event: DecreaseLiquidity): void {
Expand All @@ -134,16 +136,19 @@ export function handleDecreaseLiquidity(event: DecreaseLiquidity): void {

let token0 = Token.load(position.token0)
let token1 = Token.load(position.token1)
let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)

position.liquidity = position.liquidity.minus(event.params.liquidity)
position.withdrawnToken0 = position.withdrawnToken0.plus(amount0)
position.withdrawnToken1 = position.withdrawnToken1.plus(amount1)
if (token0 && token1) {
let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount1, token1.decimals)

position = updateFeeVars(position!, event, event.params.tokenId)
position.liquidity = position.liquidity.minus(event.params.liquidity)
position.withdrawnToken0 = position.withdrawnToken0.plus(amount0)
position.withdrawnToken1 = position.withdrawnToken1.plus(amount1)
}

position = updateFeeVars(position, event, event.params.tokenId)
position.save()
savePositionSnapshot(position!, event)
savePositionSnapshot(position, event)
}

export function handleCollect(event: Collect): void {
Expand All @@ -157,9 +162,14 @@ export function handleCollect(event: Collect): void {
}

let token0 = Token.load(position.token0)
let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
position.collectedFeesToken0 = position.collectedFeesToken0.plus(amount0)
position.collectedFeesToken1 = position.collectedFeesToken1.plus(amount0)
let token1 = Token.load(position.token1)

if (token0 && token1) {
let amount0 = convertTokenToDecimal(event.params.amount0, token0.decimals)
let amount1 = convertTokenToDecimal(event.params.amount0, token1.decimals)
position.collectedFeesToken0 = position.collectedFeesToken0.plus(amount0)
position.collectedFeesToken1 = position.collectedFeesToken1.plus(amount1)
}

position = updateFeeVars(position!, event, event.params.tokenId)
position.save()
Expand Down
2 changes: 1 addition & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function loadTransaction(event: ethereum.Event): Transaction {
}
transaction.blockNumber = event.block.number
transaction.timestamp = event.block.timestamp
transaction.gasUsed = event.transaction.gasUsed
transaction.gasUsed = BigInt.zero() //needs to be moved to transaction receipt
transaction.gasPrice = event.transaction.gasPrice
transaction.save()
return transaction as Transaction
Expand Down
10 changes: 5 additions & 5 deletions src/utils/intervalUpdates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { ethereum } from '@graphprotocol/graph-ts'
* @param event
*/
export function updateUniswapDayData(event: ethereum.Event): UniswapDayData {
let uniswap = Factory.load(FACTORY_ADDRESS)
let uniswap = Factory.load(FACTORY_ADDRESS)!
let timestamp = event.block.timestamp.toI32()
let dayID = timestamp / 86400 // rounded
let dayStartTimestamp = dayID * 86400
Expand All @@ -48,7 +48,7 @@ export function updatePoolDayData(event: ethereum.Event): PoolDayData {
.toHexString()
.concat('-')
.concat(dayID.toString())
let pool = Pool.load(event.address.toHexString())
let pool = Pool.load(event.address.toHexString())!
let poolDayData = PoolDayData.load(dayPoolID)
if (poolDayData === null) {
poolDayData = new PoolDayData(dayPoolID)
Expand Down Expand Up @@ -97,7 +97,7 @@ export function updatePoolHourData(event: ethereum.Event): PoolHourData {
.toHexString()
.concat('-')
.concat(hourIndex.toString())
let pool = Pool.load(event.address.toHexString())
let pool = Pool.load(event.address.toHexString())!
let poolHourData = PoolHourData.load(hourPoolID)
if (poolHourData === null) {
poolHourData = new PoolHourData(hourPoolID)
Expand Down Expand Up @@ -141,7 +141,7 @@ export function updatePoolHourData(event: ethereum.Event): PoolHourData {
}

export function updateTokenDayData(token: Token, event: ethereum.Event): TokenDayData {
let bundle = Bundle.load('1')
let bundle = Bundle.load('1')!
let timestamp = event.block.timestamp.toI32()
let dayID = timestamp / 86400
let dayStartTimestamp = dayID * 86400
Expand Down Expand Up @@ -184,7 +184,7 @@ export function updateTokenDayData(token: Token, event: ethereum.Event): TokenDa
}

export function updateTokenHourData(token: Token, event: ethereum.Event): TokenHourData {
let bundle = Bundle.load('1')
let bundle = Bundle.load('1')!
let timestamp = event.block.timestamp.toI32()
let hourIndex = timestamp / 3600 // get unique hour within unix history
let hourStartUnix = hourIndex * 3600 // want the rounded effect
Expand Down
18 changes: 8 additions & 10 deletions src/utils/pricing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,20 @@ import { BigDecimal, BigInt } from '@graphprotocol/graph-ts'
import { exponentToBigDecimal, safeDiv } from '../utils/index'

const WBNB_ADDRESS = '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c'
const USDC_WBNB_03_POOL = '0x6bcb0Ba386E9de0C29006e46B2f01f047cA1806E'
const USDC_WBNB_03_POOL = '0x6fe9e9de56356f7edbfcbb29fab7cd69471a4869'

// token where amounts should contribute to tracked volume and liquidity
// usually tokens that many tokens are paired with s
export let WHITELIST_TOKENS: string[] = [
WBNB_ADDRESS,
]
export let WHITELIST_TOKENS: string[] = [WBNB_ADDRESS]

let STABLE_COINS: string[] = [
'0x55d398326f99059ff775485246999027b3197955', // USDT
'0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', // USDC
'0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d' // USDC
]

let MINIMUM_ETH_LOCKED = BigDecimal.fromString('0')
let MINIMUM_ETH_LOCKED = BigDecimal.fromString('300')

let Q192 = 2 ** 192
let Q192 = BigInt.fromI32(2).pow(192 as u8)
export function sqrtPriceX96ToTokenPrices(sqrtPriceX96: BigInt, token0: Token, token1: Token): BigDecimal[] {
let num = sqrtPriceX96.times(sqrtPriceX96).toBigDecimal()
let denom = BigDecimal.fromString(Q192.toString())
Expand Down Expand Up @@ -74,15 +72,15 @@ export function findBnbPerToken(token: Token): BigDecimal {
if (!pool) {
return ZERO_BD
}

if (pool.liquidity.gt(ZERO_BI)) {
if (pool.token0 == token.id) {
// whitelist token is token1
let token1 = Token.load(pool.token1)
if (!token1) {
return ZERO_BD
}

// get the derived ETH in pool
let ethLocked = pool.totalValueLockedToken1.times(token1.derivedETH)
if (ethLocked.gt(largestLiquidityETH) && ethLocked.gt(MINIMUM_ETH_LOCKED)) {
Expand All @@ -96,7 +94,7 @@ export function findBnbPerToken(token: Token): BigDecimal {
if (!token0) {
return ZERO_BD
}

// get the derived ETH in pool
let ethLocked = pool.totalValueLockedToken0.times(token0.derivedETH)
if (ethLocked.gt(largestLiquidityETH) && ethLocked.gt(MINIMUM_ETH_LOCKED)) {
Expand Down
Loading

0 comments on commit b31edef

Please sign in to comment.