Skip to content

Commit

Permalink
sJOE Subgraph (traderjoe-xyz#24)
Browse files Browse the repository at this point in the history
* setup stablejoe subgraph, missing dayData atm

* update stableJoeDayData on events, track deposit fees collected

* make sure to create stable joe, also save users after making updates

* add joeUnstaked and joeUnstakedUSD for day data, fix some logic

* add USDC_ADDRESS

* update contract address, redeploy

* update abi

* cleanup user logic

* fix yaml file

* update joe-core and abi

* fix templates

* config lowercase

* set api version to 0.0.4

* Fix stablejoe day data errors

* run prettier

* use debug log instead of warning

* Use stablejoe contract address in day data identifiers

Co-authored-by: robotmurloc-3599 <[email protected]>
Co-authored-by: 0xmaxime <[email protected]>
  • Loading branch information
3 people authored Feb 24, 2022
1 parent 0732ec6 commit 8b1f332
Show file tree
Hide file tree
Showing 15 changed files with 390 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"devDependencies": {
"@graphprotocol/graph-cli": "^0.20.0",
"@graphprotocol/graph-ts": "^0.20.0",
"@traderjoe-xyz/core": "^2.0.0",
"@traderjoe-xyz/core": "^2.3.0",
"@typescript-eslint/eslint-plugin": "^4.0.0",
"@typescript-eslint/parser": "^4.0.0",
"eslint": "^7.0.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/constants/config/avax.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"weth_address": "0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab",
"wbtc_address": "0x50b7545627a5162f82a992c33b87adc75187b218",
"usdt_address": "0xc7198437980c041c805a1edcba50c1ce5db95118",
"usdc_address": "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664",
"usdc_e_address": "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664",
"usdc_address": "0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e",
"dai_address": "0xd586e7f844cea2f87f50152665bcbc2c279d8d70",
"time_address": "0xb54f16fb19478766a268f172c9480f8da1a7c9c3",
"apex_address": "0xd039c9079ca7f2a87d632a9c0d7cea0137bacfb5",
Expand Down
1 change: 1 addition & 0 deletions packages/constants/config/rinkeby.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"weth_address": "0xc778417e063141139fce010982780140aa0cd5ab",
"wbtc_address": "0x5b8470fbc6b31038aa07abd3010acffca6e36611",
"usdt_address": "0x5b8470fbc6b31038aa07abd3010acffca6e36611",
"usdc_e_address": "0x5b8470fbc6b31038aa07abd3010acffca6e36611",
"usdc_address": "0x5b8470fbc6b31038aa07abd3010acffca6e36611",
"dai_address": "0x5b8470fbc6b31038aa07abd3010acffca6e36611",
"time_address": "0xb54f16fb19478766a268f172c9480f8da1a7c9c3",
Expand Down
1 change: 1 addition & 0 deletions packages/constants/index.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const JOE_USDT_PAIR_ADDRESS = Address.fromString('{{ joe_usdt_pair_addres

export const WAVAX_ADDRESS = Address.fromString('{{ wavax_address }}')
export const USDT_ADDRESS = Address.fromString('{{ usdt_address }}')
export const USDC_E_ADDRESS = Address.fromString('{{ usdc_e_address }}')
export const USDC_ADDRESS = Address.fromString('{{ usdc_address }}')
export const WBTC_ADDRESS = Address.fromString('{{ wbtc_address }}')
export const TIME_ADDRESS = Address.fromString('{{ time_address }}')
Expand Down
3 changes: 2 additions & 1 deletion packages/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ export const JOE_USDT_PAIR_ADDRESS = Address.fromString('0x1643de2efb8e35374d796

export const WAVAX_ADDRESS = Address.fromString('0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7')
export const USDT_ADDRESS = Address.fromString('0xc7198437980c041c805a1edcba50c1ce5db95118')
export const USDC_ADDRESS = Address.fromString('0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664')
export const USDC_E_ADDRESS = Address.fromString('0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664')
export const USDC_ADDRESS = Address.fromString('0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e')
export const WBTC_ADDRESS = Address.fromString('0x50b7545627a5162f82a992c33b87adc75187b218')
export const TIME_ADDRESS = Address.fromString('0xb54f16fb19478766a268f172c9480f8da1a7c9c3')
export const APEX_ADDRESS = Address.fromString('0xd039c9079ca7f2a87d632a9c0d7cea0137bacfb5')
Expand Down
5 changes: 5 additions & 0 deletions subgraphs/stablejoe/config/rinkeby.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"network": "rinkeby",
"address": "0x12ba94d04a7a7f0882155b2c55b88e269428227b",
"startBlock": "10219081"
}
21 changes: 21 additions & 0 deletions subgraphs/stablejoe/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "StableJoeStaking",
"license": "UNLICENSED",
"scripts": {
"prepare:avax": "mustache config/avax.json stablejoe.template.yaml > stablejoe.avax.yaml",
"prepare:rinkeby": "mustache config/rinkeby.json stablejoe.template.yaml > stablejoe.rinkeby.yaml",
"codegen:avax": "graph codegen stablejoe.avax.yaml",
"codegen:rinkeby": "graph codegen stablejoe.rinkeby.yaml",
"build:avax": "graph build stablejoe.avax.yaml",
"build:rinkeby": "graph build stablejoe.rinkeby.yaml",
"deploy:avax": "graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ traderjoe-xyz/stablejoe stablejoe.avax.yaml",
"deploy:rinkeby": "graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ traderjoe-xyz/sjoe-rinkeby stablejoe.rinkeby.yaml",
"create-local": "graph create --node http://localhost:8020/ traderjoe-xyz/stablejoe --access-token ",
"remove-local": "graph remove --node http://localhost:8020/ traderjoe-xyz/stablejoe --access-token ",
"deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 --access-token traderjoe-xyz/stablejoe stablejoe.fuji.yaml"
},
"dependencies": {
"@graphprotocol/graph-cli": "0.26.0",
"@graphprotocol/graph-ts": "0.24.1"
}
}
26 changes: 26 additions & 0 deletions subgraphs/stablejoe/src/entities/daydata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { StableJoeDayData } from '../../generated/schema'
import { BIG_DECIMAL_ZERO } from 'const'
import { ethereum, BigInt, Address } from '@graphprotocol/graph-ts'

export function getStableJoeDayData(eventAddress: Address, block: ethereum.Block): StableJoeDayData {
const SECONDS_PER_DAY = 86400
const day = block.timestamp.toI32() / SECONDS_PER_DAY
const id = eventAddress.toHex().concat('-').concat(BigInt.fromI32(day).toString())

let dayData = StableJoeDayData.load(id)

if (dayData === null) {
dayData = new StableJoeDayData(id)
dayData.date = day
dayData.joeStaked = BIG_DECIMAL_ZERO
dayData.joeStakedUSD = BIG_DECIMAL_ZERO
dayData.joeUnstaked = BIG_DECIMAL_ZERO
dayData.joeUnstakedUSD = BIG_DECIMAL_ZERO
dayData.usdHarvested = BIG_DECIMAL_ZERO
dayData.depositFeeJOE = BIG_DECIMAL_ZERO
dayData.depositFeeUSD = BIG_DECIMAL_ZERO
}

dayData.save()
return dayData as StableJoeDayData
}
1 change: 1 addition & 0 deletions subgraphs/stablejoe/src/entities/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './daydata'
189 changes: 189 additions & 0 deletions subgraphs/stablejoe/src/mappings/stablejoe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import { Address, BigDecimal, BigInt, dataSource, ethereum, log } from '@graphprotocol/graph-ts'
import {
BIG_DECIMAL_1E18,
BIG_DECIMAL_1E6,
BIG_DECIMAL_ZERO,
JOE_USDT_PAIR_ADDRESS,
USDC_ADDRESS,
USDC_E_ADDRESS,
} from 'const'
import {
ClaimReward as ClaimRewardEvent,
Deposit as DepositEvent,
DepositFeeChanged as DepositFeeChangedEvent,
Withdraw as WithdrawEvent,
} from '../../generated/StableJoeStaking/StableJoeStaking'
import { StableJoe, User } from '../../generated/schema'
import { Pair as PairContract } from '../../generated/StableJoeStaking/Pair'
import { getStableJoeDayData } from '../entities'

function getJoePrice(): BigDecimal {
const pair = PairContract.bind(JOE_USDT_PAIR_ADDRESS)
const reservesResult = pair.try_getReserves()
if (reservesResult.reverted) {
log.info('[getJoePrice] getReserves reverted', [])
return BIG_DECIMAL_ZERO
}
const reserves = reservesResult.value
if (reserves.value0.toBigDecimal().equals(BigDecimal.fromString('0'))) {
log.error('[getJoePrice] USDT reserve 0', [])
return BIG_DECIMAL_ZERO
}
return reserves.value1.toBigDecimal().times(BIG_DECIMAL_1E18).div(reserves.value0.toBigDecimal()).div(BIG_DECIMAL_1E6)
}

export function convertAmountToDecimal(tokenAmount: BigInt): BigDecimal {
return tokenAmount.toBigDecimal().div(exponentToBigDecimal(BigInt.fromString('18')))
}

export function exponentToBigDecimal(decimals: BigInt): BigDecimal {
let bd = BigDecimal.fromString('1')
for (let i = BigInt.fromI32(0); i.lt(decimals as BigInt); i = i.plus(BigInt.fromI32(1))) {
bd = bd.times(BigDecimal.fromString('10'))
}
return bd
}

function createStableJoe(block: ethereum.Block): StableJoe {
log.debug('[createStableJoe] from {}', [dataSource.address().toHex()])

const stableJoe = new StableJoe(dataSource.address().toHex())
stableJoe.joeStaked = BIG_DECIMAL_ZERO
stableJoe.joeStakedUSD = BIG_DECIMAL_ZERO
stableJoe.usdHarvested = BIG_DECIMAL_ZERO
stableJoe.depositFee = BIG_DECIMAL_ZERO
stableJoe.depositFeeJOE = BIG_DECIMAL_ZERO
stableJoe.depositFeeUSD = BIG_DECIMAL_ZERO
stableJoe.updatedAt = block.timestamp
stableJoe.save()

return stableJoe as StableJoe
}

function getStableJoe(block: ethereum.Block): StableJoe {
log.debug('[getStableJoe] from {}', [dataSource.address().toHex()])

let stableJoe = StableJoe.load(dataSource.address().toHex())

if (stableJoe === null) {
stableJoe = createStableJoe(block)
}

return stableJoe as StableJoe
}

function createUser(address: Address, block: ethereum.Block): User {
const user = new User(address.toHex())

user.stableJoe = dataSource.address().toHex()
user.joeStaked = BIG_DECIMAL_ZERO
user.joeStakedUSD = BIG_DECIMAL_ZERO
user.usdHarvested = BIG_DECIMAL_ZERO
user.updatedAt = block.timestamp

return user as User
}

function getUser(address: Address, block: ethereum.Block): User {
let user = User.load(address.toHex())

if (user === null) {
user = createUser(address, block)
}

return user as User
}

export function handleClaimReward(event: ClaimRewardEvent): void {
const stableJoe = getStableJoe(event.block)
const user = getUser(event.params.user, event.block)

user.usdHarvested = user.usdHarvested.plus(convertAmountToDecimal(event.params.amount))
user.updatedAt = event.block.timestamp
user.save()

stableJoe.usdHarvested = stableJoe.usdHarvested.plus(convertAmountToDecimal(event.params.amount))
stableJoe.updatedAt = event.block.timestamp
stableJoe.save()

// update day data
if (USDC_ADDRESS === event.params.rewardToken || USDC_E_ADDRESS === event.params.rewardToken) {
let stableJoeDayData = getStableJoeDayData(event.address, event.block)
stableJoeDayData.usdHarvested = stableJoeDayData.usdHarvested.plus(convertAmountToDecimal(event.params.amount))
stableJoeDayData.save()
}
}

export function handleDeposit(event: DepositEvent): void {
log.debug('[handleDeposit] from {}', [dataSource.address().toHex()])

const stableJoe = getStableJoe(event.block)
let user = getUser(event.params.user, event.block)

user.joeStaked = user.joeStaked.plus(convertAmountToDecimal(event.params.amount))
user.joeStakedUSD = user.joeStakedUSD.plus(convertAmountToDecimal(event.params.amount).times(getJoePrice()))
user.updatedAt = event.block.timestamp
user.save()

log.debug('[handleDeposit] updating stableJoe and saving {}', [event.address.toHexString()])
stableJoe.joeStaked = stableJoe.joeStaked.plus(convertAmountToDecimal(event.params.amount))
stableJoe.joeStakedUSD = stableJoe.joeStakedUSD.plus(convertAmountToDecimal(event.params.amount).times(getJoePrice()))
stableJoe.updatedAt = event.block.timestamp
stableJoe.save()

log.debug('[handleDeposit] update deposit fees {}', [event.address.toHexString()])
// update deposit fees
if (stableJoe.depositFee) {
stableJoe.depositFeeJOE = stableJoe.depositFeeJOE.plus(stableJoe.depositFee)
stableJoe.depositFeeUSD = stableJoe.depositFeeUSD.plus(stableJoe.depositFee).times(getJoePrice())
}

log.debug('[handleDeposit] update day data {}', [event.address.toHexString()])
// update day data
let stableJoeDayData = getStableJoeDayData(event.address, event.block)
stableJoeDayData.joeStaked = stableJoeDayData.joeStaked.plus(convertAmountToDecimal(event.params.amount))
stableJoeDayData.joeStakedUSD = stableJoeDayData.joeStakedUSD.plus(
convertAmountToDecimal(event.params.amount).times(getJoePrice())
)
if (stableJoe.depositFee) {
stableJoeDayData.depositFeeJOE = stableJoeDayData.depositFeeJOE.plus(stableJoe.depositFee)
stableJoeDayData.depositFeeUSD = stableJoeDayData.depositFeeUSD.plus(stableJoe.depositFee).times(getJoePrice())
}

stableJoeDayData.save()
}

export function handleDepositFeeChanged(event: DepositFeeChangedEvent): void {
const stableJoe = getStableJoe(event.block)

stableJoe.depositFee = convertAmountToDecimal(event.params.newFee)
stableJoe.updatedAt = event.block.timestamp
stableJoe.save()
}

export function handleWithdraw(event: WithdrawEvent): void {
const stableJoe = getStableJoe(event.block)
const user = getUser(event.params.user, event.block)

user.joeStaked = user.joeStaked.minus(convertAmountToDecimal(event.params.amount))
user.joeStakedUSD = user.joeStakedUSD.minus(convertAmountToDecimal(event.params.amount).times(getJoePrice()))
user.updatedAt = event.block.timestamp
user.save()

const joePrice = getJoePrice()
stableJoe.joeStaked = stableJoe.joeStaked.minus(convertAmountToDecimal(event.params.amount))
stableJoe.joeStakedUSD = stableJoe.joeStakedUSD.minus(
convertAmountToDecimal(event.params.amount).times(getJoePrice())
)
stableJoe.updatedAt = event.block.timestamp
stableJoe.save()

// update day data
let stableJoeDayData = getStableJoeDayData(event.address, event.block)
stableJoeDayData.joeUnstaked = stableJoeDayData.joeUnstaked.plus(convertAmountToDecimal(event.params.amount))
stableJoeDayData.joeUnstakedUSD = stableJoeDayData.joeUnstakedUSD.plus(
convertAmountToDecimal(event.params.amount).times(joePrice)
)

stableJoeDayData.save()
}
62 changes: 62 additions & 0 deletions subgraphs/stablejoe/stablejoe.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# StableJoe
type StableJoe @entity {
# Contract address
id: ID!

# Joe staked
joeStaked: BigDecimal!

# Joe staked USD
joeStakedUSD: BigDecimal!

# USD harvested
usdHarvested: BigDecimal!

# Users in the bar
users: [User!]! @derivedFrom(field: "stableJoe")

# Deposit fee
depositFee: BigDecimal!

# Deposit fees collected in JOE
depositFeeJOE: BigDecimal!

# Deposit fees collected in USD
depositFeeUSD: BigDecimal!

# Last Updated At
updatedAt: BigInt!
}

# User
type User @entity {
# ID
id: ID!

# Stable Joe
stableJoe: StableJoe

# Staked
joeStaked: BigDecimal!

# Sum of $ at time of staking
joeStakedUSD: BigDecimal!

# USD harvested
usdHarvested: BigDecimal!

# Updated at
updatedAt: BigInt!
}

type StableJoeDayData @entity {
id: ID!
date: Int!
joeStaked: BigDecimal!
joeStakedUSD: BigDecimal!
joeUnstaked: BigDecimal!
joeUnstakedUSD: BigDecimal!
usdHarvested: BigDecimal!
depositFeeJOE: BigDecimal!
depositFeeUSD: BigDecimal!
}
35 changes: 35 additions & 0 deletions subgraphs/stablejoe/stablejoe.rinkeby.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
specVersion: 0.0.2
description: StableJoeStaking
schema:
file: ./stablejoe.graphql
dataSources:
- kind: ethereum/contract
name: StableJoeStaking
network: rinkeby
source:
address: '0x12ba94d04a7a7f0882155b2c55b88e269428227b'
abi: StableJoeStaking
startBlock: 10219081
mapping:
kind: ethereum/events
apiVersion: 0.0.4
language: wasm/assemblyscript
file: ./src/mappings/stablejoe.ts
entities:
- StableJoe
- User
- StableJoeDayData
abis:
- name: StableJoeStaking
file: ../../node_modules/@traderjoe-xyz/core/abi/StableJoeStaking.json
- name: Pair
file: ../../node_modules/@traderjoe-xyz/core/abi/JoePair.json
eventHandlers:
- event: ClaimReward(indexed address,indexed address,uint256)
handler: handleClaimReward
- event: Deposit(indexed address,uint256,uint256)
handler: handleDeposit
- event: DepositFeeChanged(uint256,uint256)
handler: handleDepositFeeChanged
- event: Withdraw(indexed address,uint256)
handler: handleWithdraw
Loading

0 comments on commit 8b1f332

Please sign in to comment.