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

Integrate kn-protocol FarmV2 #2221

Merged
merged 16 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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
53 changes: 26 additions & 27 deletions .env.adpr
Original file line number Diff line number Diff line change
@@ -1,45 +1,44 @@
VITE_AGGREGATOR_API=https://aggregator-api.dev.kyberengineering.io
VITE_AGGREGATOR_STATS_API=https://aggregator-stats.dev.kyberengineering.io
viet-nv marked this conversation as resolved.
Show resolved Hide resolved
VITE_AGGREGATOR_API=https://aggregator-api.kyberswap.com
VITE_AGGREGATOR_STATS_API=https://aggregator-stats.kyberswap.com
VITE_SENTRY_DNS=https://d94ee2d3c22043bdaec966758680b5a8@sentry.ops.kyberengineering.io/4

VITE_SERVICE_WORKER=true
VITE_SERVICE_WORKER=false

VITE_MIXPANEL_PROJECT_TOKEN=fca28a30cb98d872c2079f214955cd5e
VITE_REWARD_SERVICE_API=https://reward.dev.kyberengineering.io/api/v1
VITE_MIXPANEL_PROJECT_TOKEN=ff1eea26c19dcf4a7c35ebbc8631e714
VITE_REWARD_SERVICE_API=https://rewards.kyberswap.com/api/v1

VITE_PRICE_CHART_API=https://price-chart.dev.kyberengineering.io/api
VITE_PRICE_API=https://price.dev.kyberengineering.io
VITE_PRICE_CHART_API=https://price-chart.kyberswap.com/api
VITE_PRICE_API=https://price.kyberswap.com

VITE_NOTIFICATION_API=https://notification.dev.kyberengineering.io/api
VITE_NOTIFICATION_API=https://notification.kyberswap.com/api

VITE_CAMPAIGN_BASE_URL=https://campaigns.dev.kyberengineering.io
VITE_TYPE_AND_SWAP_URL=https://type-swap.dev.kyberengineering.io/api
VITE_CAMPAIGN_BASE_URL=https://campaigns.kyberswap.com
VITE_TYPE_AND_SWAP_URL=https://type-swap.kyberswap.com/api

VITE_TRANSAK_URL=https://staging-global.transak.com
VITE_TRANSAK_API_KEY=327b8b63-626b-4376-baf2-70a304c48488
VITE_TRANSAK_URL=https://global.transak.com
VITE_TRANSAK_API_KEY=48949c0b-2d20-4e3a-a311-51ca91ae8c0d

VITE_KS_SETTING_API=https://ks-setting.dev.kyberengineering.io/api
VITE_KS_SETTING_API=https://ks-setting.kyberswap.com/api

VITE_GTM_ID=
VITE_GTM_ID=GTM-TRQCJ8F

VITE_GOOGLE_RECAPTCHA_KEY=6Lc7yg0iAAAAALhS4C4Ez5hqMBub8hKdFvvr9sfc
VITE_POOL_FARM_BASE_URL=https://pool-farm.dev.kyberengineering.io
VITE_GOOGLE_RECAPTCHA_KEY=6LfgKRMiAAAAAPDTmXAM9LZLYAlE1zACfCJXup96
VITE_POOL_FARM_BASE_URL=https://pool-farm.kyberswap.com

VITE_LIMIT_ORDER_API_WRITE=https://limit-order.dev.kyberengineering.io/write/api
VITE_LIMIT_ORDER_API_READ=https://limit-order.dev.kyberengineering.io/read-ks/api
VITE_LIMIT_ORDER_API_WRITE=https://limit-order.kyberswap.com/write/api
VITE_LIMIT_ORDER_API_READ=https://limit-order.kyberswap.com/read-ks/api
VITE_BLOCK_SERVICE_API=https://block.kyberswap.com

# Kyber DAO Apis
VITE_KYBER_DAO_STATS_API=https://kyberswap-dao-stats.dev.kyberengineering.io
VITE_KYBER_DAO_STATS_API=https://kyberswap-dao-stats.kyberengineering.io

# oauth
VITE_ENV=development
VITE_OAUTH_CLIENT_ID=a2f76ad4-895f-401a-ba75-952a929d782c

VITE_BFF_API=https://kyberswap-bff.dev.kyberengineering.io/api
VITE_ENV=production
VITE_OAUTH_CLIENT_ID=8a95ced8-1530-45d0-bc15-a5614d1d8d08
VITE_KYBER_AI_REFERRAL_ID=1
VITE_KYBER_AI_TOPIC_ID=14
VITE_PRICE_ALERT_TOPIC_ID=13
VITE_ELASTIC_POOL_TOPIC_ID=12
VITE_BUCKET_NAME=ks-setting-a3aa20b7
VITE_KYBER_AI_TOPIC_ID=9
VITE_PRICE_ALERT_TOPIC_ID=8
VITE_ELASTIC_POOL_TOPIC_ID=7
VITE_BFF_API=https://bff.kyberswap.com/api
VITE_BUCKET_NAME=ks-setting-1d682dca
VITE_WALLETCONNECT_PROJECT_ID=f218207428d6efc3863adab795a9f123
34 changes: 19 additions & 15 deletions src/constants/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,25 @@ export function isSupportedChainId(chainId?: number): chainId is ChainId {
}

