diff --git a/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx b/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx
index 0dcc0182f..be85e49bf 100644
--- a/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx
+++ b/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx
@@ -1,5 +1,4 @@
import { useCallback, useMemo, useState, useEffect } from 'react'
-import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import CowProtocolLogo from 'components/CowProtocolLogo'
import { InvestTokenGroup, TokenLogo, InvestSummary, InvestInput, InvestAvailableBar } from '../styled'
@@ -18,8 +17,7 @@ import { ButtonSize } from 'theme'
import Loader from 'components/Loader'
import { useErrorModal } from 'hooks/useErrorMessageAndModal'
import { tryParseAmount } from 'state/swap/hooks'
-import { ONE_HUNDRED_PERCENT, ZERO_PERCENT } from 'constants/misc'
-import { PERCENTAGE_PRECISION } from 'constants/index'
+import { calculateInvestmentAmounts, calculatePercentage } from 'state/claim/hooks/utils'
enum ErrorMsgs {
Initial = 'Insufficient balance to cover the selected investment amount. Either modify the investment amount or unselect the investment option to move forward',
@@ -61,7 +59,7 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
setTypedValue(value.toExact() || '')
setInputError('')
- setPercentage(_calculatePercentage(balance, maxCost))
+ setPercentage(calculatePercentage(balance, maxCost))
}, [balance, maxCost, noBalance, optionIndex, updateInvestAmount])
// on input field change handler
@@ -96,7 +94,7 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
updateInvestAmount({ index: optionIndex, amount: parsedAmount.quotient.toString() })
// update the local state with percentage value
- setPercentage(_calculatePercentage(parsedAmount, maxCost))
+ setPercentage(calculatePercentage(parsedAmount, maxCost))
},
[balance, maxCost, optionIndex, token, updateInvestAmount]
)
@@ -124,14 +122,10 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
}
}, [approveCallback, handleCloseError, handleSetError, token?.symbol])
- const vCowAmount = useMemo(() => {
- if (!token || !price || !investedAmount) {
- return
- }
-
- const investA = CurrencyAmount.fromRawAmount(token, investedAmount)
- return price.quote(investA)
- }, [investedAmount, price, token])
+ const vCowAmount = useMemo(
+ () => calculateInvestmentAmounts(claim, investedAmount)?.vCowAmount,
+ [claim, investedAmount]
+ )
// if its claiming for someone else we will set values to max
// if there is not enough balance then we will set an error
@@ -256,16 +250,3 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
)
}
-
-function _calculatePercentage
+
+ )
+}
diff --git a/src/custom/pages/Claim/InvestmentFlow/index.tsx b/src/custom/pages/Claim/InvestmentFlow/index.tsx
index 186b66c14..5c5ce806a 100644
--- a/src/custom/pages/Claim/InvestmentFlow/index.tsx
+++ b/src/custom/pages/Claim/InvestmentFlow/index.tsx
@@ -1,4 +1,5 @@
import { useEffect, useMemo } from 'react'
+
import {
InvestFlow,
InvestContent,
@@ -8,15 +9,19 @@ import {
Steps,
ClaimTable,
AccountClaimSummary,
- TokenLogo,
} from 'pages/Claim/styled'
+import { InvestSummaryRow } from 'pages/Claim/InvestmentFlow/InvestSummaryRow'
+
import { ClaimType, useClaimState, useUserEnhancedClaimData, useClaimDispatchers } from 'state/claim/hooks'
-import { ClaimCommonTypes, EnhancedUserClaimData } from '../types'
import { ClaimStatus } from 'state/claim/actions'
-import { useActiveWeb3React } from 'hooks/web3'
+import { InvestClaim } from 'state/claim/reducer'
+import { calculateInvestmentAmounts } from 'state/claim/hooks/utils'
+
import { ApprovalState, OptionalApproveCallbackParams } from 'hooks/useApproveCallback'
+import { useActiveWeb3React } from 'hooks/web3'
+
import InvestOption from './InvestOption'
-import CowProtocolLogo from 'components/CowProtocolLogo'
+import { ClaimCommonTypes, ClaimWithInvestmentData, EnhancedUserClaimData } from '../types'
export type InvestOptionProps = {
claim: EnhancedUserClaimData
@@ -49,15 +54,52 @@ function _claimToTokenApproveData(claimType: ClaimType, tokenApproveData: TokenA
}
}
+function _classifyAndFilterClaimData(claimData: EnhancedUserClaimData[], selected: number[]) {
+ const paid: EnhancedUserClaimData[] = []
+ const free: EnhancedUserClaimData[] = []
+
+ claimData.forEach((claim) => {
+ if (claim.isFree) {
+ free.push(claim)
+ } else if (selected.includes(claim.index)) {
+ paid.push(claim)
+ }
+ })
+ return [free, paid]
+}
+
+function _enhancedUserClaimToClaimWithInvestment(
+ claim: EnhancedUserClaimData,
+ investFlowData: InvestClaim[]
+): ClaimWithInvestmentData {
+ const investmentAmount = claim.isFree
+ ? undefined
+ : investFlowData.find(({ index }) => index === claim.index)?.investedAmount
+
+ return { ...claim, ...calculateInvestmentAmounts(claim, investmentAmount) }
+}
+
export default function InvestmentFlow({ hasClaims, isAirdropOnly, ...tokenApproveData }: InvestmentFlowProps) {
const { account } = useActiveWeb3React()
- const { selected, activeClaimAccount, claimStatus, isInvestFlowActive, investFlowStep } = useClaimState()
+ const { selected, activeClaimAccount, claimStatus, isInvestFlowActive, investFlowStep, investFlowData } =
+ useClaimState()
const { initInvestFlowData } = useClaimDispatchers()
const claimData = useUserEnhancedClaimData(activeClaimAccount)
- const selectedClaims = useMemo(() => {
- return claimData.filter(({ index }) => selected.includes(index))
- }, [claimData, selected])
+ // Filtering and splitting claims into free and selected paid claims
+ // `selectedClaims` are used on step 1 and 2
+ // `freeClaims` are used on step 2
+ const [freeClaims, selectedClaims] = useMemo(
+ () => _classifyAndFilterClaimData(claimData, selected),
+ [claimData, selected]
+ )
+
+ // Merge all claims together again, with their investment data for step 2
+ const allClaims: ClaimWithInvestmentData[] = useMemo(
+ () =>
+ freeClaims.concat(selectedClaims).map((claim) => _enhancedUserClaimToClaimWithInvestment(claim, investFlowData)),
+ [freeClaims, investFlowData, selectedClaims]
+ )
useEffect(() => {
initInvestFlowData()
@@ -146,62 +188,9 @@ export default function InvestmentFlow({ hasClaims, isAirdropOnly, ...tokenAppro
-
+ {isFree ? (
+ {ClaimType[type]}
+ ) : (
+ <>
+
+
+
+ {!isFree && (
+
+ Investment amount:{' '}
+
+ {formattedCost} {symbol} ({percentage}% of available investing opportunity)
+
+
+ )}
+
+ Amount to receive:
+ {formatSmart(vCowAmount) || '0'} vCOW
+
+
+
+
+ {!isFree && (
+
+ Price:{' '}
+
+ {formatSmart(price) || '0'} vCoW per {symbol}
+
+
+ )}
+
+ Cost: {isFree ? 'Free!' : `${formattedCost} ${symbol}`}
+
+
+ Vesting:
+ {type === ClaimType.Airdrop ? 'No' : '4 years (linear)'}
+
+
+
-
-
-
- Airdrop
-
-
-
- Amount to receive:
- 13,120.50 vCOW
-
-
-
-
-
- Cost: Free!
-
-
- Vesting:
- No
-
-
-
-
+ {allClaims.map((claim) => (
+
- {' '}
-
-
-
-
- Investment amount: 1343 GNO (50% of available investing opportunity)
-
-
- Amount to receive:
- 13,120.50 vCOW
-
-
-
-
-
- Price: 2666.6666 vCoW per GNO
-
-
- Cost: 0.783375 GNO
-
-
- Vesting:
- 4 years (linear)
-
-
-
Can I modify the invested amounts or invest partial amounts later? No. Once you send the transaction, - you cannot increase or reduce the investment. Investment oportunities can only be exercised once. + you cannot increase or reduce the investment. Investment opportunities can only be exercised once.
Important! Please make sure you intend to claim and send vCOW to the mentioned receiving account(s)
diff --git a/src/custom/pages/Claim/styled.ts b/src/custom/pages/Claim/styled.ts
index 1c462b9e3..7fb480eb7 100644
--- a/src/custom/pages/Claim/styled.ts
+++ b/src/custom/pages/Claim/styled.ts
@@ -191,12 +191,24 @@ export const TokenLogo = styled.div<{ symbol: string; size: number }>`
width: ${({ size }) => `${size}px`};
height: ${({ size }) => `${size}px`};
border-radius: ${({ size }) => `${size}px`};
- background: ${({ symbol, theme }) =>
- `url(${
- symbol === 'GNO' ? LogoGNO : symbol === 'ETH' ? LogoETH : symbol === 'USDC' ? LogoUSDC : theme.blueShade3
- }) no-repeat center/contain`};
+ background: ${({ symbol, theme }) => `url(${_getLogo(symbol) || theme.blueShade3}) no-repeat center/contain`};
`
+function _getLogo(symbol: string) {
+ switch (symbol.toUpperCase()) {
+ case 'GNO':
+ return LogoGNO
+ case 'USDC':
+ return LogoUSDC
+ case 'ETH':
+ return LogoETH
+ // TODO: add xDai token logo after merging to develop
+ // case 'XDAI': return LogoXDAI
+ default:
+ return undefined
+ }
+}
+
export const ClaimSummary = styled.div`
display: flex;
width: 100%;
diff --git a/src/custom/pages/Claim/types.ts b/src/custom/pages/Claim/types.ts
index f38a01c22..8b2e7e579 100644
--- a/src/custom/pages/Claim/types.ts
+++ b/src/custom/pages/Claim/types.ts
@@ -18,3 +18,10 @@ export type EnhancedUserClaimData = UserClaimData & {
price?: Price