From afa2ba95fbaa29e2770b9e0db097eaabf0886f5d Mon Sep 17 00:00:00 2001 From: stephen <991266+stxphxn@users.noreply.github.com> Date: Wed, 17 Apr 2024 19:13:56 +0700 Subject: [PATCH 1/2] =?UTF-8?q?Enable=20Gauge=20Voting=20=F0=9F=97=B3?= =?UTF-8?q?=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 6 +- src/components/cards/MyWallet/MyWallet.vue | 11 +- .../vebal/LMVoting/meter-voting-pools.ts | 206 ++++++++++++++++++ .../queries/useVotingPoolsQuery.ts | 6 +- src/composables/useNetwork.ts | 1 + src/constants/pools.ts | 3 +- src/lib/config/meter/contracts.ts | 10 +- src/lib/config/meter/index.ts | 3 +- src/lib/config/meter/pools.ts | 8 +- .../api/graphql/generated/api-types.ts | 1 + src/services/api/graphql/mappers.ts | 2 + .../gauges/gauge-controller.decorator.ts | 34 ++- .../staking/staking-rewards.service.ts | 8 +- 13 files changed, 272 insertions(+), 27 deletions(-) create mode 100644 src/components/contextual/pages/vebal/LMVoting/meter-voting-pools.ts diff --git a/index.html b/index.html index d562affba..dc35c8f2f 100644 --- a/index.html +++ b/index.html @@ -24,7 +24,7 @@ @@ -33,7 +33,7 @@ { return t('noNativeCurrency', [nativeCurrency, networkName]); }); -const noNativeCurrencyMessageEthereum = computed(() => { - return t('noNativeCurrencyEthereum', [nativeCurrency, networkName]); -}); - const noTokensMessage = computed(() => { return t('noTokensInWallet', [networkName]); }); @@ -108,11 +103,7 @@ const emit = defineEmits<{ {{ nativeBalance }} {{ nativeCurrency }} => { try { let apiVotingPools: ApiVotingPools; + console.log(isMeter.value); if (isTestnet.value) { apiVotingPools = testnetVotingPools('GOERLI'); } else if (isMainnet.value) { apiVotingPools = telosVotingPools('telos'); + } else if (isMeter.value) { + apiVotingPools = meterVotingPools('meter'); } else { const api = getApi(); console.log(api); diff --git a/src/composables/useNetwork.ts b/src/composables/useNetwork.ts index b57fc367d..5eeba7cc2 100644 --- a/src/composables/useNetwork.ts +++ b/src/composables/useNetwork.ts @@ -40,6 +40,7 @@ export const isMainnet = computed( networkId.value === Network.TELOS || networkId.value === Network.TELOSTESTNET ); +export const isMeter = computed(() => networkId.value === Network.METER); export const isPolygon = computed(() => networkId.value === Network.POLYGON); export const isZkevm = computed(() => networkId.value === Network.ZKEVM); export const isOptimism = computed(() => networkId.value === Network.OPTIMISM); diff --git a/src/constants/pools.ts b/src/constants/pools.ts index 6179079d8..935a3fe5f 100644 --- a/src/constants/pools.ts +++ b/src/constants/pools.ts @@ -1,8 +1,7 @@ -import { isMainnet } from '@/composables/useNetwork'; import { Pools } from '@/types/pools'; import { configService } from '@/services/config/config.service'; -export const MIN_FIAT_VALUE_POOL_MIGRATION = isMainnet.value ? 100_000 : 1; // 100K USD or $1 for other networks +export const MIN_FIAT_VALUE_POOL_MIGRATION = 1; // 100K USD or $1 for other networks // Do not display APR values greater than this amount; they are likely to be nonsensical // These can arise from pools with extremely low balances (e.g., completed LBPs) diff --git a/src/lib/config/meter/contracts.ts b/src/lib/config/meter/contracts.ts index 40229ecbb..1e81dd9e3 100644 --- a/src/lib/config/meter/contracts.ts +++ b/src/lib/config/meter/contracts.ts @@ -15,11 +15,11 @@ const contracts: Contracts = { balancerQueries: meter.BalancerQueries, batchRelayer: meter.BalancerRelayer, veBAL: meter.VotingEscrow, - gaugeController: '', - gaugeFactory: '', - balancerMinter: '', - tokenAdmin: '', - veDelegationProxy: '', + gaugeController: meter.GaugeController, + gaugeFactory: meter.LiquidityGaugeFactory, + balancerMinter: meter.BalancerMinter, + tokenAdmin: meter.MSYMMTokenAdmin, + veDelegationProxy: meter.VotingEscrowDelegationProxy, veBALHelpers: '', feeDistributor: '', feeDistributorDeprecated: '', diff --git a/src/lib/config/meter/index.ts b/src/lib/config/meter/index.ts index 94757d470..eaa64d2a3 100644 --- a/src/lib/config/meter/index.ts +++ b/src/lib/config/meter/index.ts @@ -30,10 +30,11 @@ const config: Config = { 'https://storageapi.fleek.co/johngrantuk-team-bucket/poolsV2.json', subgraphs: { main: [ + 'http://graph.meter.io:8000/subgraphs/name/symmetric-meter', 'https://graph-meter.voltswap.finance/subgraphs/name/symmetric-meter', ], aave: '', - gauge: '', + gauge: 'http://graph.meter.io:8000/subgraphs/name/symmetric-meter-gauges', blocks: '', }, bridgeUrl: 'https://passport.meter.io/', diff --git a/src/lib/config/meter/pools.ts b/src/lib/config/meter/pools.ts index d230d1fbf..5f3a1dad6 100644 --- a/src/lib/config/meter/pools.ts +++ b/src/lib/config/meter/pools.ts @@ -54,7 +54,13 @@ const pools: Pools = { }, Stakable: { VotingGaugePools: [], - AllowList: [], + AllowList: [ + '0xd9fe77653c2b75cf3442c365a3f1f9c7ed1612c7000200000000000000000003', //MTRG/USDT-USDC-suUSD + '0xc4187382305ea2c953f0a164f02b4d27c9957db5000200000000000000000005', //MST-MTRG + '0x6e1be32644975613212db00bb9762fb6755ab921000200000000000000000007', //ETH-wstMTRG + '0x1ff97abe4c5a4b7ff90949b637e71626bef0dcee000000000000000000000002', //USDT-USDC-suUSD + '0x2077a828fd58025655335a8756dbcfeb7e5bec46000000000000000000000008', //mtrg-wstMTRG + ], }, Metadata: {}, Deep: [ diff --git a/src/services/api/graphql/generated/api-types.ts b/src/services/api/graphql/generated/api-types.ts index 15f22626b..73429948f 100644 --- a/src/services/api/graphql/generated/api-types.ts +++ b/src/services/api/graphql/generated/api-types.ts @@ -54,6 +54,7 @@ export enum GqlChain { Polygon = 'POLYGON', Zkevm = 'ZKEVM', Telos = 'telos', + Meter = 'meter', } export type GqlContentNewsItem = { diff --git a/src/services/api/graphql/mappers.ts b/src/services/api/graphql/mappers.ts index ae1a4b739..6e65537c7 100644 --- a/src/services/api/graphql/mappers.ts +++ b/src/services/api/graphql/mappers.ts @@ -30,6 +30,8 @@ export function mapApiChain( return Network.GOERLI; case 'telos': return Network.TELOS; + case 'meter': + return Network.METER; default: throw new Error(`Unexpected API chain: ${apiChain}`); diff --git a/src/services/balancer/gauges/gauge-controller.decorator.ts b/src/services/balancer/gauges/gauge-controller.decorator.ts index b04e7bfd9..70cfc395b 100644 --- a/src/services/balancer/gauges/gauge-controller.decorator.ts +++ b/src/services/balancer/gauges/gauge-controller.decorator.ts @@ -12,7 +12,7 @@ import { rpcProviderService } from '@/services/rpc-provider/rpc-provider.service import { getOldMulticaller } from '@/dependencies/OldMulticaller'; // eslint-disable-next-line no-restricted-imports import { Multicaller } from '@/lib/utils/balancer/contract'; -import { networkId, isTestnet } from '@/composables/useNetwork'; +import { networkId, isTestnet, isMeter } from '@/composables/useNetwork'; import { Network } from '@/lib/config/types'; import { ApiVotingPools, @@ -89,6 +89,10 @@ export class GaugeControllerDecorator { return { ...pool, ...this.formatVotes(votesDataMap.gauges[pool.gauge.address]), + // votes: '0', + // votesNextPeriod: '0', + // userVotes: '0', + // lastUserVoteTime: 0, }; }); return decoratedVotingPools; @@ -110,6 +114,7 @@ export class GaugeControllerDecorator { * @summary Fetch total points allocated towards each gauge for this period */ private callGaugeWeightThisPeriod(votingGauges: ApiVotingGauge[]) { + console.log(votingGauges); let thisWeekTimestamp = toUnixTimestamp( Math.floor(Date.now() / oneWeekInMs) * oneWeekInMs ); @@ -119,7 +124,18 @@ export class GaugeControllerDecorator { if (thisWeekTimestamp == FIRST_WEEK_TIMESTAMP) { thisWeekTimestamp = thisWeekTimestamp - oneWeekInSecs; } - votingGauges.forEach(gauge => { + // if (networkId.value === 82) { + // return votingGauges.forEach(gauge => { + // this.multicaller.call( + // `gauges.${gauge.address}.gaugeWeightNextPeriod`, + // gauge.address, + // 'getCappedRelativeWeight', + // [thisWeekTimestamp] + // ); + // }); + // } + console.log(thisWeekTimestamp); + return votingGauges.forEach(gauge => { this.multicaller.call( `gauges.${gauge.address}.gaugeWeightThisPeriod`, this.config.network.addresses.gaugeController, @@ -136,7 +152,17 @@ export class GaugeControllerDecorator { const nextWeekTimestamp = toUnixTimestamp( Math.floor((Date.now() + oneWeekInMs) / oneWeekInMs) * oneWeekInMs ); - votingGauges.forEach(gauge => { + // if (networkId.value === 82) { + // return votingGauges.forEach(gauge => { + // this.multicaller.call( + // `gauges.${gauge.address}.gaugeWeightNextPeriod`, + // gauge.address, + // 'getCappedRelativeWeight', + // [nextWeekTimestamp] + // ); + // }); + // } + return votingGauges.forEach(gauge => { this.multicaller.call( `gauges.${gauge.address}.gaugeWeightNextPeriod`, this.config.network.addresses.gaugeController, @@ -188,6 +214,8 @@ export class GaugeControllerDecorator { private getNetwork(): Network { if (isTestnet.value) { return networkId.value; + } else if (isMeter.value) { + return Network.METER; } else { return Network.TELOS; } diff --git a/src/services/staking/staking-rewards.service.ts b/src/services/staking/staking-rewards.service.ts index c7d957dfb..195947537 100644 --- a/src/services/staking/staking-rewards.service.ts +++ b/src/services/staking/staking-rewards.service.ts @@ -46,10 +46,14 @@ export class StakingRewardsService { ); let veBALTotalSupply = '0'; - if (networkId.value === Network.TELOS) { + if ( + networkId.value === Network.TELOS || + networkId.value === Network.METER + ) { const lockInfo = await new BalancerContractsService().veBAL.getLockInfo( userAddress ); + console.log('lockInfo', lockInfo); veBALTotalSupply = lockInfo.totalSupply; } else { // get l2 veBAL total supply from delegation proxy @@ -58,7 +62,9 @@ export class StakingRewardsService { // need to use veBAL balance from the proxy as the balance from the proxy takes // into account the amount of delegated veBAL as well + console.log('userAddress', userAddress); const userVeBALBalance = await veBalProxy.getAdjustedBalance(userAddress); + console.log('userVeBALBalance', userVeBALBalance); return { veBALTotalSupply, From 7cc2430efe9a27799981bb8f2bb7312b3b667b9b Mon Sep 17 00:00:00 2001 From: stephen <991266+stxphxn@users.noreply.github.com> Date: Thu, 18 Apr 2024 05:34:10 +0700 Subject: [PATCH 2/2] Add gauges subgraph --- package-lock.json | 14 +++--- package.json | 2 +- .../queries/useVotingEscrowQuery.ts | 2 +- src/lib/config/meter/index.ts | 4 +- .../pool/decorators/pool.decorator.ts | 46 +++++++++++++++++-- src/services/pool/pool.service.ts | 34 +++++++------- 6 files changed, 70 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index babbffb21..b6133bde8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "@popperjs/core": "^2.9.2", "@sentry/browser": "^7.17.4", "@sentry/tracing": "^7.17.4", - "@symmetric-v3/sdk": "^1.2.16-beta.1", + "@symmetric-v3/sdk": "^1.2.17-beta.1", "@tanstack/vue-query": "^4.22.0", "@testing-library/jest-dom": "^5.16.1", "@testing-library/vue": "^7.0.0", @@ -6833,9 +6833,9 @@ } }, "node_modules/@symmetric-v3/sdk": { - "version": "1.2.16-beta.1", - "resolved": "https://registry.npmjs.org/@symmetric-v3/sdk/-/sdk-1.2.16-beta.1.tgz", - "integrity": "sha512-8vg2WnuKOWMx1OBlm83/8s8B5BNOBMZK4VycyCnpcRSQg9nJ1SbzsWI5i99L0ovuqGQgpiOUf3cAvJRXsvICCw==", + "version": "1.2.17-beta.1", + "resolved": "https://registry.npmjs.org/@symmetric-v3/sdk/-/sdk-1.2.17-beta.1.tgz", + "integrity": "sha512-/f4NmiZJE+hN1g9DZtpSedEcbDf74pSFPWSLBnqNIJPtFhFFRMKFspRSj1ABwiB9mPJ/9QkJJSeAk3uWw2pfUQ==", "dev": true, "dependencies": { "@balancer-labs/sor": "^4.1.1-beta.16", @@ -34330,9 +34330,9 @@ } }, "@symmetric-v3/sdk": { - "version": "1.2.16-beta.1", - "resolved": "https://registry.npmjs.org/@symmetric-v3/sdk/-/sdk-1.2.16-beta.1.tgz", - "integrity": "sha512-8vg2WnuKOWMx1OBlm83/8s8B5BNOBMZK4VycyCnpcRSQg9nJ1SbzsWI5i99L0ovuqGQgpiOUf3cAvJRXsvICCw==", + "version": "1.2.17-beta.1", + "resolved": "https://registry.npmjs.org/@symmetric-v3/sdk/-/sdk-1.2.17-beta.1.tgz", + "integrity": "sha512-/f4NmiZJE+hN1g9DZtpSedEcbDf74pSFPWSLBnqNIJPtFhFFRMKFspRSj1ABwiB9mPJ/9QkJJSeAk3uWw2pfUQ==", "dev": true, "requires": { "@balancer-labs/sor": "^4.1.1-beta.16", diff --git a/package.json b/package.json index bfae1fcea..2ffc58107 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "@popperjs/core": "^2.9.2", "@sentry/browser": "^7.17.4", "@sentry/tracing": "^7.17.4", - "@symmetric-v3/sdk": "^1.2.16-beta.1", + "@symmetric-v3/sdk": "^1.2.17-beta.1", "@tanstack/vue-query": "^4.22.0", "@testing-library/jest-dom": "^5.16.1", "@testing-library/vue": "^7.0.0", diff --git a/src/composables/queries/useVotingEscrowQuery.ts b/src/composables/queries/useVotingEscrowQuery.ts index d68f079a8..b99815b19 100644 --- a/src/composables/queries/useVotingEscrowQuery.ts +++ b/src/composables/queries/useVotingEscrowQuery.ts @@ -33,7 +33,7 @@ export function useVotingEscrowLocksQuery( return false; } - if (networkId === Network.MAINNET) { + if (networkId === Network.TELOS || networkId === Network.METER) { return true; } diff --git a/src/lib/config/meter/index.ts b/src/lib/config/meter/index.ts index eaa64d2a3..c70b7e4dc 100644 --- a/src/lib/config/meter/index.ts +++ b/src/lib/config/meter/index.ts @@ -30,11 +30,11 @@ const config: Config = { 'https://storageapi.fleek.co/johngrantuk-team-bucket/poolsV2.json', subgraphs: { main: [ - 'http://graph.meter.io:8000/subgraphs/name/symmetric-meter', 'https://graph-meter.voltswap.finance/subgraphs/name/symmetric-meter', ], aave: '', - gauge: 'http://graph.meter.io:8000/subgraphs/name/symmetric-meter-gauges', + gauge: + 'https://graph-meter.voltswap.finance/subgraphs/name/symmetric-meter-gauges', blocks: '', }, bridgeUrl: 'https://passport.meter.io/', diff --git a/src/services/pool/decorators/pool.decorator.ts b/src/services/pool/decorators/pool.decorator.ts index cca394b94..059f58406 100644 --- a/src/services/pool/decorators/pool.decorator.ts +++ b/src/services/pool/decorators/pool.decorator.ts @@ -7,6 +7,7 @@ import PoolService from '../pool.service'; import { PoolMulticaller } from './pool.multicaller'; import axios from 'axios'; import { configService } from '@/services/config/config.service'; +import { rewardSymbol } from '@/composables/useNetwork'; /** * @summary Decorates a set of pools with additonal data. @@ -22,11 +23,14 @@ export class PoolDecorator { tokens: TokenInfoMap, fullDecoration = true ): Promise { - if (configService.network.chainId === 40) { + if ( + configService.network.chainId === 40 + // configService.network.chainId === 82 + ) { const rewardData: any = localStorage.getItem('REWARD_PRICE'); if (rewardData) { - const { timestamp } = JSON.parse(rewardData); - if (isPriceOutdated(timestamp)) { + const data = JSON.parse(rewardData); + if (isPriceOutdated(data.timestamp) || !data[`${rewardSymbol}_price`]) { setRewardPriceInLocalStorage() .then(() => { console.log('REWARD_PRICE has been updated in local storage'); @@ -128,11 +132,43 @@ const getWTLOSPrice = async (): Promise => { } }; +// const getMTRG_wstMTRGPrice = async (): Promise => { +// try { +// const priceQuery = await useGraphQuery( +// config[Network.METER].subgraph, +// QUERY_KEYS.Tokens.Prices( +// ref(82), +// ref({ +// '0x2077a828fd58025655335a8756dbcfeb7e5bec46': 0, +// }) +// ), +// () => ({ +// token: { +// id: '0x2077a828fd58025655335a8756dbcfeb7e5bec46', +// latestUSDPrice: true, +// }, +// }), +// reactive({ enabled: isEnabled }) +// ); +// console.log(priceQuery); +// const response = await axios.get( +// 'https://api.coingecko.com/api/v3/simple/token_price/telos?contract_addresses=0xD102cE6A4dB07D247fcc28F366A623Df0938CA9E&vs_currencies=usd' +// ); +// const price = +// response.data['0xd102ce6a4db07d247fcc28f366a623df0938ca9e'].usd; +// return price; +// } catch (error) { +// console.error(error); +// throw error; +// } +// }; + const setRewardPriceInLocalStorage = async (): Promise => { try { - const price = await getWTLOSPrice(); + const WTLOS_price = await getWTLOSPrice(); + // const MTRG_wstMTRG_price = await getMTRG_wstMTRGPrice(); const timestamp = Date.now(); - const data = { price, timestamp }; + const data = { WTLOS_price, timestamp }; localStorage.setItem('REWARD_PRICE', JSON.stringify(data)); } catch (error) { console.error(error); diff --git a/src/services/pool/pool.service.ts b/src/services/pool/pool.service.ts index 17db8882b..fbddaab95 100644 --- a/src/services/pool/pool.service.ts +++ b/src/services/pool/pool.service.ts @@ -13,7 +13,7 @@ import { TokenInfoMap } from '@/types/TokenList'; import { OnchainDataFormater } from './decorators/onchain-data.formater'; import { AprBreakdown } from '@symmetric-v3/sdk'; -import useNetwork, { networkId } from '@/composables/useNetwork'; +import useNetwork, { networkId, rewardSymbol } from '@/composables/useNetwork'; import { getBalancerSDK } from '@/dependencies/balancer-sdk'; import { Pool as SDKPool } from '@symmetric-v3/sdk'; import { captureBalancerException } from '@/lib/utils/errors'; @@ -87,21 +87,23 @@ export default class PoolService { const rewardData: any = localStorage.getItem('REWARD_PRICE'); console.log(rewardData); if (rewardData) { - const { price } = JSON.parse(rewardData); - const rewardPrice = parseFloat(price); - const yearlyRewardUsd = - parseFloat(formatUnits(yearlyReward.toString(), 18)) * rewardPrice; - const totalSupply = await gaugeTotalSupply(this.pool.address); - const totalSupplyUsd = Number(this.bptPrice) * totalSupply; - const rewardValue = - yearlyRewardUsd / parseFloat(totalSupplyUsd.toString()); - const rewardValueScaled = Math.round(10000 * rewardValue); - apr.rewardAprs = { - total: rewardValueScaled, - breakdown: { - [reward.token]: rewardValueScaled, - }, - }; + const data = JSON.parse(rewardData); + if (data[`${rewardSymbol.value}_price`]) { + const rewardPrice = parseFloat(data[`${rewardSymbol.value}_price`]); + const yearlyRewardUsd = + parseFloat(formatUnits(yearlyReward.toString(), 18)) * rewardPrice; + const totalSupply = await gaugeTotalSupply(this.pool.address); + const totalSupplyUsd = Number(this.bptPrice) * totalSupply; + const rewardValue = + yearlyRewardUsd / parseFloat(totalSupplyUsd.toString()); + const rewardValueScaled = Math.round(10000 * rewardValue); + apr.rewardAprs = { + total: rewardValueScaled, + breakdown: { + [reward.token]: rewardValueScaled, + }, + }; + } } }