export const FAUCET_NETWORKS = [ChainId.BTTC]
export const CHAINS_SUPPORT_NEW_POOL_FARM_API: readonly ChainId[] = [
ChainId.MAINNET,
// ChainId.MUMBAI,
// ChainId.MATIC,
// ChainId.BSCTESTNET,
ChainId.BSCMAINNET,
// ChainId.AVAXTESTNET,
ChainId.AVAXMAINNET,
ChainId.FANTOM,
ChainId.CRONOS,
ChainId.BTTC,
ChainId.ARBITRUM,
ChainId.AURORA,
ChainId.OPTIMISM,
]

// TODO(viet-nv): Base on this to config ks-setting when release then remove
// export const CHAINS_SUPPORT_NEW_POOL_FARM_API: readonly ChainId[] = [
// ChainId.MAINNET,
// // ChainId.MUMBAI,
// // ChainId.MATIC,
// // ChainId.BSCTESTNET,
// ChainId.BSCMAINNET,
// // ChainId.AVAXTESTNET,
// ChainId.AVAXMAINNET,
// ChainId.FANTOM,
// ChainId.CRONOS,
// ChainId.BTTC,
// ChainId.ARBITRUM,
// ChainId.AURORA,
// // ChainId.VELAS,
// // ChainId.OASIS,
// ChainId.OPTIMISM,
// ]

