diff --git a/.vscode/settings.json b/.vscode/settings.json index ef8a85e7a2..564eaa67f3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,12 +1,14 @@ { "cSpell.words": [ - "giveth", - "merkle", - "xdai", - "GIVpower", + "GIVback", "GIVeconomy", + "giveth", "GIVfarm", - "GIVback", + "GIVpower", "GIVstream", + "HONEYSWAP", + "merkle", + "SUSHISWAP", + "xdai" ] } \ No newline at end of file diff --git a/package.json b/package.json index 617138b66c..448c4d060f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "givethdapp", - "version": "2.3.2", + "version": "2.3.3", "private": true, "scripts": { "build": "next build", diff --git a/src/components/DAOChangeNetworkModal.tsx b/src/components/DAOChangeNetworkModal.tsx new file mode 100644 index 0000000000..7c8c7228c0 --- /dev/null +++ b/src/components/DAOChangeNetworkModal.tsx @@ -0,0 +1,76 @@ +import { + IconInfo16, + neutralColors, + brandColors, + Caption, + Button, +} from '@giveth/ui-design-system'; +import { useWeb3React } from '@web3-react/core'; +import { InjectedConnector } from '@web3-react/injected-connector'; +import styled from 'styled-components'; +import { switchNetwork } from '@/lib/metamask'; +import { Flex } from './styled-components/Flex'; +import config from '@/configuration'; + +interface IChangeNetworkModal { + network: number; +} + +export const DAOChangeNetworkModal = ({ network }: IChangeNetworkModal) => { + const { account, activate } = useWeb3React(); + const networkLabel = + network === config.XDAI_NETWORK_NUMBER ? 'Gnosis chain' : 'Mainnet'; + + const checkWalletAndSwitchNetwork = async (network: number) => { + if (!account) { + await activate(new InjectedConnector({})); + await switchNetwork(network); + } + if (account) { + await switchNetwork(network); + } + }; + return ( + + + + Switch network + + This RegenFarm is only available on {networkLabel} + checkWalletAndSwitchNetwork(network)} + /> + + ); +}; + +const DAOChangeNetworkModalContainer = styled.div` + background-color: ${neutralColors.gray[100]}; + color: ${brandColors.giv[300]}; + border: 1px solid ${brandColors.giv[300]}; + border-radius: 8px; + width: 320px; + z-index: 4; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + opacity: 2; + padding: 16px; +`; + +const Title = styled(Caption)` + font-weight: bold; +`; + +const Desc = styled(Caption)` + margin-left: 32px; + margin-bottom: 16px; +`; + +const ChangeButton = styled(Button)` + color: ${brandColors.giv[300]}; + margin-left: auto; +`; diff --git a/src/components/RegenFarm.tsx b/src/components/RegenFarm.tsx new file mode 100644 index 0000000000..1f6f562222 --- /dev/null +++ b/src/components/RegenFarm.tsx @@ -0,0 +1,75 @@ +import React, { FC } from 'react'; +import { useWeb3React } from '@web3-react/core'; +import { H4 } from '@giveth/ui-design-system'; +import styled from 'styled-components'; +import { + givEconomySupportedNetworks, + regenFarmStreamCardCol, +} from '@/lib/constants/constants'; +import StakingPoolCard from './cards/StakingPoolCard'; +import { Row, Col } from './Grid'; +import { PoolRow } from './homeTabs/GIVfarm.sc'; +import config from '@/configuration'; +import { RegenFarmConfig } from '@/types/config'; +import { DAOChangeNetworkModal } from './DAOChangeNetworkModal'; +import { DAOContainer, DAOChangeNetwork } from './givfarm/GIVfrens.sc'; +import { RegenStreamCard } from './givfarm/RegenStreamCard'; + +interface IRegenFarmProps { + regenFarm: RegenFarmConfig; +} + +export const RegenFarm: FC = ({ regenFarm }) => { + const { chainId } = useWeb3React(); + const { pools } = regenFarm; + + return ( + + + {regenFarm.title} + + {pools.map((poolStakingConfig, idx) => ( + + + + ))} + + {regenFarm && ( + + )} + + + {chainId !== config.MAINNET_NETWORK_NUMBER && + chainId !== config.XDAI_NETWORK_NUMBER && ( + <> + + + + )} + + + ); +}; + +const DaoTitle = styled(H4)` + margin-top: 32px; + margin-bottom: 24px; +`; diff --git a/src/components/cards/BaseStakingCard.tsx b/src/components/cards/BaseStakingCard.tsx index 7a17863dab..4ecbb288ef 100644 --- a/src/components/cards/BaseStakingCard.tsx +++ b/src/components/cards/BaseStakingCard.tsx @@ -1,4 +1,4 @@ -import React, { FC, ReactNode, useEffect, useMemo, useState } from 'react'; +import React, { FC, ReactNode, useEffect, useState } from 'react'; import { brandColors, IconExternalLink, @@ -15,6 +15,7 @@ import { useRouter } from 'next/router'; import config from '../../configuration'; import { PoolStakingConfig, + RegenFarmConfig, RegenPoolStakingConfig, SimplePoolStakingConfig, StakingPlatform, @@ -129,6 +130,7 @@ interface IBaseStakingCardProps { poolStakingConfig: PoolStakingConfig | RegenPoolStakingConfig; stakeInfo: IStakeInfo; notif?: ReactNode; + regenStreamConfig?: RegenFarmConfig; stakedPositions?: LiquidityPosition[]; unstakedPositions?: LiquidityPosition[]; currentIncentive?: { @@ -140,6 +142,7 @@ const BaseStakingCard: FC = ({ stakeInfo, poolStakingConfig, notif, + regenStreamConfig, stakedPositions, unstakedPositions, currentIncentive, @@ -181,9 +184,9 @@ const BaseStakingCard: FC = ({ provideLiquidityLink, unit, farmStartTimeMS, + farmEndTimeMS, active, archived, - discontinued, introCard, network: poolNetwork, } = poolStakingConfig; @@ -201,15 +204,9 @@ const BaseStakingCard: FC = ({ const userGIVLocked = sdh.getUserGIVLockedBalance(); const userGIVPowerBalance = sdh.getUserGIVPowerBalance(); - - const regenStreamConfig = useMemo(() => { - if (!regenStreamType) return undefined; - const networkConfig = - chainId === config.XDAI_NETWORK_NUMBER - ? config.XDAI_CONFIG - : config.MAINNET_CONFIG; - return networkConfig.regenStreams.find(s => s.type === regenStreamType); - }, [chainId, regenStreamType]); + const isDiscontinued = farmEndTimeMS + ? getNowUnixMS() > farmEndTimeMS + : false; useEffect(() => { if (isFirstStakeShown || !router) return; @@ -301,7 +298,7 @@ const BaseStakingCard: FC = ({ )} - {(!active || archived || discontinued) && disableModal && ( + {(!active || archived || isDiscontinued) && disableModal && ( @@ -312,12 +309,12 @@ const BaseStakingCard: FC = ({ justifyContent='space-evenly' > - {discontinued + {isDiscontinued ? 'Attention Farmers!' : 'This pool is no longer available'} - {discontinued + {isDiscontinued ? 'This farm has ended, move your funds to another farm to keep earning rewards.' : 'Please unstake your tokens and check out other available pools.'} @@ -670,9 +667,8 @@ const BaseStakingCard: FC = ({ ) : ( )} diff --git a/src/components/cards/StakingCardIntro.tsx b/src/components/cards/StakingCardIntro.tsx index 5abf064c17..8179552f36 100644 --- a/src/components/cards/StakingCardIntro.tsx +++ b/src/components/cards/StakingCardIntro.tsx @@ -9,22 +9,25 @@ import { } from '@giveth/ui-design-system'; import { Dispatch, FC, SetStateAction } from 'react'; import styled from 'styled-components'; -import { SimplePoolStakingConfig } from '@/types/config'; +import { IntroCardConfig } from '@/types/config'; import { getSymbolIconWithName } from '../StakingPoolImages'; import { Flex } from '../styled-components/Flex'; import { StakeCardState } from './BaseStakingCard'; interface IStakingCardIntro { - poolStakingConfig: SimplePoolStakingConfig; setState: Dispatch>; + symbol: string; + introCard?: IntroCardConfig; } const StakingCardIntro: FC = ({ - poolStakingConfig, + symbol, + introCard, setState, }) => { - const { title, introCard } = poolStakingConfig; - const titleIcon = introCard?.icon ? introCard?.icon : title.split(' / ')[0]; + const titleIcon = introCard?.icon + ? introCard?.icon + : symbol.split(' / ')[0]; return ( diff --git a/src/components/cards/StakingPoolCard.tsx b/src/components/cards/StakingPoolCard.tsx index b9da2ab4f7..b8976f06c7 100644 --- a/src/components/cards/StakingPoolCard.tsx +++ b/src/components/cards/StakingPoolCard.tsx @@ -1,15 +1,20 @@ import BaseStakingCard from './BaseStakingCard'; import { useStakingPool } from '@/hooks/useStakingPool'; import type { + RegenFarmConfig, RegenPoolStakingConfig, SimplePoolStakingConfig, } from '@/types/config'; import type { FC } from 'react'; interface IStakingPoolCardProps { poolStakingConfig: SimplePoolStakingConfig | RegenPoolStakingConfig; + regenStreamConfig?: RegenFarmConfig; } -const StakingPoolCard: FC = ({ poolStakingConfig }) => { +const StakingPoolCard: FC = ({ + poolStakingConfig, + regenStreamConfig, +}) => { const { apr, notStakedAmount, stakedAmount, earned } = useStakingPool(poolStakingConfig); const stakeInfo = { @@ -23,6 +28,7 @@ const StakingPoolCard: FC = ({ poolStakingConfig }) => { ); }; diff --git a/src/components/givfarm/GIVfrens.sc.tsx b/src/components/givfarm/GIVfrens.sc.tsx index f28e13a0a5..5b91272282 100644 --- a/src/components/givfarm/GIVfrens.sc.tsx +++ b/src/components/givfarm/GIVfrens.sc.tsx @@ -13,7 +13,6 @@ export const GIVfrensLink = styled(GLink)` export const DAOContainer = styled(Col)` position: relative; - padding-top: 24px; `; export const DAOChangeNetwork = styled.div` diff --git a/src/components/givfarm/GIVfrens.tsx b/src/components/givfarm/GIVfrens.tsx index 89f7c6ada7..48b815f184 100644 --- a/src/components/givfarm/GIVfrens.tsx +++ b/src/components/givfarm/GIVfrens.tsx @@ -1,29 +1,19 @@ import React, { FC } from 'react'; import { H3 } from '@giveth/ui-design-system'; import { useWeb3React } from '@web3-react/core'; -import { RegenPoolStakingConfig } from '@/types/config'; -import { - DAOContainer, - GIVfrensLink, - Subtitle, - DAOChangeNetwork, -} from '@/components/givfarm/GIVfrens.sc'; -import { PoolRow } from '@/components/homeTabs/GIVfarm.sc'; -import StakingPoolCard from '@/components/cards/StakingPoolCard'; -import { Col, Row } from '../Grid'; import config from '@/configuration'; -import { givEconomySupportedNetworks } from '@/lib/constants/constants'; -import { RegenStreamCard } from './RegenStreamCard'; -import DAOChangeNetworkModal from './DAOChangeNetworkModal'; +import { Col } from '../Grid'; +import { RegenFarm } from '../RegenFarm'; +import { Subtitle, GIVfrensLink } from './GIVfrens.sc'; -interface IGIVfrensProps { - regenFarms: RegenPoolStakingConfig[]; - network: number; -} +interface IGIVfrensProps {} -export const GIVfrens: FC = ({ regenFarms, network }) => { +export const GIVfrens: FC = () => { const { chainId } = useWeb3React(); - if (regenFarms.length === 0) return null; + const regenFarms = + chainId === config.XDAI_NETWORK_NUMBER + ? config.XDAI_CONFIG.regenFarms + : config.MAINNET_CONFIG.regenFarms; return ( <> @@ -43,54 +33,9 @@ export const GIVfrens: FC = ({ regenFarms, network }) => { . - - {regenFarms.map((poolStakingConfig, index) => { - const regenStream = config.NETWORKS_CONFIG[ - network - ].regenStreams.find( - s => s.type === poolStakingConfig.regenStreamType, - ); - return ( - - - - - - - {regenStream && ( - - )} - - - {chainId !== config.MAINNET_NETWORK_NUMBER && - chainId !== config.XDAI_NETWORK_NUMBER && ( - <> - - - - )} - - ); - })} - + {regenFarms.map((regenFarm, index) => ( + + ))} ); }; diff --git a/src/components/givfarm/RegenStreamCard.tsx b/src/components/givfarm/RegenStreamCard.tsx index c41884233e..315ba9f302 100644 --- a/src/components/givfarm/RegenStreamCard.tsx +++ b/src/components/givfarm/RegenStreamCard.tsx @@ -10,6 +10,7 @@ import { IconGIVStream, IconHelp, Lead, + neutralColors, P, Subline, } from '@giveth/ui-design-system'; @@ -23,7 +24,7 @@ import { PercentageRow, } from '@/components/homeTabs/GIVstream.sc'; import { IconWithTooltip } from '@/components/IconWithToolTip'; -import { RegenStreamConfig, StreamType } from '@/types/config'; +import { RegenFarmConfig, StreamType } from '@/types/config'; import { BN, formatWeiHelper } from '@/helpers/number'; import { IconFox } from '@/components/Icons/Fox'; import { IconCult } from '@/components/Icons/Cult'; @@ -33,10 +34,12 @@ import { useAppSelector } from '@/features/hooks'; import config from '@/configuration'; import { SubgraphDataHelper } from '@/lib/subgraph/subgraphDataHelper'; import { TokenDistroHelper } from '@/lib/contractHelper/TokenDistroHelper'; +import { StakeCardState } from '../cards/BaseStakingCard'; +import StakingCardIntro from '../cards/StakingCardIntro'; interface RegenStreamProps { network: number; - streamConfig: RegenStreamConfig; + streamConfig: RegenFarmConfig; } export const getStreamIconWithType = (type: StreamType, size?: number) => { @@ -54,6 +57,7 @@ export const RegenStreamCard: FC = ({ network, streamConfig, }) => { + const [state, setState] = useState(StakeCardState.NORMAL); const [showModal, setShowModal] = useState(false); const [usdAmount, setUSDAmount] = useState('0'); const [rewardLiquidPart, setRewardLiquidPart] = useState(constants.Zero); @@ -86,7 +90,7 @@ export const RegenStreamCard: FC = ({ ? mainnetThirdPartyTokensPrice : xDaiThirdPartyTokensPrice; const price = new BigNumber( - currentPrice[streamConfig.tokenAddressOnUniswapV2], + currentPrice[streamConfig.tokenAddressOnUniswapV2.toLowerCase()], ); if (!price || price.isNaN()) return; @@ -122,106 +126,135 @@ export const RegenStreamCard: FC = ({ const icon = getStreamIconWithType(streamConfig.type, 40); return ( - <> - - - - {icon} -
{streamConfig.title}
-
- - - {formatWeiHelper(rewardStream)} - - {streamConfig.rewardTokenSymbol}/week - - {/* } - direction={'left'} - > - - Your {streamConfig.rewardTokenSymbol}stream - flowrate - - */} - -
-
- - -
- {streamConfig.rewardTokenSymbol}stream progress -
- - } - direction={'right'} - > - - Liquid{' '} - {streamConfig.rewardTokenSymbol} - {' '} - that has already flowed out of the{' '} - {streamConfig.rewardTokenSymbol}stream - - + + {state === StakeCardState.NORMAL ? ( + + + + {icon} +
{streamConfig.title}
+ {streamConfig.introCard && ( + + setState(StakeCardState.INTRO) + } + > + + + )}
-
- - - {percentage?.toFixed(2)}% - 100% - -
- {`Time remaining: ` + remainTime} - + + + + {formatWeiHelper(rewardStream)} + + + {streamConfig.rewardTokenSymbol}/week + + +
- - {getStreamIconWithType(streamConfig.type, 24)} - {formatWeiHelper(rewardLiquidPart)} - - {streamConfig.rewardTokenSymbol} - - - ~${usdAmount} + + +
+ {streamConfig.rewardTokenSymbol}stream + progress +
+ + } + direction={'bottom'} + > + + Liquid{' '} + {streamConfig.rewardTokenSymbol} + {' '} + that has already flowed out of the{' '} + {streamConfig.rewardTokenSymbol}stream + + +
+
+ + + {percentage?.toFixed(2)}% + 100% +
- setShowModal(true)} - buttonType='primary' - disabled={rewardLiquidPart.isZero()} - size='large' - /> - - {showModal && ( - - )} - - + {`Time remaining: ` + remainTime} + +
+ + {getStreamIconWithType(streamConfig.type, 24)} + + {formatWeiHelper(rewardLiquidPart)} + + + {streamConfig.rewardTokenSymbol} + + + ~${usdAmount} +
+ setShowModal(true)} + buttonType='primary' + disabled={rewardLiquidPart.isZero()} + size='large' + /> +
+ + ) : ( + + )} + {showModal && ( + + )} + ); }; -const RegenStreamContainer = styled(Flex)` +const RegenStreamContainer = styled.div` height: 488px; background-color: ${brandColors.giv[700]}; border-radius: 8px; - padding: 24px; position: relative; flex-direction: column; justify-content: space-between; overflow: hidden; `; +const RegenStreamInnerContainer = styled(Flex)` + height: 488px; + padding: 24px; + flex-direction: column; + justify-content: space-between; +`; + const HeaderRow = styled(Flex)` - margin-bottom: 76px; + margin-bottom: 24px; +`; + +export const IntroIcon = styled.div` + position: absolute; + top: 4px; + right: -24px; + cursor: pointer; + color: ${brandColors.deep[100]}; + transition: color 0.3s ease; + :hover { + color: ${neutralColors.gray[100]}; + } `; const RateRow = styled(Flex)` @@ -276,6 +309,6 @@ const Converted = styled(Caption)` const HarvestButton = styled(Button)` width: auto; - padding-left: 64px; - padding-right: 64px; + flex: 1; + max-width: 264px; `; diff --git a/src/components/homeTabs/GIVfarm.tsx b/src/components/homeTabs/GIVfarm.tsx index 2b7e9928aa..962b875888 100644 --- a/src/components/homeTabs/GIVfarm.tsx +++ b/src/components/homeTabs/GIVfarm.tsx @@ -227,17 +227,7 @@ export const TabGIVfarmBottom = () => { )} {renderPools(chainId, showArchivedPools)} - {chainId === config.XDAI_NETWORK_NUMBER ? ( - - ) : ( - - )} + diff --git a/src/components/modals/APR.tsx b/src/components/modals/APR.tsx index f296e6e74f..d25f5a551a 100644 --- a/src/components/modals/APR.tsx +++ b/src/components/modals/APR.tsx @@ -10,15 +10,15 @@ import { import { Modal } from './Modal'; import { Flex } from '../styled-components/Flex'; -import { RegenStreamConfig } from '@/types/config'; import { IModal } from '@/types/common'; import { useModalAnimation } from '@/hooks/useModalAnimation'; import { mediaQueries } from '@/lib/constants/constants'; +import { RegenFarmConfig } from '@/types/config'; import type { TokenDistroHelper } from '@/lib/contractHelper/TokenDistroHelper'; interface IAPRModalProps extends IModal { tokenDistroHelper?: TokenDistroHelper; - regenStreamConfig?: RegenStreamConfig; + regenStreamConfig?: RegenFarmConfig; } export const APRModal: FC = ({ diff --git a/src/components/modals/HarvestAll.tsx b/src/components/modals/HarvestAll.tsx index d59b75e511..88e806d91b 100644 --- a/src/components/modals/HarvestAll.tsx +++ b/src/components/modals/HarvestAll.tsx @@ -18,7 +18,7 @@ import { Modal } from './Modal'; import LoadingAnimation from '@/animations/loading.json'; import { PoolStakingConfig, - RegenStreamConfig, + RegenFarmConfig, SimplePoolStakingConfig, } from '@/types/config'; import { BN, formatWeiHelper, Zero } from '@/helpers/number'; @@ -73,7 +73,7 @@ interface IHarvestAllModalProps extends IModal { earned?: ethers.BigNumber; network: number; tokenDistroHelper?: TokenDistroHelper; - regenStreamConfig?: RegenStreamConfig; + regenStreamConfig?: RegenFarmConfig; stakedPositions?: LiquidityPosition[]; currentIncentive?: { key?: (string | number)[] | null | undefined; diff --git a/src/components/modals/StakeLock/Lock.tsx b/src/components/modals/StakeLock/Lock.tsx index 0ab6f7aa8a..dfb8563b11 100644 --- a/src/components/modals/StakeLock/Lock.tsx +++ b/src/components/modals/StakeLock/Lock.tsx @@ -32,11 +32,10 @@ import { IconWithTooltip } from '@/components/IconWithToolTip'; import { Flex } from '@/components/styled-components/Flex'; import links from '@/lib/constants/links'; import ExternalLink from '@/components/ExternalLink'; -import type { PoolStakingConfig, RegenStreamConfig } from '@/types/config'; +import type { PoolStakingConfig } from '@/types/config'; interface ILockModalProps extends IModal { poolStakingConfig: PoolStakingConfig; - regenStreamConfig?: RegenStreamConfig; maxAmount: BigNumber; } diff --git a/src/components/modals/StakeLock/Stake.tsx b/src/components/modals/StakeLock/Stake.tsx index 9589f76886..8d0e0f6a97 100644 --- a/src/components/modals/StakeLock/Stake.tsx +++ b/src/components/modals/StakeLock/Stake.tsx @@ -35,13 +35,13 @@ import { import { useModalAnimation } from '@/hooks/useModalAnimation'; import type { PoolStakingConfig, - RegenStreamConfig, + RegenFarmConfig, SimplePoolStakingConfig, } from '@/types/config'; interface IStakeModalProps extends IModal { poolStakingConfig: PoolStakingConfig; - regenStreamConfig?: RegenStreamConfig; + regenStreamConfig?: RegenFarmConfig; maxAmount: BigNumber; } diff --git a/src/components/modals/Unstake/UnStake.tsx b/src/components/modals/Unstake/UnStake.tsx index 96d11380a3..05bf676873 100644 --- a/src/components/modals/Unstake/UnStake.tsx +++ b/src/components/modals/Unstake/UnStake.tsx @@ -24,7 +24,7 @@ import { StakeState } from '@/lib/staking'; import { IModal } from '@/types/common'; import { PoolStakingConfig, - RegenStreamConfig, + RegenFarmConfig, SimplePoolStakingConfig, StakingType, } from '@/types/config'; @@ -37,7 +37,7 @@ import config from '@/configuration'; interface IUnStakeModalProps extends IModal { poolStakingConfig: PoolStakingConfig; - regenStreamConfig?: RegenStreamConfig; + regenStreamConfig?: RegenFarmConfig; maxAmount: BigNumber; } diff --git a/src/components/modals/WhatisStream.tsx b/src/components/modals/WhatisStream.tsx index 53371635b1..f22c16a7f8 100644 --- a/src/components/modals/WhatisStream.tsx +++ b/src/components/modals/WhatisStream.tsx @@ -15,16 +15,16 @@ import Link from 'next/link'; import { Flex, FlexCenter } from '../styled-components/Flex'; import { Modal } from './Modal'; import Routes from '@/lib/constants/Routes'; -import { RegenStreamConfig } from '@/types/config'; import { IModal } from '@/types/common'; import { useAppSelector } from '@/features/hooks'; import { ETheme } from '@/features/general/general.slice'; import { useModalAnimation } from '@/hooks/useModalAnimation'; +import { RegenFarmConfig } from '@/types/config'; import type { TokenDistroHelper } from '@/lib/contractHelper/TokenDistroHelper'; interface IWhatisStreamModal extends IModal { tokenDistroHelper?: TokenDistroHelper; - regenStreamConfig?: RegenStreamConfig; + regenStreamConfig?: RegenFarmConfig; } export const WhatisStreamModal: FC = ({ diff --git a/src/config/development.ts b/src/config/development.ts index 106f596ee2..0df493725d 100644 --- a/src/config/development.ts +++ b/src/config/development.ts @@ -51,7 +51,7 @@ const config: EnvConfig = { LM_ADDRESS: '0x929C9353D67af21411d4475B30D960F23C209abd', BUY_LINK: 'https://app.uniswap.org/#/swap?outputCurrency=0x29434A25abd94AE882aA883eea81585Aaa5b078D', - discontinued: SEPT_8TH_2022, + farmEndTimeMS: SEPT_8TH_2022, active: false, archived: true, }, @@ -72,7 +72,7 @@ const config: EnvConfig = { unit: 'LP', active: false, archived: true, - discontinued: SEPT_8TH_2022, + farmEndTimeMS: SEPT_8TH_2022, }, { network: MAINNET_NETWORK_NUMBER, @@ -115,7 +115,7 @@ const config: EnvConfig = { ], uniswapV2Subgraph: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2', - regenStreams: [ + regenFarms: [ // // TODO: GOERLI // { // tokenDistroAddress: @@ -127,29 +127,32 @@ const config: EnvConfig = { // rewardTokenSymbol: 'CULT', // tokenAddressOnUniswapV2: // '0xf0f9d895aca5c8678f706fb8216fa22957685a13', - // }, - ], - regenFarms: [ - // // TODO: GOERLI - // { - // POOL_ADDRESS: '0x6bb32725aa31b1a99e7c782e0605b0fb57e4b9e6', - // LM_ADDRESS: '0x9d23d449af3e2c07a286688c85ff5d3d4c219d79', - // type: StakingType.UNISWAPV2_CULT_ETH, - // platform: StakingPlatform.UNISWAP, - // title: 'CULT / ETH', - // description: '50% CULT, 50% ETH', - // provideLiquidityLink: - // 'https://app.uniswap.org/#/add/v2/0x3e4d3FadEE2338D420bb5E5cB26aAd96c165476c/ETH?chain=kovan', - // unit: 'LP', - // regenStreamType: StreamType.CULT, - // regenFarmType: RegenFarmType.CULT_ETH, - // introCard: { - // title: 'CULT', - // description: `The purpose of CULT is to empower those building and contributing to our decentralized future. Our society makes it as difficult as possible to break away from societal, economic and other norms, and CULT serves to fund and support those who are working to take back our future. CULT is a reminder that the power in people is stronger than the people in power.\n\n CULT is the governance token of the Cult DAO. Every transaction of the CULT token allows you to contribute & fast-forward economic & societal change by contributing a 0.4% tax to the treasury. Fight from within until you get out, or change the system in doing so.`, - // link: 'https://cultdao.io/', - // }, - // farmStartTimeMS: 1646306818206, - // active: true, + // pools: [ + // // TODO: GOERLI + // { + // network: MAINNET_NETWORK_NUMBER, + // POOL_ADDRESS: + // '0x6bb32725aa31b1a99e7c782e0605b0fb57e4b9e6', + // LM_ADDRESS: + // '0x9d23d449af3e2c07a286688c85ff5d3d4c219d79', + // type: StakingType.UNISWAPV2_CULT_ETH, + // platform: StakingPlatform.UNISWAP, + // title: 'CULT / ETH', + // description: '50% CULT, 50% ETH', + // provideLiquidityLink: + // 'https://app.uniswap.org/#/add/v2/0x3e4d3FadEE2338D420bb5E5cB26aAd96c165476c/ETH?chain=kovan', + // unit: 'LP', + // regenStreamType: StreamType.CULT, + // regenFarmType: RegenFarmType.CULT_ETH, + // introCard: { + // title: 'CULT', + // description: `The purpose of CULT is to empower those building and contributing to our decentralized future. Our society makes it as difficult as possible to break away from societal, economic and other norms, and CULT serves to fund and support those who are working to take back our future. CULT is a reminder that the power in people is stronger than the people in power.\n\n CULT is the governance token of the Cult DAO. Every transaction of the CULT token allows you to contribute & fast-forward economic & societal change by contributing a 0.4% tax to the treasury. Fight from within until you get out, or change the system in doing so.`, + // link: 'https://cultdao.io/', + // }, + // farmStartTimeMS: 1646306818206, + // active: true, + // }, + // ], // }, ], }, @@ -217,7 +220,7 @@ const config: EnvConfig = { unit: 'LP', active: false, archived: true, - discontinued: SEPT_8TH_2022, + farmEndTimeMS: SEPT_8TH_2022, }, { network: XDAI_NETWORK_NUMBER, @@ -233,14 +236,14 @@ const config: EnvConfig = { active: false, archived: true, farmStartTimeMS: 1655997000000, - discontinued: SEPT_8TH_2022, + farmEndTimeMS: SEPT_8TH_2022, }, ], uniswapV2Subgraph: 'https://api.thegraph.com/subgraphs/name/1hive/honeyswap-v2', - regenStreams: [ + regenFarms: [ { tokenDistroAddress: '0xCA29ec6F4218E230294993E0d77d5ece5a6573D8', @@ -251,30 +254,59 @@ const config: EnvConfig = { rewardTokenSymbol: 'FOX', tokenAddressOnUniswapV2: '0x21a42669643f45Bc0e086b8Fc2ed70c23D67509d', - }, - ], - regenFarms: [ - { - network: XDAI_NETWORK_NUMBER, - POOL_ADDRESS: '0xD28C07F802212F04AF41834ec0CC81d2d283124B', - LM_ADDRESS: '0x06851400866e065972ff21e1ECdE035b4772736d', - type: StakingType.HONEYSWAP_FOX_HNY, - platform: StakingPlatform.HONEYSWAP, - title: 'FOX / HNY', - description: '50% FOX, 50% HNY', - provideLiquidityLink: - 'https://app.honeyswap.org/#/add/0x18cE354571ba71bC7b3d633b254954C5A9cfC195/0x69F79C9eA174d4659B18c7993c7EFbBbB58cF068', - unit: 'LP', - regenStreamType: StreamType.FOX, - regenFarmType: RegenFarmType.FOX_HNY, - introCard: { - title: 'FOX', - description: - 'ShapeShift is the free and open-source one-stop-shop for cross-chain DeFi. Buy, sell, send, receive, trade, and earn yield on your crypto across a growing number of protocols and chains with no added fees ever. FOX is the governance token of the ShapeShift DAO.', - link: 'https://shapeshift.com/', - }, - farmStartTimeMS: 1646306818206, - active: true, + pools: [ + { + network: XDAI_NETWORK_NUMBER, + POOL_ADDRESS: + '0xD28C07F802212F04AF41834ec0CC81d2d283124B', + LM_ADDRESS: + '0x06851400866e065972ff21e1ECdE035b4772736d', + type: StakingType.HONEYSWAP_FOX_HNY, + platform: StakingPlatform.HONEYSWAP, + title: 'FOX / HNY', + description: '50% FOX, 50% HNY', + provideLiquidityLink: + 'https://app.honeyswap.org/#/add/0x18cE354571ba71bC7b3d633b254954C5A9cfC195/0x69F79C9eA174d4659B18c7993c7EFbBbB58cF068', + unit: 'LP', + regenStreamType: StreamType.FOX, + regenFarmType: RegenFarmType.FOX_HNY, + + farmStartTimeMS: 1646306818206, + active: true, + farmEndTimeMS: 1665932450000, + introCard: { + title: 'ShapeShift DAO', + description: + 'ShapeShift is the free and open-source one-stop-shop for cross-chain DeFi. Buy, sell, send, receive, trade, and earn yield on your crypto across a growing number of protocols and chains with no added fees ever. FOX is the governance token of the ShapeShift DAO.', + link: 'https://shapeshift.com/', + }, + }, + { + network: XDAI_NETWORK_NUMBER, + POOL_ADDRESS: + '0x0714A2fE9574F591a4ed3fD03b63714e8681fBb7', + LM_ADDRESS: + '0x93c40bCA6a854B2190a054136a316C4Df7f89f10', + type: StakingType.HONEYSWAP_FOX_XDAI, + platform: StakingPlatform.HONEYSWAP, + title: 'FOX / xDAI', + description: '50% FOX, 50% xDAI', + provideLiquidityLink: + 'https://app.honeyswap.org/#/add/0x18cE354571ba71bC7b3d633b254954C5A9cfC195/0x97c4dD5cE204b8c1F2f3B8fBfBBDC771d867d18c', + unit: 'LP', + regenStreamType: StreamType.FOX, + regenFarmType: RegenFarmType.FOX_XDAI, + + farmStartTimeMS: 1646306818206, + active: true, + introCard: { + title: 'ShapeShift DAO', + description: + 'ShapeShift is the free and open-source one-stop-shop for cross-chain DeFi. Buy, sell, send, receive, trade, and earn yield on your crypto across a growing number of protocols and chains with no added fees ever. FOX is the governance token of the ShapeShift DAO.', + link: 'https://shapeshift.com/', + }, + }, + ], }, ], }, diff --git a/src/config/production.ts b/src/config/production.ts index d27d47983b..379ccce724 100644 --- a/src/config/production.ts +++ b/src/config/production.ts @@ -50,7 +50,7 @@ const config: EnvConfig = { LM_ADDRESS: '0x4B9EfAE862a1755F7CEcb021856D467E86976755', BUY_LINK: 'https://app.uniswap.org/#/swap?outputCurrency=0x900db999074d9277c5da2a43f252d74366230da0', - discontinued: SEPT_8TH_2022, + farmEndTimeMS: SEPT_8TH_2022, active: false, archived: true, }, @@ -71,7 +71,7 @@ const config: EnvConfig = { unit: 'LP', farmStartTimeMS: 1651345200000, active: false, - discontinued: SEPT_8TH_2022, + farmEndTimeMS: SEPT_8TH_2022, archived: true, }, { @@ -139,7 +139,7 @@ const config: EnvConfig = { ], uniswapV2Subgraph: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2', - regenStreams: [ + regenFarms: [ { tokenDistroAddress: '0x73f2D115C2cBAa3b5F477A78F7A7CD348D8b70a2', @@ -150,29 +150,31 @@ const config: EnvConfig = { rewardTokenSymbol: 'CULT', tokenAddressOnUniswapV2: '0xf0f9D895aCa5c8678f706FB8216fa22957685A13', - }, - ], - regenFarms: [ - { - network: MAINNET_NETWORK_NUMBER, - POOL_ADDRESS: '0x5281E311734869C64ca60eF047fd87759397EFe6', - LM_ADDRESS: '0xa479103c2618aD514653B53F064Bc6c9dC35a30b', - type: StakingType.UNISWAPV2_CULT_ETH, - platform: StakingPlatform.UNISWAP, - title: 'CULT / ETH', - description: '50% CULT, 50% ETH', - provideLiquidityLink: - 'https://app.uniswap.org/#/add/v2/0xf0f9D895aCa5c8678f706FB8216fa22957685A13/ETH?chain=mainnet', - unit: 'LP', - regenStreamType: StreamType.CULT, - regenFarmType: RegenFarmType.CULT_ETH, - introCard: { - title: 'CULT', - description: `The purpose of CULT is to empower those building and contributing to our decentralized future. Our society makes it as difficult as possible to break away from societal, economic and other norms, and CULT serves to fund and support those who are working to take back our future. CULT is a reminder that the power in people is stronger than the people in power.\n\n CULT is the governance token of the Cult DAO. Every transaction of the CULT token allows you to contribute & fast-forward economic & societal change by contributing a 0.4% tax to the treasury. Fight from within until you get out, or change the system in doing so.`, - link: 'https://cultdao.io/', - }, - farmStartTimeMS: 1655218800000, - active: true, + pools: [ + { + network: MAINNET_NETWORK_NUMBER, + POOL_ADDRESS: + '0x5281E311734869C64ca60eF047fd87759397EFe6', + LM_ADDRESS: + '0xa479103c2618aD514653B53F064Bc6c9dC35a30b', + type: StakingType.UNISWAPV2_CULT_ETH, + platform: StakingPlatform.UNISWAP, + title: 'CULT / ETH', + description: '50% CULT, 50% ETH', + provideLiquidityLink: + 'https://app.uniswap.org/#/add/v2/0xf0f9D895aCa5c8678f706FB8216fa22957685A13/ETH?chain=mainnet', + unit: 'LP', + regenStreamType: StreamType.CULT, + regenFarmType: RegenFarmType.CULT_ETH, + farmStartTimeMS: 1655218800000, + active: true, + introCard: { + title: 'CULT', + description: `The purpose of CULT is to empower those building and contributing to our decentralized future. Our society makes it as difficult as possible to break away from societal, economic and other norms, and CULT serves to fund and support those who are working to take back our future. CULT is a reminder that the power in people is stronger than the people in power.\n\n CULT is the governance token of the Cult DAO. Every transaction of the CULT token allows you to contribute & fast-forward economic & societal change by contributing a 0.4% tax to the treasury. Fight from within until you get out, or change the system in doing so.`, + link: 'https://cultdao.io/', + }, + }, + ], }, ], }, @@ -238,7 +240,7 @@ const config: EnvConfig = { 'https://gnosis.sushi.com/add/0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1/0x4f4F9b8D5B4d0Dc10506e5551B0513B61fD59e75', unit: 'LP', active: false, - discontinued: SEPT_8TH_2022, + farmEndTimeMS: SEPT_8TH_2022, archived: true, }, { @@ -253,7 +255,7 @@ const config: EnvConfig = { 'https://app.honeyswap.org/#/add/0x4f4F9b8D5B4d0Dc10506e5551B0513B61fD59e75/xdai', unit: 'LP', active: false, - discontinued: SEPT_8TH_2022, // change this to archived: true when it's over + farmEndTimeMS: SEPT_8TH_2022, // change this to archived: true when it's over farmStartTimeMS: 1656086400000, archived: true, }, @@ -262,7 +264,7 @@ const config: EnvConfig = { uniswapV2Subgraph: 'https://api.thegraph.com/subgraphs/name/1hive/honeyswap-v2', - regenStreams: [ + regenFarms: [ { tokenDistroAddress: '0xA9a37a14E562D0E1d335B4714E3455483ede7A9a', @@ -273,30 +275,57 @@ const config: EnvConfig = { rewardTokenSymbol: 'FOX', tokenAddressOnUniswapV2: '0x21a42669643f45bc0e086b8fc2ed70c23d67509d', - }, - ], - regenFarms: [ - { - network: XDAI_NETWORK_NUMBER, - POOL_ADDRESS: '0x8a0bee989c591142414ad67fb604539d917889df', - LM_ADDRESS: '0x502EC7a040F486EE6Cb7d634D94764874B29dE68', - type: StakingType.HONEYSWAP_FOX_HNY, - platform: StakingPlatform.HONEYSWAP, - title: 'FOX / HNY', - description: '50% FOX, 50% HNY', - provideLiquidityLink: - 'https://app.honeyswap.org/#/add/0x21a42669643f45bc0e086b8fc2ed70c23d67509d/0x71850b7e9ee3f13ab46d67167341e4bdc905eef9?chainId=100', - unit: 'LP', - regenStreamType: StreamType.FOX, - regenFarmType: RegenFarmType.FOX_HNY, - introCard: { - title: 'FOX', - description: - 'ShapeShift is the free and open-source one-stop-shop for cross-chain DeFi. Buy, sell, send, receive, trade, and earn yield on your crypto across a growing number of protocols and chains with no added fees ever. FOX is the governance token of the ShapeShift DAO.', - link: 'https://shapeshift.com/', - }, - farmStartTimeMS: 1649001600000, - active: true, + pools: [ + { + network: XDAI_NETWORK_NUMBER, + POOL_ADDRESS: + '0x8a0bee989c591142414ad67fb604539d917889df', + LM_ADDRESS: + '0x502EC7a040F486EE6Cb7d634D94764874B29dE68', + type: StakingType.HONEYSWAP_FOX_HNY, + platform: StakingPlatform.HONEYSWAP, + title: 'FOX / HNY', + description: '50% FOX, 50% HNY', + provideLiquidityLink: + 'https://app.honeyswap.org/#/add/0x21a42669643f45bc0e086b8fc2ed70c23d67509d/0x71850b7e9ee3f13ab46d67167341e4bdc905eef9?chainId=100', + unit: 'LP', + regenStreamType: StreamType.FOX, + regenFarmType: RegenFarmType.FOX_HNY, + farmStartTimeMS: 1649001600000, + active: true, + farmEndTimeMS: 1665932450000, + introCard: { + title: 'ShapeShift DAO', + description: + 'ShapeShift is the free and open-source one-stop-shop for cross-chain DeFi. Buy, sell, send, receive, trade, and earn yield on your crypto across a growing number of protocols and chains with no added fees ever. FOX is the governance token of the ShapeShift DAO.', + link: 'https://shapeshift.com/', + }, + }, + { + network: XDAI_NETWORK_NUMBER, + POOL_ADDRESS: + '0xc22313fd39f7d4d73a89558f9e8e444c86464bac', + LM_ADDRESS: + '0x9A333AD00868472c0314F76DB8dA305B83890129', + type: StakingType.HONEYSWAP_FOX_XDAI, + platform: StakingPlatform.HONEYSWAP, + title: 'FOX / xDAI', + description: '50% FOX, 50% xDAI', + provideLiquidityLink: + 'https://app.honeyswap.org/#/add/0x21a42669643f45bc0e086b8fc2ed70c23d67509d/0xe91d153e0b41518a2ce8dd3d7944fa863463a97d?chainId=100', + unit: 'LP', + regenStreamType: StreamType.FOX, + regenFarmType: RegenFarmType.FOX_XDAI, + farmStartTimeMS: 1666026660000, + active: true, + introCard: { + title: 'ShapeShift DAO', + description: + 'ShapeShift is the free and open-source one-stop-shop for cross-chain DeFi. Buy, sell, send, receive, trade, and earn yield on your crypto across a growing number of protocols and chains with no added fees ever. FOX is the governance token of the ShapeShift DAO.', + link: 'https://shapeshift.com/', + }, + }, + ], }, ], }, diff --git a/src/features/price/price.thunks.ts b/src/features/price/price.thunks.ts index 3350718ae7..84f0551e61 100644 --- a/src/features/price/price.thunks.ts +++ b/src/features/price/price.thunks.ts @@ -32,14 +32,14 @@ export const fetchMainnetThirdPartyTokensPriceAsync = createAsyncThunk( 'price/fetchMainnetThirdPartyTokensPrice', async () => { const promises: Promise[] = []; - config.MAINNET_CONFIG.regenStreams.forEach(streamConfig => { + config.MAINNET_CONFIG.regenFarms.forEach(streamConfig => { const tokenAddress = streamConfig.tokenAddressOnUniswapV2.toLowerCase(); promises.push(fetchMainnetTokenPrice(tokenAddress)); }); return Promise.all(promises).then(prices => { let res: { [x: string]: string } = {}; - config.MAINNET_CONFIG.regenStreams.forEach((streamConfig, idx) => { + config.MAINNET_CONFIG.regenFarms.forEach((streamConfig, idx) => { const tokenAddress = streamConfig.tokenAddressOnUniswapV2.toLowerCase(); res[tokenAddress] = prices[idx]; @@ -53,14 +53,14 @@ export const fetchGnosisThirdPartyTokensPriceAsync = createAsyncThunk( 'price/fetchGnosisThirdPartyTokensPric', async () => { const promises: Promise[] = []; - config.XDAI_CONFIG.regenStreams.forEach(streamConfig => { + config.XDAI_CONFIG.regenFarms.forEach(streamConfig => { const tokenAddress = streamConfig.tokenAddressOnUniswapV2.toLowerCase(); promises.push(fetchGnosisTokenPrice(tokenAddress)); }); return Promise.all(promises).then(prices => { let res: { [x: string]: string } = {}; - config.XDAI_CONFIG.regenStreams.forEach((streamConfig, idx) => { + config.XDAI_CONFIG.regenFarms.forEach((streamConfig, idx) => { const tokenAddress = streamConfig.tokenAddressOnUniswapV2.toLowerCase(); res[tokenAddress] = prices[idx]; diff --git a/src/lib/constants/constants.ts b/src/lib/constants/constants.ts index 083046c586..24793f3dc8 100644 --- a/src/lib/constants/constants.ts +++ b/src/lib/constants/constants.ts @@ -115,3 +115,8 @@ export const statusCodes = [ '503', '504', ] as const; + +export const regenFarmStreamCardCol = { + sm: [12, 6, 12], + lg: [12, 8, 4], +}; diff --git a/src/lib/stakingPool.ts b/src/lib/stakingPool.ts index 58e8cdbad9..a06bd6a2d7 100644 --- a/src/lib/stakingPool.ts +++ b/src/lib/stakingPool.ts @@ -271,7 +271,7 @@ const getSimplePoolStakingAPR = async ( const { regenStreamType } = poolStakingConfig as RegenPoolStakingConfig; const streamConfig = regenStreamType && - config.NETWORKS_CONFIG[network].regenStreams.find( + config.NETWORKS_CONFIG[network].regenFarms.find( s => s.type === regenStreamType, ); const tokenAddress = streamConfig diff --git a/src/lib/subgraph/subgraphQueryBuilder.ts b/src/lib/subgraph/subgraphQueryBuilder.ts index 5517fb6fa1..d70f1474e0 100644 --- a/src/lib/subgraph/subgraphQueryBuilder.ts +++ b/src/lib/subgraph/subgraphQueryBuilder.ts @@ -82,7 +82,7 @@ export class SubgraphQueryBuilder { ): string => { return [ networkConfig.TOKEN_DISTRO_ADDRESS, - ...networkConfig.regenStreams.map(c => { + ...networkConfig.regenFarms.map(c => { return c.tokenDistroAddress; }), ] @@ -275,7 +275,9 @@ export class SubgraphQueryBuilder { ...(config.MAINNET_CONFIG.pools.filter( c => c.type !== StakingType.UNISWAPV3_ETH_GIV, ) as Array), - ...config.MAINNET_CONFIG.regenFarms, + ...config.MAINNET_CONFIG.regenFarms + .map(regenFarm => regenFarm.pools) + .flat(), ], userAddress, )} @@ -298,7 +300,9 @@ export class SubgraphQueryBuilder { getGivStakingConfig(config.XDAI_CONFIG), ...(config.XDAI_CONFIG .pools as Array), - ...config.XDAI_CONFIG.regenFarms, + ...config.XDAI_CONFIG.regenFarms + .map(regenFarm => regenFarm.pools) + .flat(), ], userAddress, )} diff --git a/src/types/config.ts b/src/types/config.ts index 783f8530a9..d4f50a809f 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -1,10 +1,10 @@ export interface BasicStakingConfig { LM_ADDRESS: string; network: number; - discontinued?: number; GARDEN_ADDRESS?: string; BUY_LINK?: string; farmStartTimeMS?: number; + farmEndTimeMS?: number; icon?: string; } export enum StakingPlatform { @@ -26,11 +26,13 @@ export enum StakingType { ICHI_GIV_ONEGIV = 'Ichi_GIV_oneGIV', HONEYSWAP_FOX_HNY = 'Honeyswap_FOX_HNY', + HONEYSWAP_FOX_XDAI = 'Honeyswap_FOX_DAI', UNISWAPV2_CULT_ETH = 'UniswapV2_CULT_ETH', } export enum RegenFarmType { FOX_HNY = 'FOX_HNY_FARM', + FOX_XDAI = 'FOX_XDAI_FARM', CULT_ETH = 'CULT_ETH_FARM', } @@ -100,7 +102,7 @@ export interface GasPreference { maxPriorityFeePerGas?: string; } -export interface RegenStreamConfig { +export interface RegenFarmConfig { title: string; tokenDistroAddress: string; type: StreamType; @@ -108,6 +110,8 @@ export interface RegenStreamConfig { rewardTokenSymbol: string; // For price purpose tokenAddressOnUniswapV2: string; + pools: RegenPoolStakingConfig[]; + introCard?: IntroCardConfig; } export interface BasicNetworkConfig { @@ -137,8 +141,7 @@ export interface BasicNetworkConfig { >; uniswapV2Subgraph: string; - regenStreams: RegenStreamConfig[]; - regenFarms: RegenPoolStakingConfig[]; + regenFarms: RegenFarmConfig[]; } interface MainnetNetworkConfig extends BasicNetworkConfig {