Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stableswap Masterchef refactor #31

Merged
merged 10 commits into from
Apr 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fuseio/earn-sdk",
"version": "0.4.4",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
3 changes: 3 additions & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const UNISWAP_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/uni
export const FUSESWAP_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/fuseio/fuseswap'
export const VOLTAGE_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/voltfinance/voltage-exchange'
export const PANCAKESWAP_SUBGRAPH_URL = 'https://bsc.streamingfast.io/subgraphs/name/pancakeswap/exchange-v2'
export const STABLESWAP_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/voltfinance/stableswap'

export const MASTERCHEF_V2_ADDRESS = '0xc71E27C7e128d9CAEb2b8cA756647f7F199cF39e'
export const MASTERCHEF_V3_ADDRESS = '0xE3e184a7b75D0Ae6E17B58F5283b91B4E0A2604F'
Expand All @@ -17,3 +18,5 @@ export const MASTERCHEF_V3_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/na

export const xVOLT = '0x97a6e78c9208c21afaDa67e7E61d7ad27688eFd1'
export const VOLT = '0x34Ef2Cc892a88415e9f02b91BfA9c91fC0bE6bD4'

export const STABLESWAP_POOLS = ['0x2a68D7C6Ea986fA06B2665d08b4D08F5e7aF960c', '0x83D158Beadbb3445AC901cFd0ca33FB30CCC8f53']
15 changes: 14 additions & 1 deletion src/graphql/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import fetch from 'cross-fetch'
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client/core'
import { UNISWAP_SUBGRAPH_URL, FUSESWAP_SUBGRAPH_URL, PANCAKESWAP_SUBGRAPH_URL, MASTERCHEF_V2_SUBGRAPH_URL, MASTERCHEF_V3_SUBGRAPH_URL, VOLTAGE_SUBGRAPH_URL } from '../constants'
import {
UNISWAP_SUBGRAPH_URL,
FUSESWAP_SUBGRAPH_URL,
PANCAKESWAP_SUBGRAPH_URL,
MASTERCHEF_V2_SUBGRAPH_URL,
MASTERCHEF_V3_SUBGRAPH_URL,
VOLTAGE_SUBGRAPH_URL,
STABLESWAP_SUBGRAPH_URL
} from '../constants'