// Fee options instead of dynamic fee
export const STATIC_FEE_OPTIONS: { [chainId: number]: number[] | undefined } = {
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useKyberSwapConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ const parseResponse = (

return {
rpc,
prochart: data?.prochart || false,
isEnableBlockService: data?.isEnableBlockService || false,
isEnableKNProtocol: data?.isEnableKNProtocol || false,
blockClient: isEVM(defaultChainId)
? createClient(data?.blockSubgraph || NETWORKS_INFO[defaultChainId].defaultBlockSubgraph)
: createClient(ethereumInfo.defaultBlockSubgraph),
Expand Down
31 changes: 3 additions & 28 deletions src/pages/Farm/ElasticFarmv2/components/FarmCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -262,34 +262,9 @@ function FarmCard({
</RowBetween>

<RowBetween>
<MouseoverTooltip
placement="bottom"
width="fit-content"
text={
farm.tvl ? (
<>
<Flex alignItems="center" sx={{ gap: '4px' }}>
<CurrencyLogo currency={farm.token0} size="16px" />
{farm.tvlToken0.toSignificant(6)} {farm.token0.symbol}
</Flex>

<Flex alignItems="center" sx={{ gap: '4px' }} marginTop="4px">
<CurrencyLogo currency={farm.token1} size="16px" />
{farm.tvlToken1.toSignificant(6)} {farm.token1.symbol}
</Flex>
</>
) : (
''
)
}
>
<Text fontSize="16px" fontWeight="500" color={theme.text} data-testid="tvl-value">
{farm.tvl ? formatDollarAmount(farm.tvl) : '--'}
</Text>

{!!farm.tvl && <DownSvg />}
</MouseoverTooltip>

<Text fontSize="16px" fontWeight="500" color={theme.text} data-testid="tvl-value">
{farm.tvl ? formatDollarAmount(farm.tvl) : '--'}
</Text>
<Text fontSize="14px" fontWeight="500" color={theme.text}>
{isEnded || farm.isSettled ? (
isEnded ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { ButtonOutlined } from 'components/Button'
import CurrencyLogo from 'components/CurrencyLogo'
import { MouseoverTooltip } from 'components/Tooltip'
import PROMM_FARM_ABI from 'constants/abis/v2/farm.json'
import FarmV2ABI from 'constants/abis/v2/farmv2.json'
import { useActiveWeb3React, useWeb3React } from 'hooks'
import { useProAmmNFTPositionManagerContract } from 'hooks/useContract'
import { config } from 'hooks/useElasticLegacy'
Expand All @@ -31,6 +32,7 @@ import { formatDollarAmount } from 'utils/numbers'

type Props = {
nftId: string
fId: string
feeValue0: CurrencyAmount<Currency>
feeValue1: CurrencyAmount<Currency>
feeUsd: number
Expand All @@ -43,9 +45,11 @@ type Props = {
}

const FarmInterface = new Interface(PROMM_FARM_ABI)
const FarmV2Interface = new Interface(FarmV2ABI)

const CollectFeesPanel: React.FC<Props> = ({
nftId,
fId,
chainId,
feeUsd,
feeValue0,
Expand Down Expand Up @@ -131,6 +135,7 @@ const CollectFeesPanel: React.FC<Props> = ({
}

const collectFeeFromFarmContract = async () => {
console.log(farmAddress, feeValue0, feeValue1)
viet-nv marked this conversation as resolved.
Show resolved Hide resolved
if (!farmAddress || !feeValue0 || !feeValue1) {
dispatch(setAttemptingTxn(false))
dispatch(setTxError('Something went wrong!'))
Expand All @@ -140,14 +145,19 @@ const CollectFeesPanel: React.FC<Props> = ({
const amount0Min = feeValue0.subtract(feeValue0.multiply(basisPointsToPercent(allowedSlippage)))
const amount1Min = feeValue1.subtract(feeValue1.multiply(basisPointsToPercent(allowedSlippage)))
try {
const encoded = FarmInterface.encodeFunctionData('claimFee', [
[nftId],
amount0Min.quotient.toString(),
amount1Min.quotient.toString(),
poolAddress,
true,
deadline?.toString(),
])
const encoded = (fId ? FarmV2Interface : FarmInterface).encodeFunctionData(
'claimFee',
fId
? [fId, [nftId], amount0Min.quotient.toString(), amount1Min.quotient.toString(), deadline?.toString(), true]
: [
[nftId],
amount0Min.quotient.toString(),
amount1Min.quotient.toString(),
poolAddress,
true,
deadline?.toString(),
],
)

sendTransaction({
to: farmAddress,
Expand Down
53 changes: 43 additions & 10 deletions src/pages/MyEarnings/ElasticPools/SinglePosition/PositionView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Divider from 'components/Divider'
import FormattedCurrencyAmount from 'components/FormattedCurrencyAmount'
import { MouseoverTooltip } from 'components/Tooltip'
import PROMM_FARM_ABI from 'constants/abis/v2/farm.json'
import FarmV2ABI from 'constants/abis/v2/farmv2.json'
import { VERSION } from 'constants/v2'
import { useActiveWeb3React, useWeb3React } from 'hooks'
import { useAllTokens } from 'hooks/Tokens'
Expand All @@ -39,6 +40,7 @@ import { formatDisplayNumber } from 'utils/numbers'
import ActionButtons from './ActionButtons'

const FarmInterface = new Interface(PROMM_FARM_ABI)
const FarmV2Interface = new Interface(FarmV2ABI)

const PositionView: React.FC<CommonProps> = props => {
const { positionEarning, position, pendingFee, tokenPrices: prices, chainId, currency0, currency1 } = props
Expand Down Expand Up @@ -114,35 +116,61 @@ const PositionView: React.FC<CommonProps> = props => {
const theme = useTheme()
const tokens = useAllTokens(true, chainId)

const farmRewards = positionEarning.joinedPositions?.[0]?.farmingPool?.rewardTokensIds?.map((rwId, index) => {
const token = tokens[rwId] || new Token(chainId, rwId, 18, '', '')
let farmRewards =
positionEarning.joinedPositions?.[0]?.farmingPool?.rewardTokensIds?.map((rwId, index) => {
const token = tokens[rwId] || new Token(chainId, rwId, 18, '', '')

return CurrencyAmount.fromRawAmount(token, positionEarning.joinedPositions?.[0]?.pendingRewards?.[index] || '0')
})
return CurrencyAmount.fromRawAmount(token, positionEarning.joinedPositions?.[0]?.pendingRewards?.[index] || '0')
}) || []

const farmV2Rewards =
positionEarning.farmV2DepositedPositions?.[0].pendingRewards.map((amount, index) => {
const tokenId = positionEarning.farmV2DepositedPositions?.[0].farmV2.rewards[index].tokenID || ''
const token = tokens[tokenId] || new Token(chainId, tokenId, 18, '', '')

return CurrencyAmount.fromRawAmount(token, amount)
}) || []

farmRewards = farmRewards.concat(farmV2Rewards)

const disabledHarvest =
!positionEarning.joinedPositions?.[0]?.pendingRewards?.some(item => item !== '0') &&
!positionEarning.farmV2DepositedPositions?.[0].pendingRewards?.some(item => item !== '0')

const addTransactionWithType = useTransactionAdder()

const handleHarvest = () => {
const farmContract = positionEarning.joinedPositions?.[0]?.farmId
const farmContract =
positionEarning.joinedPositions?.[0]?.farmId ||
positionEarning.farmV2DepositedPositions?.[0].farmV2.id.split('_')[0]
const isInFarmV2 = !!positionEarning.farmV2DepositedPositions?.[0]
const pId = positionEarning.joinedPositions?.[0]?.pid
const fId = positionEarning?.farmV2DepositedPositions?.[0].farmV2.id.split('_')[1]

const library = libraryRef.current

dispatch(setShowPendingModal(MODAL_PENDING_TEXTS.HARVEST))
dispatch(setAttemptingTxn(true))

if (!library || !pId || !farmContract) {
if (!library || (isInFarmV2 ? !fId : !pId) || !farmContract) {
dispatch(setAttemptingTxn(false))
dispatch(setTxError('Something went wrong!'))
return
}

const encodedPid = defaultAbiCoder.encode(['tupple(uint256[] pIds)'], [{ pIds: [pId] }])
const encodedData = FarmInterface.encodeFunctionData('harvestMultiplePools', [[positionEarning.id], [encodedPid]])
let encodedData = ''
if (isInFarmV2) {
encodedData = FarmV2Interface.encodeFunctionData('claimReward', [fId, [positionEarning.id]])
} else {
const encodedPid = defaultAbiCoder.encode(['tupple(uint256[] pIds)'], [{ pIds: [pId] }])
encodedData = FarmInterface.encodeFunctionData('harvestMultiplePools', [[positionEarning.id], [encodedPid]])
}

const txn = {
to: farmContract,
data: encodedData,
}

library
.getSigner()
.estimateGas(txn)
Expand Down Expand Up @@ -253,12 +281,17 @@ const PositionView: React.FC<CommonProps> = props => {

<CollectFeesPanel
nftId={positionEarning.id}
fId={positionEarning?.farmV2DepositedPositions?.[0].farmV2.id.split('_')[1]}
chainId={chainId}
feeUsd={feeUsd}
feeValue0={feeReward0}
feeValue1={feeReward1}
hasUserDepositedInFarm={positionEarning.owner !== positionEarning.ownerOriginal}
farmAddress={positionEarning.depositedPosition?.farm || positionEarning.joinedPositions?.[0]?.farmId}
farmAddress={
positionEarning?.farmV2DepositedPositions?.[0].farmV2.id.split('_')[0] ||
positionEarning.depositedPosition?.farm ||
positionEarning.joinedPositions?.[0]?.farmId
}
poolAddress={positionEarning.pool.id}
position={position}
isLegacy={isLegacyPosition}
Expand Down Expand Up @@ -303,7 +336,7 @@ const PositionView: React.FC<CommonProps> = props => {
</Flex>

<ButtonOutlined
disabled={!positionEarning.joinedPositions?.[0]?.pendingRewards?.some(item => item !== '0')}
disabled={disabledHarvest}
style={{
height: '36px',
width: 'fit-content',
Expand Down
8 changes: 8 additions & 0 deletions src/services/earning/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ export type ElasticPositionEarningWithDetails = {
pendingRewardUSD: string[]
liquidity: string
}[]

farmV2DepositedPositions: {
farmV2: {
id: string
rewards: Array<{ amount: string; index: number; tokenID: string }>
}
pendingRewards: Array<string>
}[]
} & HistoricalEarning

export type ClassicPositionEarningWithDetails = {
Expand Down
24 changes: 24 additions & 0 deletions src/services/knprotocol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ChainId } from '@kyberswap/ks-sdk-core'
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

import { POOL_FARM_BASE_URL } from 'constants/env'
import { NETWORKS_INFO } from 'constants/networks'
import { EVMNetworkInfo } from 'constants/networks/type'
import { SubgraphFarmV2 } from 'state/farms/elasticv2/types'

const knProtocolApi = createApi({
reducerPath: 'knProtocol',
baseQuery: fetchBaseQuery({ baseUrl: POOL_FARM_BASE_URL }),
endpoints: builder => ({
getFarmV2: builder.query<{ data: { data: SubgraphFarmV2[] } }, ChainId>({
query: (chainId: ChainId) => ({
url: `/${
(NETWORKS_INFO[chainId] as EVMNetworkInfo).poolFarmRoute
}/api/v1/elastic-new/farm-v2?perPage=1000&page=1`,
}),
}),
}),
})

export default knProtocolApi
export const { useLazyGetFarmV2Query } = knProtocolApi
4 changes: 2 additions & 2 deletions src/services/ksSetting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import { TopToken } from 'state/topTokens/type'

export type KyberSwapConfig = {
rpc: string
prochart: boolean
isEnableBlockService: boolean
isEnableKNProtocol: boolean
blockClient: ApolloClient<NormalizedCacheObject>
classicClient: ApolloClient<NormalizedCacheObject>
elasticClient: ApolloClient<NormalizedCacheObject>
Expand All @@ -23,8 +23,8 @@ export type KyberSwapConfig = {

export type KyberSwapConfigResponse = {
rpc: string
prochart: boolean
isEnableBlockService: boolean
isEnableKNProtocol: boolean
blockSubgraph: string
classicSubgraph: string
elasticSubgraph: string
Expand Down
Loading
Loading