Skip to content

Commit

Permalink
Merge pull request #49 from HaloDAO/develop
Browse files Browse the repository at this point in the history
Merge develop to master, for v1.0.3 release
  • Loading branch information
schystz authored Jul 10, 2021
2 parents 25cc079 + 6ba983e commit 73ae39f
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 48 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ REACT_APP_BALANCER_POOLS_ADDRESSES=0x0,0x0
REACT_APP_UNI_POOLS_ADDRESSES=0x0,0x0
REACT_APP_SUSHI_POOLS_ADDRESSES=0x0,0x0
REACT_APP_BALANCER_LPTOKEN_POOL_MAP=0x0:0x0,0x0:0x0
REACT_APP_DISABLED_POOLS=0x0,0x0

REACT_APP_HALO_TOKEN_ADDRESS_MAINNET=
REACT_APP_HALO_REWARDS_ADDRESS_MAINNET=
Expand Down
5 changes: 4 additions & 1 deletion public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,8 @@
"emptyStateTitleInVest": "Let's get vesting!",
"emptyStateSubTitleInFarm": "You’re one step away from earning. Connect your wallet to join the farm.",
"emptyStateSubTitleInVest": "You’re one step away from earning. Connect your wallet to start to vest.",
"add": "Add"
"add": "Add",
"staking disabled": "Staking Disabled",
"inactive pools": "Inactive Pools",
"inactive": "Inactive"
}
68 changes: 45 additions & 23 deletions src/components/Farm/FarmPoolCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { useDispatch } from 'react-redux'
import { AppDispatch } from 'state'
import useHaloHalo from 'halo-hooks/useHaloHalo'
import { tokenSymbolForPool } from 'utils/poolInfo'
import { PENDING_REWARD_FAILED } from 'constants/pools'

const StyledFixedHeightRowCustom = styled(FixedHeightRow)`
padding: 1rem;
Expand Down Expand Up @@ -415,9 +416,10 @@ const ClaimButton = styled(ButtonOutlined)`
interface FarmPoolCardProps {
poolInfo: PoolInfo
tokenPrice: TokenPrice
isActivePool: boolean
}