export const uniswapClient = new ApolloClient({
link: new HttpLink({ uri: UNISWAP_SUBGRAPH_URL, fetch }),
Expand Down Expand Up @@ -31,3 +39,8 @@ export const masterChefV3Client = new ApolloClient({
link: new HttpLink({ uri: MASTERCHEF_V3_SUBGRAPH_URL, fetch }),
cache: new InMemoryCache()
})

export const stableswapClient = new ApolloClient({
link: new HttpLink({ uri: STABLESWAP_SUBGRAPH_URL, fetch }),
cache: new InMemoryCache()
})
18 changes: 18 additions & 0 deletions src/graphql/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ export function pairQuery (address: string) {
`
}

export function stablePoolQuery (poolAddress: string) {
return gql`
{
swaps(id: "${poolAddress.toLowerCase()}") {
numTokens
balances
lpTokenSupply
virtualPrice
tokens {
id
name
symbol
}
}
}
`
}

export function tokenPriceQuery (address: string) {
return gql`
{
Expand Down
32 changes: 12 additions & 20 deletions src/rewards/ChefRewardProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,36 +75,30 @@ export default class ChefRewardProgram extends RewardProgram {
const globalTotalStake = pool?.balance
const userTotalStaked = weiToNumber(user?.amount).toString()

let reserve0, reserve1, token0, token1, pairPrice
let reserves, tokens, pairPrice

if (pairAddress.toLowerCase() === xVOLT.toLowerCase()) {
token0 = await fetchTokenInfo(xVOLT, this.web3)
token1 = null
tokens = [await fetchTokenInfo(xVOLT, this.web3), null]

reserve0 = globalTotalStake
reserve1 = null
reserves = [globalTotalStake, null]

pairPrice = await fetchVoltageTokenPrice(VOLT, networkId)
} else {
const {
reserveUSD,
totalSupply,
token0: token0Info,
token1: token1Info,
totalReserve0,
totalReserve1
tokens: tokensInfo,
totalReserves
} = await fetchChefPairInfo(pairAddress, networkId)

const reserves = calculateReserves(
const _reserves = calculateReserves(
globalTotalStake,
totalSupply,
totalReserve0,
totalReserve1
totalReserves
)

token0 = token0Info
token1 = token1Info
reserve0 = reserves[0].toFixed()
reserve1 = reserves[1].toFixed()
tokens = tokensInfo
reserves = _reserves.map((reserve) => reserve.toFixed())
pairPrice = reserveUSD / totalSupply
}

Expand Down Expand Up @@ -157,13 +151,11 @@ export default class ChefRewardProgram extends RewardProgram {
return {
globalTotalStake,
rewardsInfo,
token0,
token1,
tokens,
totalStakedUSD,
globalTotalStakeUSD,
pairPrice,
reserve0,
reserve1
reserves
}
}

Expand Down
9 changes: 3 additions & 6 deletions src/rewards/MultiRewardProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,7 @@ export default class MultiRewardProgram extends RewardProgram {
const [reserve0, reserve1] = calculateReserves(
globalTotalStake,
totalSupply,
totalReserve0,
totalReserve1
[totalReserve0, totalReserve1]
)

const pairPrice = reserveUSD / totalSupply
Expand All @@ -181,13 +180,11 @@ export default class MultiRewardProgram extends RewardProgram {
return {
globalTotalStake,
rewardsInfo,
token0,
token1,
tokens: [token0, token1],
totalStakedUSD,
globalTotalStakeUSD,
pairPrice,
reserve0: reserve0.toFixed(),
reserve1: reserve1.toFixed()
reserves: [reserve0.toFixed(), reserve1.toFixed()]
}
}

Expand Down
9 changes: 3 additions & 6 deletions src/rewards/SingleRewardProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,7 @@ export default class SingleRewardProgram extends RewardProgram {
const [reserve0, reserve1] = calculateReserves(
globalTotalStake,
totalSupply,
totalReserve0,
totalReserve1
[totalReserve0, totalReserve1]
)

const lockedRewards = new BigNumber(totalRewards).minus(
Expand Down Expand Up @@ -234,13 +233,11 @@ export default class SingleRewardProgram extends RewardProgram {
apyPercent
}
],
token0,
token1,
tokens: [token0, token1],
totalStakedUSD,
globalTotalStakeUSD,
pairPrice,
reserve0: reserve0.toFixed(),
reserve1: reserve1.toFixed(),
reserves: [reserve0.toFixed(), reserve1.toFixed()],
lockedRewards: lockedRewards.toFixed()
}
}
Expand Down
38 changes: 26 additions & 12 deletions src/utils/fetchChefPairInfo.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import { NetworkId } from '../constants'
import { pairQuery } from '../graphql/query'
import { voltageClient } from '../graphql'
import { pairQuery, stablePoolQuery } from '../graphql/query'
import { stableswapClient, voltageClient } from '../graphql'
import { isStableswap } from '.'

async function fetchPairInfoVoltage (address: string) {
const result = await voltageClient.query({
query: pairQuery(address)
})
return {
reserveUSD: result?.data?.pair?.reserveUSD,
totalSupply: result?.data?.pair?.totalSupply,
token0: result?.data?.pair?.token0,
token1: result?.data?.pair?.token1,
totalReserve0: result?.data?.pair?.reserve0,
totalReserve1: result?.data?.pair?.reserve1
let result
if (isStableswap(address)) {
result = await stableswapClient.query({
query: stablePoolQuery(address)
})
const tokens = result?.data?.swaps?.tokens
const reserves = result?.data?.swaps?.balances
return {
reserveUSD: result?.data?.swaps?.lpTokenSupply * 1,
totalSupply: result?.data?.swaps?.lpTokenSupply,
tokens,
totalReserves: reserves
}
} else {
result = await voltageClient.query({
query: pairQuery(address)
})
return {
reserveUSD: result?.data?.pair?.reserveUSD,
totalSupply: result?.data?.pair?.totalSupply,
tokens: [result?.data?.pair?.token0, result?.data?.pair?.token1],
totalReserves: [result?.data?.pair?.reserve0, result?.data?.pair?.reserve1]
}
}
}

Expand Down
22 changes: 12 additions & 10 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BigNumber } from 'bignumber.js'
import { MASTERCHEF_V2_ADDRESS, MASTERCHEF_V3_ADDRESS } from '../constants'
import { MASTERCHEF_V2_ADDRESS, MASTERCHEF_V3_ADDRESS, STABLESWAP_POOLS } from '../constants'
import { masterChefV2Client, masterChefV3Client } from '../graphql'
import { Chef } from '../rewards/ChefRewardProgram'

Expand All @@ -16,16 +16,14 @@ export function numberToWei (value: string, decimals = 18): string {
export function calculateReserves (
globalTotalStake: string,
totalSupply: string,
totalReserve0: string,
totalReserve1: string
totalReserves: string[]
) {
const reserve0 = new BigNumber(globalTotalStake)
.div(numberToWei(totalSupply))
.multipliedBy(numberToWei(totalReserve0))
const reserve1 = new BigNumber(globalTotalStake)
.div(numberToWei(totalSupply))
.multipliedBy(numberToWei(totalReserve1))
return [reserve0, reserve1]
const reserves = totalReserves.map(
(totalReserve) =>
new BigNumber(globalTotalStake)
.div(numberToWei(totalSupply))
.multipliedBy(numberToWei(totalReserve)))
return reserves
}

export function calculateApy (
Expand All @@ -52,3 +50,7 @@ export function getChefSubgraph (chef: Chef) {
return masterChefV3Client
}
}

export function isStableswap (address: string) {
return STABLESWAP_POOLS.includes(address)
}