From c849508e01b329415bbb503a65f800c422ba0d4a Mon Sep 17 00:00:00 2001 From: 0xPeluche <0xpeluche@proton.me> Date: Thu, 16 Nov 2023 19:12:11 +0100 Subject: [PATCH 1/3] Smardex missings pools, missing stake, new MasterChef --- src/adapters/smardex/ethereum/farm.ts | 156 +++++++----------------- src/adapters/smardex/ethereum/index.ts | 78 ++++++++---- src/adapters/smardex/ethereum/pool.ts | 59 +++++++++ src/adapters/smardex/ethereum/reward.ts | 35 ++++++ src/adapters/smardex/ethereum/stake.ts | 35 +++--- 5 files changed, 209 insertions(+), 154 deletions(-) create mode 100644 src/adapters/smardex/ethereum/pool.ts create mode 100644 src/adapters/smardex/ethereum/reward.ts diff --git a/src/adapters/smardex/ethereum/farm.ts b/src/adapters/smardex/ethereum/farm.ts index ce75ac111..7dd2fb1ea 100644 --- a/src/adapters/smardex/ethereum/farm.ts +++ b/src/adapters/smardex/ethereum/farm.ts @@ -1,37 +1,22 @@ -import type { Balance, BalancesContext, BaseContext, Contract } from '@lib/adapter' -import { keyBy, rangeBI } from '@lib/array' +import type { BalancesContext, Contract } from '@lib/adapter' import { mapSuccessFilter } from '@lib/array' -import { call } from '@lib/call' -import type { Call } from '@lib/multicall' +import type { GetUsersInfosParams } from '@lib/masterchef/masterChefBalance' import { multicall } from '@lib/multicall' -import type { Token } from '@lib/token' -import { isNotNullish } from '@lib/type' -import type { Pair } from '@lib/uniswap/v2/factory' -import { getUnderlyingBalances } from '@lib/uniswap/v2/pair' const abi = { - campaignInfo: { - inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - name: 'campaignInfo', + userInfo: { + inputs: [ + { internalType: 'uint256', name: '', type: 'uint256' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'userInfo', outputs: [ - { internalType: 'contract IERC20', name: 'stakingToken', type: 'address' }, - { internalType: 'contract IERC20', name: 'rewardToken', type: 'address' }, - { internalType: 'uint256', name: 'startBlock', type: 'uint256' }, - { internalType: 'uint256', name: 'lastRewardBlock', type: 'uint256' }, - { internalType: 'uint256', name: 'accRewardPerShare', type: 'uint256' }, - { internalType: 'uint256', name: 'totalStaked', type: 'uint256' }, - { internalType: 'uint256', name: 'totalRewards', type: 'uint256' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, ], stateMutability: 'view', type: 'function', }, - campaignInfoLen: { - inputs: [], - name: 'campaignInfoLen', - outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - stateMutability: 'view', - type: 'function', - }, pendingReward: { inputs: [ { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, @@ -42,107 +27,48 @@ const abi = { stateMutability: 'view', type: 'function', }, - userInfo: { - inputs: [ - { internalType: 'uint256', name: '', type: 'uint256' }, - { internalType: 'address', name: '', type: 'address' }, - ], - name: 'userInfo', - outputs: [ - { internalType: 'uint256', name: 'amount', type: 'uint256' }, - { internalType: 'uint256', name: 'rewardDebt', type: 'uint256' }, - ], - stateMutability: 'view', - type: 'function', - }, } as const -const SDEX: Token = { - chain: 'ethereum', - address: '0x5DE8ab7E27f6E7A1fFf3E5B337584Aa43961BEeF', - decimals: 18, - symbol: 'SDEX', -} - -export async function getSmarDexFarmBalances( +export async function getUserInfosSDEX( ctx: BalancesContext, - pairs: Pair[], - masterchef: Contract, -): Promise { - const poolsBalances: Balance[] = [] - const masterchefPools: Contract[] = await getMasterChefPoolsInfos(ctx, pairs, masterchef) - - const calls: Call[] = masterchefPools.map((pool) => ({ - target: masterchef.address, - params: [pool.pid, ctx.address], - })) - - const [poolsBalancesRes, pendingRewardsRes] = await Promise.all([ - multicall({ ctx, calls, abi: abi.userInfo }), - multicall({ ctx, calls, abi: abi.pendingReward }), - ]) - - for (let userIdx = 0; userIdx < poolsBalancesRes.length; userIdx++) { - const masterchefPool = masterchefPools[userIdx] - const poolBalanceRes = poolsBalancesRes[userIdx] - const pendingRewardRes = pendingRewardsRes[userIdx] - - if (!poolBalanceRes.success || !pendingRewardRes.success) { - continue - } - - const [amount] = poolBalanceRes.output - - poolsBalances.push({ - ...masterchefPool, - underlyings: masterchefPool.underlyings as Contract[], - category: 'farm', - amount: amount, - rewards: [{ ...SDEX, amount: pendingRewardRes.output }], - }) - } - - return getUnderlyingBalances(ctx, poolsBalances) -} - -const getMasterChefPoolsInfos = async (ctx: BaseContext, pairs: Pair[], masterchef: Contract): Promise => { - const pairByAddress = keyBy(pairs, 'address', { lowercase: true }) - - const poolLengthRes = await call({ + { masterChefAddress, pools, getUserBalance }: GetUsersInfosParams, +) { + const poolsInfos = await multicall({ ctx, - target: masterchef.address, - abi: abi.campaignInfoLen, + calls: pools.map((pool) => ({ target: masterChefAddress, params: [pool.pid, ctx.address] }) as const), + abi: abi.userInfo, }) - const poolInfosRes = await multicall({ - ctx, - calls: rangeBI(0n, poolLengthRes).map((idx) => ({ target: masterchef.address, params: [idx] }) as const), - abi: abi.campaignInfo, - }) + return mapSuccessFilter(poolsInfos, (res: any, index) => { + const pool = pools[index] + const underlyings = pool.underlyings as Contract[] + const rewards = pool.rewards as Contract[] + const userBalance = Array.isArray(res.output) ? getUserBalance!({ userBalance: res.output }) : res.output - const pools: Contract[] = mapSuccessFilter(poolInfosRes, (res) => { - const [stakingToken] = res.output return { - chain: ctx.chain, - address: stakingToken, - lpToken: stakingToken, - pid: res.input.params[0], + ...pool, + amount: userBalance, + underlyings, + rewards, + category: 'farm', } }) +} - const masterchefPools: Contract[] = pools - .map((pool: Contract) => { - const pair = pairByAddress[pool.lpToken.toLowerCase()] - - if (!pair) { - return null - } - - const contract: Contract = { ...pair, pid: pool.pid, category: 'farm' } +export async function getUserPendingSDEX( + ctx: BalancesContext, + { masterChefAddress, pools, rewardToken }: GetUsersInfosParams, +) { + const userPendingRewards = await multicall({ + ctx, + calls: pools.map((pool) => ({ target: masterChefAddress, params: [pool.pid, ctx.address] }) as const), + abi: abi.pendingReward, + }) - return contract - }) - .filter(isNotNullish) + return mapSuccessFilter(userPendingRewards, (res: any, index) => { + const pool = pools[index] + const reward = rewardToken || (pool.rewards?.[0] as Contract) - return masterchefPools + return [{ ...reward, amount: res.output }] + }) } diff --git a/src/adapters/smardex/ethereum/index.ts b/src/adapters/smardex/ethereum/index.ts index 4e3d1ef4b..0e0653779 100644 --- a/src/adapters/smardex/ethereum/index.ts +++ b/src/adapters/smardex/ethereum/index.ts @@ -1,18 +1,34 @@ -import type { BalancesContext, BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' +import { getSmardexMasterChefPoolsContracts } from '@adapters/smardex/ethereum/pool' +import { getUserPendingSDEX } from '@adapters/smardex/ethereum/reward' +import { getSmarDexStakeBalances } from '@adapters/smardex/ethereum/stake' +import type { BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' import { resolveBalances } from '@lib/balance' -import type { Pair } from '@lib/uniswap/v2/factory' +import { getMasterChefPoolsBalances } from '@lib/masterchef/masterChefBalance' import { getPairsContracts } from '@lib/uniswap/v2/factory' import { getPairsBalances } from '@lib/uniswap/v2/pair' -import { getSmarDexFarmBalances } from './farm' -import { getSmarDexStakeBalances } from './stake' +const stakers: Contract[] = [ + { + chain: 'ethereum', + address: '0xB940D63c2deD1184BbdE059AcC7fEE93654F02bf', + underlyings: ['0x5DE8ab7E27f6E7A1fFf3E5B337584Aa43961BEeF'], + decimals: 18, + symbol: 'stSDEX', + }, + { + chain: 'ethereum', + address: '0x80497049b005fd236591c3cd431dbd6e06eb1a31', + underlyings: ['0x5DE8ab7E27f6E7A1fFf3E5B337584Aa43961BEeF'], + decimals: 18, + symbol: 'stSDEX', + }, +] -const staker: Contract = { +const SDEX: Contract = { chain: 'ethereum', - address: '0xB940D63c2deD1184BbdE059AcC7fEE93654F02bf', - underlyings: ['0x5DE8ab7E27f6E7A1fFf3E5B337584Aa43961BEeF'], + address: '0x5DE8ab7E27f6E7A1fFf3E5B337584Aa43961BEeF', decimals: 18, - symbol: 'stSDEX', + symbol: 'SDEX', } const masterChef: Contract = { @@ -20,22 +36,32 @@ const masterChef: Contract = { address: '0xe74A7a544534DA80fBaC4d2475a6fDc03388154f', } +const masterChef2: Contract = { + chain: 'ethereum', + address: '0x7d85c0905a6e1ab5837a0b57cd94a419d3a77523', +} + export const getContracts = async (ctx: BaseContext, props: any) => { const offset = props.pairOffset || 0 const limit = 100 - const { pairs, allPairsLength } = await getPairsContracts({ - ctx, - factoryAddress: '0x7753F36E711B66a0350a753aba9F5651BAE76A1D', - offset, - limit, - }) + const [pools, pools2, { pairs, allPairsLength }] = await Promise.all([ + getSmardexMasterChefPoolsContracts(ctx, masterChef), + getSmardexMasterChefPoolsContracts(ctx, masterChef2), + getPairsContracts({ + ctx, + factoryAddress: '0x7753F36E711B66a0350a753aba9F5651BAE76A1D', + offset, + limit, + }), + ]) return { contracts: { - masterChef, + pools, + pools2, pairs, - staker, + stakers, }, revalidate: 60 * 60, revalidateProps: { @@ -44,14 +70,22 @@ export const getContracts = async (ctx: BaseContext, props: any) => { } } -const getSmarDexBalances = async (ctx: BalancesContext, pairs: Pair[], masterChef: Contract) => { - return Promise.all([getPairsBalances(ctx, pairs), getSmarDexFarmBalances(ctx, pairs, masterChef)]) -} - export const getBalances: GetBalancesHandler = async (ctx, contracts) => { const balances = await resolveBalances(ctx, contracts, { - pairs: (...args) => getSmarDexBalances(...args, masterChef), - staker: getSmarDexStakeBalances, + stakers: getSmarDexStakeBalances, + pairs: getPairsBalances, + pools: (...args) => + getMasterChefPoolsBalances(...args, { + masterChefAddress: masterChef.address, + rewardToken: SDEX, + getUserPendingRewards: (...args) => getUserPendingSDEX(...args), + }), + pools2: (...args) => + getMasterChefPoolsBalances(...args, { + masterChefAddress: masterChef2.address, + rewardToken: SDEX, + getUserPendingRewards: (...args) => getUserPendingSDEX(...args), + }), }) return { diff --git a/src/adapters/smardex/ethereum/pool.ts b/src/adapters/smardex/ethereum/pool.ts new file mode 100644 index 000000000..62c7d903f --- /dev/null +++ b/src/adapters/smardex/ethereum/pool.ts @@ -0,0 +1,59 @@ +import type { BaseContext, Contract } from '@lib/adapter' +import { mapSuccessFilter, rangeBI } from '@lib/array' +import { call } from '@lib/call' +import { getMasterChefPoolsContracts, type GetPoolsInfosParams } from '@lib/masterchef/masterChefContract' +import { multicall } from '@lib/multicall' + +const abi = { + campaignInfo: { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'campaignInfo', + outputs: [ + { internalType: 'contract IERC20', name: 'stakingToken', type: 'address' }, + { internalType: 'contract IERC20', name: 'rewardToken', type: 'address' }, + { internalType: 'uint256', name: 'startBlock', type: 'uint256' }, + { internalType: 'uint256', name: 'lastRewardBlock', type: 'uint256' }, + { internalType: 'uint256', name: 'accRewardPerShare', type: 'uint256' }, + { internalType: 'uint256', name: 'totalStaked', type: 'uint256' }, + { internalType: 'uint256', name: 'totalRewards', type: 'uint256' }, + ], + stateMutability: 'view', + type: 'function', + }, + campaignInfoLen: { + inputs: [], + name: 'campaignInfoLen', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +} as const + +export async function getSmardexMasterChefPoolsContracts(ctx: BaseContext, masterChef: Contract): Promise { + return getMasterChefPoolsContracts(ctx, { + masterChefAddress: masterChef.address, + getAllPoolLength: (...args) => getAllPoolLength(...args), + getPoolInfos: (...args) => getPoolInfos(...args), + }) +} + +async function getAllPoolLength(ctx: BaseContext, masterChefAddress: `0x${string}`) { + return call({ ctx, target: masterChefAddress, abi: abi.campaignInfoLen }) +} + +export async function getPoolInfos( + ctx: BaseContext, + { masterChefAddress, poolLength, getLpToken }: GetPoolsInfosParams, +) { + const poolInfos = await multicall({ + ctx, + calls: rangeBI(0n, poolLength).map((idx) => ({ target: masterChefAddress, params: [idx] }) as const), + abi: abi.campaignInfo, + }) + + return mapSuccessFilter(poolInfos, (res) => { + const lpToken = Array.isArray(res.output) ? getLpToken!({ lpToken: res.output }) : res.output + + return { chain: ctx.chain, address: lpToken, pid: res.input.params![0] } + }) +} diff --git a/src/adapters/smardex/ethereum/reward.ts b/src/adapters/smardex/ethereum/reward.ts new file mode 100644 index 000000000..cd60f524d --- /dev/null +++ b/src/adapters/smardex/ethereum/reward.ts @@ -0,0 +1,35 @@ +import type { BalancesContext, Contract } from '@lib/adapter' +import { mapSuccessFilter } from '@lib/array' +import type { GetUsersInfosParams } from '@lib/masterchef/masterChefBalance' +import { multicall } from '@lib/multicall' + +const abi = { + pendingReward: { + inputs: [ + { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, + { internalType: 'address', name: '_user', type: 'address' }, + ], + name: 'pendingReward', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +} as const + +export async function getUserPendingSDEX( + ctx: BalancesContext, + { masterChefAddress, pools, rewardToken }: GetUsersInfosParams, +) { + const userPendingRewards = await multicall({ + ctx, + calls: pools.map((pool) => ({ target: masterChefAddress, params: [pool.pid, ctx.address] }) as const), + abi: abi.pendingReward, + }) + + return mapSuccessFilter(userPendingRewards, (res: any, index) => { + const pool = pools[index] + const reward = rewardToken || (pool.rewards?.[0] as Contract) + + return [{ ...reward, amount: res.output }] + }) +} diff --git a/src/adapters/smardex/ethereum/stake.ts b/src/adapters/smardex/ethereum/stake.ts index b849da0e2..32cb764b5 100644 --- a/src/adapters/smardex/ethereum/stake.ts +++ b/src/adapters/smardex/ethereum/stake.ts @@ -1,5 +1,6 @@ import type { Balance, BalancesContext, Contract } from '@lib/adapter' -import { call } from '@lib/call' +import { mapSuccessFilter } from '@lib/array' +import { multicall } from '@lib/multicall' import type { Token } from '@lib/token' const abi = { @@ -29,28 +30,28 @@ const SDEX: Token = { symbol: 'SDEX', } -export async function getSmarDexStakeBalances(ctx: BalancesContext, staker: Contract): Promise { - const userInfo = await call({ +export async function getSmarDexStakeBalances(ctx: BalancesContext, stakers: Contract[]): Promise { + const userInfosRes = await multicall({ ctx, - target: staker.address, - params: [ctx.address], + calls: stakers.map((staker) => ({ target: staker.address, params: [ctx.address] }) as const), abi: abi.userInfo, }) - const [shares, _lastBlockUpdate] = userInfo - - const sharesToTokens = await call({ + const sharesToTokens = await multicall({ ctx, - target: staker.address, - params: [shares], + calls: mapSuccessFilter(userInfosRes, (res) => ({ target: res.input.target, params: [res.output[0]] }) as const), abi: abi.sharesToTokens, }) - return { - ...staker, - amount: sharesToTokens, - underlyings: [SDEX], - rewards: undefined, - category: 'stake', - } + return mapSuccessFilter(sharesToTokens, (res, index) => { + const staker = stakers[index] + + return { + ...staker, + amount: res.output, + underlyings: [SDEX], + rewards: undefined, + category: 'stake', + } + }) } From aa96ebaba67b4b8b6851b06aefe58c65fd665910 Mon Sep 17 00:00:00 2001 From: 0xPeluche <0xpeluche@proton.me> Date: Thu, 16 Nov 2023 19:27:13 +0100 Subject: [PATCH 2/3] Update, Smardex bsc polygon base arbitrum --- src/adapters/smardex/arbitrum/index.ts | 61 +++++++++++++++++++ src/adapters/smardex/base/index.ts | 61 +++++++++++++++++++ src/adapters/smardex/bsc/index.ts | 61 +++++++++++++++++++ .../smardex/{ethereum => common}/farm.ts | 0 .../smardex/{ethereum => common}/pool.ts | 0 src/adapters/smardex/ethereum/index.ts | 4 +- src/adapters/smardex/ethereum/reward.ts | 35 ----------- src/adapters/smardex/index.ts | 8 +++ src/adapters/smardex/polygon/index.ts | 61 +++++++++++++++++++ 9 files changed, 254 insertions(+), 37 deletions(-) create mode 100644 src/adapters/smardex/arbitrum/index.ts create mode 100644 src/adapters/smardex/base/index.ts create mode 100644 src/adapters/smardex/bsc/index.ts rename src/adapters/smardex/{ethereum => common}/farm.ts (100%) rename src/adapters/smardex/{ethereum => common}/pool.ts (100%) delete mode 100644 src/adapters/smardex/ethereum/reward.ts create mode 100644 src/adapters/smardex/polygon/index.ts diff --git a/src/adapters/smardex/arbitrum/index.ts b/src/adapters/smardex/arbitrum/index.ts new file mode 100644 index 000000000..d0aac3f59 --- /dev/null +++ b/src/adapters/smardex/arbitrum/index.ts @@ -0,0 +1,61 @@ +import { getUserPendingSDEX } from '@adapters/smardex/common/farm' +import { getSmardexMasterChefPoolsContracts } from '@adapters/smardex/common/pool' +import type { BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' +import { resolveBalances } from '@lib/balance' +import { getMasterChefPoolsBalances } from '@lib/masterchef/masterChefBalance' +import { getPairsContracts } from '@lib/uniswap/v2/factory' +import { getPairsBalances } from '@lib/uniswap/v2/pair' + +const SDEX: Contract = { + chain: 'arbitrum', + address: '0xabd587f2607542723b17f14d00d99b987c29b074', + decimals: 18, + symbol: 'SDEX', +} + +const masterChef: Contract = { + chain: 'arbitrum', + address: '0x53D165DF0414bD02E91747775450934BF2257f69', +} + +export const getContracts = async (ctx: BaseContext, props: any) => { + const offset = props.pairOffset || 0 + const limit = 100 + + const [pools, { pairs, allPairsLength }] = await Promise.all([ + getSmardexMasterChefPoolsContracts(ctx, masterChef), + getPairsContracts({ + ctx, + factoryAddress: '0x41A00e3FbE7F479A99bA6822704d9c5dEB611F22', + offset, + limit, + }), + ]) + + return { + contracts: { + pools, + pairs, + }, + revalidate: 60 * 60, + revalidateProps: { + pairOffset: Math.min(offset + limit, allPairsLength), + }, + } +} + +export const getBalances: GetBalancesHandler = async (ctx, contracts) => { + const balances = await resolveBalances(ctx, contracts, { + pairs: getPairsBalances, + pools: (...args) => + getMasterChefPoolsBalances(...args, { + masterChefAddress: masterChef.address, + rewardToken: SDEX, + getUserPendingRewards: (...args) => getUserPendingSDEX(...args), + }), + }) + + return { + groups: [{ balances }], + } +} diff --git a/src/adapters/smardex/base/index.ts b/src/adapters/smardex/base/index.ts new file mode 100644 index 000000000..7a40b47ae --- /dev/null +++ b/src/adapters/smardex/base/index.ts @@ -0,0 +1,61 @@ +import { getUserPendingSDEX } from '@adapters/smardex/common/farm' +import { getSmardexMasterChefPoolsContracts } from '@adapters/smardex/common/pool' +import type { BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' +import { resolveBalances } from '@lib/balance' +import { getMasterChefPoolsBalances } from '@lib/masterchef/masterChefBalance' +import { getPairsContracts } from '@lib/uniswap/v2/factory' +import { getPairsBalances } from '@lib/uniswap/v2/pair' + +const SDEX: Contract = { + chain: 'base', + address: '0xFd4330b0312fdEEC6d4225075b82E00493FF2e3f', + decimals: 18, + symbol: 'SDEX', +} + +const masterChef: Contract = { + chain: 'base', + address: '0xa5D378c05192E3f1F365D6298921879C4D51c5a3', +} + +export const getContracts = async (ctx: BaseContext, props: any) => { + const offset = props.pairOffset || 0 + const limit = 100 + + const [pools, { pairs, allPairsLength }] = await Promise.all([ + getSmardexMasterChefPoolsContracts(ctx, masterChef), + getPairsContracts({ + ctx, + factoryAddress: '0xdd4536dD9636564D891c919416880a3e250f975A', + offset, + limit, + }), + ]) + + return { + contracts: { + pools, + pairs, + }, + revalidate: 60 * 60, + revalidateProps: { + pairOffset: Math.min(offset + limit, allPairsLength), + }, + } +} + +export const getBalances: GetBalancesHandler = async (ctx, contracts) => { + const balances = await resolveBalances(ctx, contracts, { + pairs: getPairsBalances, + pools: (...args) => + getMasterChefPoolsBalances(...args, { + masterChefAddress: masterChef.address, + rewardToken: SDEX, + getUserPendingRewards: (...args) => getUserPendingSDEX(...args), + }), + }) + + return { + groups: [{ balances }], + } +} diff --git a/src/adapters/smardex/bsc/index.ts b/src/adapters/smardex/bsc/index.ts new file mode 100644 index 000000000..d6a4fd9a9 --- /dev/null +++ b/src/adapters/smardex/bsc/index.ts @@ -0,0 +1,61 @@ +import { getUserPendingSDEX } from '@adapters/smardex/common/farm' +import { getSmardexMasterChefPoolsContracts } from '@adapters/smardex/common/pool' +import type { BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' +import { resolveBalances } from '@lib/balance' +import { getMasterChefPoolsBalances } from '@lib/masterchef/masterChefBalance' +import { getPairsContracts } from '@lib/uniswap/v2/factory' +import { getPairsBalances } from '@lib/uniswap/v2/pair' + +const SDEX: Contract = { + chain: 'bsc', + address: '0xFdc66A08B0d0Dc44c17bbd471B88f49F50CdD20F', + decimals: 18, + symbol: 'SDEX', +} + +const masterChef: Contract = { + chain: 'bsc', + address: '0xb891Aeb2130805171796644a2af76Fc7Ff25a0b9', +} + +export const getContracts = async (ctx: BaseContext, props: any) => { + const offset = props.pairOffset || 0 + const limit = 100 + + const [pools, { pairs, allPairsLength }] = await Promise.all([ + getSmardexMasterChefPoolsContracts(ctx, masterChef), + getPairsContracts({ + ctx, + factoryAddress: '0xA8EF6FEa013034E62E2C4A9Ec1CDb059fE23Af33', + offset, + limit, + }), + ]) + + return { + contracts: { + pools, + pairs, + }, + revalidate: 60 * 60, + revalidateProps: { + pairOffset: Math.min(offset + limit, allPairsLength), + }, + } +} + +export const getBalances: GetBalancesHandler = async (ctx, contracts) => { + const balances = await resolveBalances(ctx, contracts, { + pairs: getPairsBalances, + pools: (...args) => + getMasterChefPoolsBalances(...args, { + masterChefAddress: masterChef.address, + rewardToken: SDEX, + getUserPendingRewards: (...args) => getUserPendingSDEX(...args), + }), + }) + + return { + groups: [{ balances }], + } +} diff --git a/src/adapters/smardex/ethereum/farm.ts b/src/adapters/smardex/common/farm.ts similarity index 100% rename from src/adapters/smardex/ethereum/farm.ts rename to src/adapters/smardex/common/farm.ts diff --git a/src/adapters/smardex/ethereum/pool.ts b/src/adapters/smardex/common/pool.ts similarity index 100% rename from src/adapters/smardex/ethereum/pool.ts rename to src/adapters/smardex/common/pool.ts diff --git a/src/adapters/smardex/ethereum/index.ts b/src/adapters/smardex/ethereum/index.ts index 0e0653779..95ae15791 100644 --- a/src/adapters/smardex/ethereum/index.ts +++ b/src/adapters/smardex/ethereum/index.ts @@ -1,5 +1,5 @@ -import { getSmardexMasterChefPoolsContracts } from '@adapters/smardex/ethereum/pool' -import { getUserPendingSDEX } from '@adapters/smardex/ethereum/reward' +import { getUserPendingSDEX } from '@adapters/smardex/common/farm' +import { getSmardexMasterChefPoolsContracts } from '@adapters/smardex/common/pool' import { getSmarDexStakeBalances } from '@adapters/smardex/ethereum/stake' import type { BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' import { resolveBalances } from '@lib/balance' diff --git a/src/adapters/smardex/ethereum/reward.ts b/src/adapters/smardex/ethereum/reward.ts deleted file mode 100644 index cd60f524d..000000000 --- a/src/adapters/smardex/ethereum/reward.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { BalancesContext, Contract } from '@lib/adapter' -import { mapSuccessFilter } from '@lib/array' -import type { GetUsersInfosParams } from '@lib/masterchef/masterChefBalance' -import { multicall } from '@lib/multicall' - -const abi = { - pendingReward: { - inputs: [ - { internalType: 'uint256', name: '_campaignID', type: 'uint256' }, - { internalType: 'address', name: '_user', type: 'address' }, - ], - name: 'pendingReward', - outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - stateMutability: 'view', - type: 'function', - }, -} as const - -export async function getUserPendingSDEX( - ctx: BalancesContext, - { masterChefAddress, pools, rewardToken }: GetUsersInfosParams, -) { - const userPendingRewards = await multicall({ - ctx, - calls: pools.map((pool) => ({ target: masterChefAddress, params: [pool.pid, ctx.address] }) as const), - abi: abi.pendingReward, - }) - - return mapSuccessFilter(userPendingRewards, (res: any, index) => { - const pool = pools[index] - const reward = rewardToken || (pool.rewards?.[0] as Contract) - - return [{ ...reward, amount: res.output }] - }) -} diff --git a/src/adapters/smardex/index.ts b/src/adapters/smardex/index.ts index 06b753e92..1954bd56b 100644 --- a/src/adapters/smardex/index.ts +++ b/src/adapters/smardex/index.ts @@ -1,10 +1,18 @@ import type { Adapter } from '@lib/adapter' +import * as arbitrum from './arbitrum' +import * as base from './base' +import * as bsc from './bsc' import * as ethereum from './ethereum' +import * as polygon from './polygon' const adapter: Adapter = { id: 'smardex', ethereum, + arbitrum, + bsc, + polygon, + base, } export default adapter diff --git a/src/adapters/smardex/polygon/index.ts b/src/adapters/smardex/polygon/index.ts new file mode 100644 index 000000000..7abdcfa97 --- /dev/null +++ b/src/adapters/smardex/polygon/index.ts @@ -0,0 +1,61 @@ +import { getUserPendingSDEX } from '@adapters/smardex/common/farm' +import { getSmardexMasterChefPoolsContracts } from '@adapters/smardex/common/pool' +import type { BaseContext, Contract, GetBalancesHandler } from '@lib/adapter' +import { resolveBalances } from '@lib/balance' +import { getMasterChefPoolsBalances } from '@lib/masterchef/masterChefBalance' +import { getPairsContracts } from '@lib/uniswap/v2/factory' +import { getPairsBalances } from '@lib/uniswap/v2/pair' + +const SDEX: Contract = { + chain: 'bsc', + address: '0x6899fAcE15c14348E1759371049ab64A3a06bFA6', + decimals: 18, + symbol: 'SDEX', +} + +const masterChef: Contract = { + chain: 'bsc', + address: '0x7DB73A1e526db36c40e508b09428420c1fA8e46b', +} + +export const getContracts = async (ctx: BaseContext, props: any) => { + const offset = props.pairOffset || 0 + const limit = 100 + + const [pools, { pairs, allPairsLength }] = await Promise.all([ + getSmardexMasterChefPoolsContracts(ctx, masterChef), + getPairsContracts({ + ctx, + factoryAddress: '0x9A1e1681f6D59Ca051776410465AfAda6384398f', + offset, + limit, + }), + ]) + + return { + contracts: { + pools, + pairs, + }, + revalidate: 60 * 60, + revalidateProps: { + pairOffset: Math.min(offset + limit, allPairsLength), + }, + } +} + +export const getBalances: GetBalancesHandler = async (ctx, contracts) => { + const balances = await resolveBalances(ctx, contracts, { + pairs: getPairsBalances, + pools: (...args) => + getMasterChefPoolsBalances(...args, { + masterChefAddress: masterChef.address, + rewardToken: SDEX, + getUserPendingRewards: (...args) => getUserPendingSDEX(...args), + }), + }) + + return { + groups: [{ balances }], + } +} From 33363ef492cbfd0b747389e8748cb12b2ac6f366 Mon Sep 17 00:00:00 2001 From: 0xPeluche <0xpeluche@proton.me> Date: Thu, 16 Nov 2023 19:30:16 +0100 Subject: [PATCH 3/3] fix polygon --- src/adapters/smardex/polygon/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/adapters/smardex/polygon/index.ts b/src/adapters/smardex/polygon/index.ts index 7abdcfa97..f59cc174e 100644 --- a/src/adapters/smardex/polygon/index.ts +++ b/src/adapters/smardex/polygon/index.ts @@ -7,14 +7,14 @@ import { getPairsContracts } from '@lib/uniswap/v2/factory' import { getPairsBalances } from '@lib/uniswap/v2/pair' const SDEX: Contract = { - chain: 'bsc', + chain: 'polygon', address: '0x6899fAcE15c14348E1759371049ab64A3a06bFA6', decimals: 18, symbol: 'SDEX', } const masterChef: Contract = { - chain: 'bsc', + chain: 'polygon', address: '0x7DB73A1e526db36c40e508b09428420c1fA8e46b', }