export default function FarmPoolCard({ poolInfo, tokenPrice }: FarmPoolCardProps) {
export default function FarmPoolCard({ poolInfo, tokenPrice, isActivePool }: FarmPoolCardProps) {
const { chainId, account } = useActiveWeb3React()
const { t } = useTranslation()
const dispatch = useDispatch<AppDispatch>()
Expand Down Expand Up @@ -452,7 +454,9 @@ export default function FarmPoolCard({ poolInfo, tokenPrice }: FarmPoolCardProps

// Get user earned HALO
const unclaimedRewards = useUnclaimedRewardsPerPool([poolInfo.pid])
const unclaimedPoolRewards = unclaimedRewards[poolInfo.pid] ?? 0
let unclaimedPoolRewards = unclaimedRewards[poolInfo.pid] ?? 0
const hasPendingRewardTokenError = unclaimedPoolRewards === PENDING_REWARD_FAILED
unclaimedPoolRewards = hasPendingRewardTokenError ? 0 : unclaimedPoolRewards
const unclaimedHALO = unclaimedPoolRewards * rewardsToHALOPrice

// Make use of `useApproveCallback` for checking & setting allowance
Expand Down Expand Up @@ -636,7 +640,7 @@ export default function FarmPoolCard({ poolInfo, tokenPrice }: FarmPoolCardProps
</StyledRowFixed>
<StyledRowFixed width="13%">
<LabelText className="first">{t('apy')}:</LabelText>
<StyledTextForValue>{poolAPY}</StyledTextForValue>
<StyledTextForValue>{isActivePool ? poolAPY : t('inactive')}</StyledTextForValue>
</StyledRowFixed>
<StyledRowFixed width="18%">
<LabelText className="first">{t('totalPoolValue')}:</LabelText>
Expand All @@ -654,7 +658,13 @@ export default function FarmPoolCard({ poolInfo, tokenPrice }: FarmPoolCardProps
</StyledRowFixed>
<StyledRowFixed width="14%">
<LabelText>{t('earned')}:</LabelText>
<StyledTextForValue>{formatNumber(unclaimedHALO)} RNBW</StyledTextForValue>
<StyledTextForValue>
{hasPendingRewardTokenError ? (
<u>{formatNumber(unclaimedHALO, isActivePool ? undefined : NumberFormat.short)} RNBW</u>
) : (
<>{formatNumber(unclaimedHALO, isActivePool ? undefined : NumberFormat.short)} RNBW</>
)}
</StyledTextForValue>
</StyledRowFixed>
<StyledRowFixed width="8%" justify="flex-end">
{account && (
Expand All @@ -664,7 +674,9 @@ export default function FarmPoolCard({ poolInfo, tokenPrice }: FarmPoolCardProps
<ManageCloseButton onClick={() => setShowMore(!showMore)}>{t('closeTxt')}</ManageCloseButton>
</HideSmallFullWidth>
) : (
<ManageCloseButtonAlt onClick={() => setShowMore(!showMore)}>{t('add')}</ManageCloseButtonAlt>
<ManageCloseButtonAlt onClick={() => setShowMore(!showMore)}>
{isActivePool ? t('add') : t('manage')}
</ManageCloseButtonAlt>
)}
</>
)}
Expand Down Expand Up @@ -697,23 +709,25 @@ export default function FarmPoolCard({ poolInfo, tokenPrice }: FarmPoolCardProps
value={stakeAmount}
onUserInput={amount => setStakeAmount(amount)}
id="stake-input"
disabled={!isActivePool}
/>
<ButtonMax
onClick={() => {
setStakeAmount(`${toFixed(bptBalance, 8)}`)
}}
disabled={!isActivePool}
>
{t('max')}
</ButtonMax>
</RowFlat>
<Column>
<ButtonHalo
id="stake-button"
disabled={[
ButtonHaloStates.Disabled,
ButtonHaloStates.Approving,
ButtonHaloStates.TxInProgress
].includes(stakeButtonState)}
disabled={
[ButtonHaloStates.Disabled, ButtonHaloStates.Approving, ButtonHaloStates.TxInProgress].includes(
stakeButtonState
) || !isActivePool
}
onClick={() => {
if (stakeButtonState === ButtonHaloStates.Approved) {
stakeLpToken()
Expand All @@ -722,19 +736,25 @@ export default function FarmPoolCard({ poolInfo, tokenPrice }: FarmPoolCardProps
}
}}
>
{(stakeButtonState === ButtonHaloStates.Disabled ||
stakeButtonState === ButtonHaloStates.Approved) && <>{t('stake')}</>}
{stakeButtonState === ButtonHaloStates.NotApproved && <>{t('approve')}</>}
{stakeButtonState === ButtonHaloStates.Approving && (
<>
{HALO_REWARDS_MESSAGE.approving}&nbsp;
<CustomLightSpinner src={Spinner} alt="loader" size={'15px'} />{' '}
</>
)}
{stakeButtonState === ButtonHaloStates.TxInProgress && (
{!isActivePool ? (
<>{t('staking disabled')}</>
) : (
<>
{HALO_REWARDS_MESSAGE.staking}&nbsp;
<CustomLightSpinner src={Spinner} alt="loader" size={'15px'} />{' '}
{(stakeButtonState === ButtonHaloStates.Disabled ||
stakeButtonState === ButtonHaloStates.Approved) && <>{t('stake')}</>}
{stakeButtonState === ButtonHaloStates.NotApproved && <>{t('approve')}</>}
{stakeButtonState === ButtonHaloStates.Approving && (
<>
{HALO_REWARDS_MESSAGE.approving}&nbsp;
<CustomLightSpinner src={Spinner} alt="loader" size={'15px'} />{' '}
</>
)}
{stakeButtonState === ButtonHaloStates.TxInProgress && (
<>
{HALO_REWARDS_MESSAGE.staking}&nbsp;
<CustomLightSpinner src={Spinner} alt="loader" size={'15px'} />{' '}
</>
)}
</>
)}
</ButtonHalo>
Expand Down Expand Up @@ -808,7 +828,9 @@ export default function FarmPoolCard({ poolInfo, tokenPrice }: FarmPoolCardProps
</RewardsChild>
<RewardsChild className="main">
<Text className="label">{poolInfo.pair} Rewards:</Text>
<Text className="balance">{formatNumber(unclaimedHALO)} RNBW</Text>
<Text className="balance">
{formatNumber(unclaimedHALO, isActivePool ? undefined : NumberFormat.short)} RNBW
</Text>
</RewardsChild>
<RewardsChild>
<ClaimButton
Expand Down
36 changes: 33 additions & 3 deletions src/components/Farm/FarmPoolTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ import FarmPoolCard from 'components/Farm/FarmPoolCard'
import Card from 'components/Card'
import { PoolInfo } from 'halo-hooks/usePoolInfo'
import { TokenPrice } from 'halo-hooks/useTokenPrice'
import { groupPoolsInfo } from 'utils/poolInfo'
import styled from 'styled-components'

const InactivePools = styled.div`
margin-top: 1rem;
.tbHeader {
margin-bottom: 0.5rem;
}
`

interface FarmPoolTableProps {
poolsInfo: PoolInfo[]
Expand All @@ -16,8 +26,9 @@ interface FarmPoolTableProps {

const FarmPoolTable = ({ poolsInfo, tokenPrice }: FarmPoolTableProps) => {
const { t } = useTranslation()

const { account } = useWeb3React()
const { inactivePools, activePools } = groupPoolsInfo(poolsInfo)

if (account) {
return (
<>
Expand Down Expand Up @@ -58,9 +69,28 @@ const FarmPoolTable = ({ poolsInfo, tokenPrice }: FarmPoolTableProps) => {
</AutoColumn>
</Card>
</HideSmall>
{poolsInfo.map(poolInfo => {
return <FarmPoolCard key={poolInfo.address} poolInfo={poolInfo} tokenPrice={tokenPrice} />

{activePools.map(poolInfo => {
return (
<FarmPoolCard key={poolInfo.address} poolInfo={poolInfo} tokenPrice={tokenPrice} isActivePool={true} />
)
})}

{inactivePools.length > 0 && (
<InactivePools>
<TYPE.thHeader className="tbHeader">{t('inactive pools')}</TYPE.thHeader>
{inactivePools.map(poolInfo => {
return (
<FarmPoolCard
key={poolInfo.address}
poolInfo={poolInfo}
tokenPrice={tokenPrice}
isActivePool={false}
/>
)
})}
</InactivePools>
)}
</AutoColumn>
</>
)
Expand Down
12 changes: 12 additions & 0 deletions src/constants/pools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ rawLpTokenPoolMapList.forEach(rawLpTokenPool => {
})

export const BALANCER_LPTOKEN_POOL_MAP = lpTokenPoolMap

/**
* Misc
*/
export const PENDING_REWARD_FAILED = -99999

/**
* Inactive pools
*/

const inactivePoolsRaw = process.env.REACT_APP_INACTIVE_POOLS || ''
export const INACTIVE_POOLS = inactivePoolsRaw.split(',').map(a => a.toLowerCase())
4 changes: 3 additions & 1 deletion src/halo-hooks/useFarmSummary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useUnclaimedRewardsPerPool, useStakedBPTPerPool } from './useRewards'
import useHaloHalo from './useHaloHalo'
import { getPoolLiquidity } from 'utils/poolInfo'
import { TokenPrice } from './useTokenPrice'
import { PENDING_REWARD_FAILED } from 'constants/pools'

const useFarmSummary = (poolsInfo: PoolInfo[], tokenPrice: TokenPrice) => {
// Get user balance for each pool
Expand Down Expand Up @@ -47,7 +48,8 @@ const useFarmSummary = (poolsInfo: PoolInfo[], tokenPrice: TokenPrice) => {

for (const poolInfo of poolsInfo) {
// Add unclaimed HALO per pool to totalHALOEarned
const unclaimedPoolRewards = unclaimedRewards[poolInfo.pid] ?? 0
let unclaimedPoolRewards = unclaimedRewards[poolInfo.pid] ?? 0
unclaimedPoolRewards = unclaimedPoolRewards === PENDING_REWARD_FAILED ? 0 : unclaimedPoolRewards
totalHALOEarned += unclaimedPoolRewards * rewardsToHALOPrice

// Calculate LPToken price per pool
Expand Down
1 change: 0 additions & 1 deletion src/halo-hooks/useHaloHalo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ const useHaloHalo = () => {

// one year in seconds / 31536000
const timePriceChangedRatio = 31536000 / (currentTimestamp - genesisTimestamp)
console.log(`Genesis timestamp is ${genesisTimestamp}, current block timestamp is ${currentTimestamp}`)

// 1 comes from the 1:1 ratio before adding rewards
const priceChange = Number(formatEther(currentHaloHaloPrice)) - 1
Expand Down
45 changes: 28 additions & 17 deletions src/halo-hooks/useRewards.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { useHALORewardsContract } from 'hooks/useContract'
import { useCallback, useMemo } from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useSingleCallResult, useSingleContractMultipleData } from 'state/multicall/hooks'
import { formatEther } from 'ethers/lib/utils'
import { useTransactionAdder } from 'state/transactions/hooks'
import { useActiveWeb3React } from 'hooks'
import { tokenSymbolForPool } from 'utils/poolInfo'
import { ZERO_ADDRESS } from '../constants'
import { BigNumber } from 'ethers'
import { PENDING_REWARD_FAILED } from 'constants/pools'

/**
* Internal Methods
Expand Down Expand Up @@ -61,24 +62,34 @@ export const useUnclaimedRewardsPerPool = (poolIds: number[]): { [poolId: number
const { account } = useActiveWeb3React()
const rewardsContract = useHALORewardsContract()

const args = useMemo(() => poolIds.map(poolId => [`${poolId}`, account ?? ZERO_ADDRESS]), [poolIds, account])
const results = useSingleContractMultipleData(rewardsContract, 'pendingRewardToken', args)
const [unclaimedRewards, setUnclaimedRewards] = useState(() => {
const rewards: { [poolId: number]: number } = {}
for (const pid of poolIds) {
rewards[pid] = 0
}
return rewards
})

const fetchPendingRewards = useCallback(async () => {
const newUnclaimedRewards = unclaimedRewards
for (const pid of poolIds) {
try {
const result = await rewardsContract?.pendingRewardToken(`${pid}`, account)
newUnclaimedRewards[pid] = parseFloat(formatEther(result.toString()))
} catch (err) {
console.error(`Error fetching pending rewards for pid[${pid}]: `, err)
newUnclaimedRewards[pid] = PENDING_REWARD_FAILED
}
}
setUnclaimedRewards(newUnclaimedRewards)
}, [poolIds, account, rewardsContract, unclaimedRewards])

return useMemo(
() =>
poolIds.length > 0
? poolIds.reduce<{ [poolId: number]: number }>((memo, poolId, i) => {
if (!results[i]) return memo
useEffect(() => {
if (!account) return
fetchPendingRewards()
}, [poolIds, account, fetchPendingRewards])

const reward = results[i].result
if (reward) {
memo[poolId] = parseFloat(formatEther(reward.toString()))
}
return memo
}, {})
: {},
[poolIds, results]
)
return unclaimedRewards
}

export const useStakedBPTPerPool = (poolIds: number[]): { [poolId: number]: number } => {
Expand Down
8 changes: 7 additions & 1 deletion src/utils/formatNumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export enum NumberFormat {
usd,
usdLong,
percent,
percentShort
percentShort,
short
}

export function formatNumber(number: number, key?: NumberFormat) {
Expand All @@ -20,6 +21,11 @@ export function formatNumber(number: number, key?: NumberFormat) {
if (number < 1) format = '0.[0000]'
}

if (key === NumberFormat.short) {
format = '0.[00]'
if (number > 1000) format = '0.[0]a'
}

if (key === NumberFormat.usd) {
format = '$(0.[00])'
if (number > 1000) format = '$(0.[0]a)'
Expand Down
24 changes: 23 additions & 1 deletion src/utils/poolInfo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BALANCER_POOLS_ADDRESSES, SUSHI_POOLS_ADDRESSES, UNI_POOLS_ADDRESSES } from 'constants/pools'
import { BALANCER_POOLS_ADDRESSES, INACTIVE_POOLS, SUSHI_POOLS_ADDRESSES, UNI_POOLS_ADDRESSES } from 'constants/pools'
import { PoolInfo } from 'halo-hooks/usePoolInfo'
import { TokenPrice } from 'halo-hooks/useTokenPrice'
import { getAddress } from 'ethers/lib/utils'
Expand All @@ -20,6 +20,10 @@ const isSushiPool = (address: string) => {
return SUSHI_POOLS_ADDRESSES.includes(address.toLocaleLowerCase())
}

const isInactivePool = (address: string) => {
return INACTIVE_POOLS.includes(address.toLocaleLowerCase())
}

export const groupByPoolProvider = (addresses: string[]) => {
const balancerPools: PoolIdLpTokenMap[] = []
const uniPools: PoolIdLpTokenMap[] = []
Expand Down Expand Up @@ -77,3 +81,21 @@ export const getPoolLiquidity = (poolInfo: PoolInfo, tokenPrice: TokenPrice) =>
return poolInfo.liquidity
}
}

export const groupPoolsInfo = (poolInfos: PoolInfo[]) => {
const activePools: PoolInfo[] = []
const inactivePools: PoolInfo[] = []

for (const poolInfo of poolInfos) {
if (isInactivePool(poolInfo.asToken.address)) {
inactivePools.push(poolInfo)
} else {
activePools.push(poolInfo)
}
}

return {
activePools,
inactivePools
}
}

0 comments on commit 73ae39f

Please sign in to comment.