Skip to content

Commit

Permalink
feat(gauges): Allow fetch on block number (#9110)
Browse files Browse the repository at this point in the history
<!--
Before opening a pull request, please read the [contributing
guidelines](https://github.com/pancakeswap/pancake-frontend/blob/develop/CONTRIBUTING.md)
first
-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances gauge fetching by adding block number support and
refactoring gauge-related functions.

### Detailed summary
- Added block number support for fetching gauges
- Updated functions to accept block number options
- Refactored gauge-related functions for better flexibility

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your
question}`

<!-- end pr-codex -->
  • Loading branch information
0xjojoex authored Feb 26, 2024
1 parent cad2dc3 commit 9886d06
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/large-bats-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@pancakeswap/gauges': minor
---

Allow fetch gagues with block number
1 change: 1 addition & 0 deletions apps/web/src/config/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const ARBITRUM_NODES = [

export const SERVER_NODES = {
[ChainId.BSC]: [
getNodeRealUrl(ChainId.BSC, process.env.SERVER_NODE_REAL_API_ETH) || '',
process.env.NEXT_PUBLIC_NODE_PRODUCTION || '',
getGroveUrl(ChainId.BSC, process.env.NEXT_PUBLIC_GROVE_API_KEY) || '',
'https://bsc.publicnode.com',
Expand Down
9 changes: 8 additions & 1 deletion apps/web/src/pages/api/gauges/getAllGauges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const handler: NextApiHandler = async (req, res) => {
const inCap = Boolean(queryParsed.inCap ?? true)
const bothCap = Boolean(queryParsed.bothCap ?? false)
const killed = Boolean(queryParsed.killed ?? false)
const blockNumber = queryParsed.blockNumber ? BigInt(queryParsed.blockNumber as string) : undefined

try {
const gauges = await getAllGauges(
Expand All @@ -26,10 +27,16 @@ const handler: NextApiHandler = async (req, res) => {
inCap,
bothCap,
killed,
blockNumber,
},
)

res.setHeader('Cache-Control', `max-age=0, s-maxage=${MAX_CACHE_SECONDS}, stale-while-revalidate`)
if (blockNumber) {
// cache for long time if blockNumber is provided
res.setHeader('Cache-Control', `max-age=10800, s-maxage=31536000`)
} else {
res.setHeader('Cache-Control', `max-age=10, s-maxage=${MAX_CACHE_SECONDS}, stale-while-revalidate`)
}
return res.status(200).json({
data: JSON.parse(stringify(gauges)),
lastUpdated: Number(Date.now()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ArcElement, Chart as ChartJS, Legend, Tooltip } from 'chart.js'
import React, { useCallback, useMemo, useRef, useState } from 'react'
import { Doughnut } from 'react-chartjs-2'
import styled, { keyframes } from 'styled-components'
import { Hash } from 'viem'
import { ChartLabel } from './ChartLabel'
import { ChartTooltip, OTHERS_GAUGES } from './ChartTooltip'

Expand Down Expand Up @@ -93,7 +94,7 @@ export const WeightsPieChart: React.FC<{
}
},
{
hash: OTHERS_GAUGES,
hash: OTHERS_GAUGES as Hash,
pairName: `Other|${sortedGauge.length - maxCount}`,
} as Gauge,
)
Expand Down
10 changes: 8 additions & 2 deletions packages/gauges/src/fetchAllGauges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ import { fetchGaugesCount } from './fetchGaugesCount'
import { getGaugeHash } from './getGaugeHash'
import { GaugeInfo } from './types'

export const fetchAllGauges = async (client: PublicClient): Promise<GaugeInfo[]> => {
export const fetchAllGauges = async (
client: PublicClient,
options?: {
blockNumber?: bigint
},
): Promise<GaugeInfo[]> => {
const contract = getContract(client)
const counts = await fetchGaugesCount(client)
const counts = await fetchGaugesCount(client, options)

const multicalls: MulticallContracts<ContractFunctionConfig<typeof gaugesVotingABI, 'gauges'>[]> = []

Expand All @@ -22,6 +27,7 @@ export const fetchAllGauges = async (client: PublicClient): Promise<GaugeInfo[]>
const response = (await client.multicall({
contracts: multicalls,
allowFailure: false,
...options,
})) as ContractFunctionResult<typeof gaugesVotingABI, 'gauges'>[]

return response.reduce((prev, curr) => {
Expand Down
19 changes: 16 additions & 3 deletions packages/gauges/src/fetchAllKilledGauges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { gaugesVotingABI } from './abis'
import { getContract } from './contract'
import { GaugeInfo } from './types'

export const filterKilledGauges = async (client: PublicClient, gauges: GaugeInfo[]): Promise<GaugeInfo[]> => {
export const fetchAllKilledGauges = async (
client: PublicClient,
gauges: GaugeInfo[],
options?: {
blockNumber?: bigint
},
): Promise<GaugeInfo[]> => {
const contract = getContract(client)

const multicalls: MulticallContracts<ContractFunctionConfig<typeof gaugesVotingABI, 'gaugeIsKilled_'>[]> = []
Expand All @@ -19,9 +25,16 @@ export const filterKilledGauges = async (client: PublicClient, gauges: GaugeInfo
const response = (await client.multicall({
contracts: multicalls,
allowFailure: false,
...options,
})) as ContractFunctionResult<typeof gaugesVotingABI, 'gaugeIsKilled_'>[]

return gauges.filter((_, index) => {
return !response[index]
return gauges.map((gauge, index) => {
if (response[index] === true) {
return {
...gauge,
killed: response[index],
}
}
return gauge
})
}
5 changes: 4 additions & 1 deletion packages/gauges/src/fetchGaugeVoting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ export const fetchAllGaugesVoting = async (
client: PublicClient,
gaugeInfos: GaugeInfoConfig[],
inCap: boolean = true,
options?: {
blockNumber?: bigint
},
): Promise<Gauge[]> => {
const contract = getCalcContract(client)

const weights = await contract.read.massGetGaugeWeight([inCap])
const weights = await contract.read.massGetGaugeWeight([inCap], options)

return gaugeInfos.map((gauge) => ({
...gauge,
Expand Down
9 changes: 7 additions & 2 deletions packages/gauges/src/fetchGaugesCount.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { PublicClient } from 'viem'
import { getContract } from './contract'

export const fetchGaugesCount = async (client: PublicClient): Promise<number> => {
export const fetchGaugesCount = async (
client: PublicClient,
options?: {
blockNumber?: bigint
},
): Promise<number> => {
const contract = getContract(client)

const count = await contract.read.gaugeCount()
const count = await contract.read.gaugeCount(options)

return Number(count || 0)
}
19 changes: 12 additions & 7 deletions packages/gauges/src/getAllGauges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PublicClient } from 'viem'
import { CONFIG_PROD } from './constants/config/prod'
import { CONFIG_TESTNET } from './constants/config/testnet'
import { fetchAllGauges } from './fetchAllGauges'
import { filterKilledGauges } from './fetchAllKilledGauges'
import { fetchAllKilledGauges } from './fetchAllKilledGauges'
import { fetchAllGaugesVoting } from './fetchGaugeVoting'
import { Gauge, GaugeConfig, GaugeInfoConfig } from './types'

Expand All @@ -12,6 +12,7 @@ export type getAllGaugesOptions = {
bothCap?: boolean
// include killed gauges if true
killed?: boolean
blockNumber?: bigint
}

export const getAllGauges = async (
Expand All @@ -23,13 +24,17 @@ export const getAllGauges = async (
killed: false,
},
): Promise<Gauge[]> => {
const { testnet, inCap, bothCap, killed } = options
const { testnet, inCap, bothCap, killed, blockNumber } = options
const presets = testnet ? CONFIG_TESTNET : CONFIG_PROD

const allGaugeInfos = await fetchAllGauges(client)
const allGaugeInfos = await fetchAllGauges(client, {
blockNumber,
})
let allActiveGaugeInfos = allGaugeInfos

if (!killed) allActiveGaugeInfos = await filterKilledGauges(client, allGaugeInfos)
allActiveGaugeInfos = await fetchAllKilledGauges(client, allGaugeInfos, { blockNumber })

if (!killed) allActiveGaugeInfos = allGaugeInfos.filter((gauge) => !gauge.killed)

const allGaugeInfoConfigs = allActiveGaugeInfos.reduce((prev, gauge) => {
const filters = presets.filter((p) => p.address === gauge.pairAddress && Number(p.chainId) === gauge.chainId)
Expand All @@ -52,12 +57,12 @@ export const getAllGauges = async (
}, [] as GaugeInfoConfig[])

if (!bothCap) {
const allGaugesVoting = await fetchAllGaugesVoting(client, allGaugeInfoConfigs, inCap)
const allGaugesVoting = await fetchAllGaugesVoting(client, allGaugeInfoConfigs, inCap, options)
return allGaugesVoting
}

const inCapVoting = await fetchAllGaugesVoting(client, allGaugeInfoConfigs, true)
const notInCapVoting = await fetchAllGaugesVoting(client, allGaugeInfoConfigs, false)
const inCapVoting = await fetchAllGaugesVoting(client, allGaugeInfoConfigs, true, options)
const notInCapVoting = await fetchAllGaugesVoting(client, allGaugeInfoConfigs, false, options)

return inCapVoting.reduce((prev, inCapGauge) => {
const notInCapGauge = notInCapVoting.find((p) => p.hash === inCapGauge.hash)
Expand Down
5 changes: 3 additions & 2 deletions packages/gauges/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChainId } from '@pancakeswap/chains'
import { FeeAmount } from '@pancakeswap/v3-sdk'
import type { Address } from 'viem'
import type { Address, Hash } from 'viem'

export enum GaugeType {
// @note: this is a hack
Expand Down Expand Up @@ -66,13 +66,14 @@ export interface GaugeVeCakePoolConfig extends GaugeBaseConfig {
export type GaugeConfig = GaugeV2Config | GaugeStableSwapConfig | GaugeV3Config | GaugeALMConfig | GaugeVeCakePoolConfig

export type GaugeInfo = {
hash: string
hash: Hash
pairAddress: Address
masterChef: Address
pid: number
chainId: number
boostMultiplier: number
maxVoteCap: number
killed?: boolean
}

export type GaugeInfoConfig = GaugeInfo & GaugeConfig
Expand Down

0 comments on commit 9886d06

Please sign in to comment.