From a8d90c6aacbed4ac39259e90afd474e4f894607b Mon Sep 17 00:00:00 2001 From: David Date: Tue, 25 Jan 2022 09:08:10 -0300 Subject: [PATCH] [Claim-Approve] Hook optional amountToCheckAgainstAllowance param (#2175) * mod the mod * edit the modded trade and claim approve hooks * edit places in app using new hook params * fix approve logic conditional * change logic * [CLAIM - Approve] Wire new approve logic into app (fixes broken merge stuff also) (#2233) * move approve logic from Claim > InvestOption * helper utils * tweak claim approve hook * apply @nenadV91's suggested fix * path * allow investmentAmount ro take maxCost * remove investmentAmount * && instead of || * tweak to approve logic * fix rebase error --- src/custom/hooks/useApproveCallback/index.ts | 79 +++++++++--- .../useApproveCallbackMod.ts | 120 +++++++++++------- .../Claim/InvestmentFlow/InvestOption.tsx | 65 +++++++--- .../pages/Claim/InvestmentFlow/index.tsx | 43 +------ src/custom/pages/Claim/index.tsx | 36 +----- src/custom/pages/Swap/SwapMod.tsx | 9 +- src/custom/state/claim/hooks/utils.ts | 21 ++- src/custom/state/swap/extension.ts | 6 + 8 files changed, 224 insertions(+), 155 deletions(-) diff --git a/src/custom/hooks/useApproveCallback/index.ts b/src/custom/hooks/useApproveCallback/index.ts index 89cac7fde..204b85082 100644 --- a/src/custom/hooks/useApproveCallback/index.ts +++ b/src/custom/hooks/useApproveCallback/index.ts @@ -1,22 +1,34 @@ -import { Currency, CurrencyAmount } from '@uniswap/sdk-core' +import { Currency, CurrencyAmount, MaxUint256, Percent } from '@uniswap/sdk-core' import { useActiveWeb3React } from '@src/hooks/web3' import { Field } from '@src/state/swap/actions' import { computeSlippageAdjustedAmounts } from 'utils/prices' import { useMemo } from 'react' import { GP_VAULT_RELAYER, V_COW_CONTRACT_ADDRESS } from 'constants/index' import TradeGp from 'state/swap/TradeGp' -import { ZERO_PERCENT } from 'constants/misc' -import { useApproveCallback } from './useApproveCallbackMod' +import { ApproveCallbackParams, useApproveCallback } from './useApproveCallbackMod' export { ApprovalState, useApproveCallback } from './useApproveCallbackMod' +import { ClaimType } from 'state/claim/hooks' +import { supportedChainId } from 'utils/supportedChainId' +import { EnhancedUserClaimData } from 'pages/Claim/types' + +type ApproveCallbackFromTradeParams = Pick< + ApproveCallbackParams, + 'openTransactionConfirmationModal' | 'closeModals' | 'amountToCheckAgainstAllowance' +> & { + trade: TradeGp | undefined + allowedSlippage: Percent +} + // export function useApproveCallbackFromTrade(trade?: Trade, allowedSlippage = 0) { -export function useApproveCallbackFromTrade( - openTransactionConfirmationModal: (message: string) => void, - closeModals: () => void, - trade?: TradeGp, - allowedSlippage = ZERO_PERCENT -) { +export function useApproveCallbackFromTrade({ + openTransactionConfirmationModal, + closeModals, + trade, + allowedSlippage, + amountToCheckAgainstAllowance, +}: ApproveCallbackFromTradeParams) { const { chainId } = useActiveWeb3React() const amountToApprove = useMemo(() => { @@ -29,22 +41,57 @@ export function useApproveCallbackFromTrade( const vaultRelayer = chainId ? GP_VAULT_RELAYER[chainId] : undefined - return useApproveCallback(openTransactionConfirmationModal, closeModals, amountToApprove, vaultRelayer) + return useApproveCallback({ + openTransactionConfirmationModal, + closeModals, + amountToApprove, + spender: vaultRelayer, + amountToCheckAgainstAllowance, + }) } export type OptionalApproveCallbackParams = { transactionSummary: string } -export function useApproveCallbackFromClaim( - openTransactionConfirmationModal: (message: string) => void, - closeModals: () => void, - amountToApprove: CurrencyAmount | undefined -) { +type ApproveCallbackFromClaimParams = Omit< + ApproveCallbackParams, + 'spender' | 'amountToApprove' | 'amountToCheckAgainstAllowance' +> & { + claim: EnhancedUserClaimData + investmentAmount?: CurrencyAmount +} + +export function useApproveCallbackFromClaim({ + openTransactionConfirmationModal, + closeModals, + claim, + investmentAmount, +}: ApproveCallbackFromClaimParams) { const { chainId } = useActiveWeb3React() + const supportedChain = supportedChainId(chainId) const vCowContract = chainId ? V_COW_CONTRACT_ADDRESS[chainId] : undefined + // Claim only approves GNO and USDC (GnoOption & Investor, respectively.) + const approveAmounts = useMemo(() => { + if (supportedChain && (claim.type === ClaimType.GnoOption || claim.type === ClaimType.Investor)) { + const investmentCurrency = claim.currencyAmount?.currency as Currency + return { + amountToApprove: CurrencyAmount.fromRawAmount(investmentCurrency, MaxUint256), + // pass in a custom investmentAmount or just use the maxCost + amountToCheckAgainstAllowance: investmentAmount || claim.cost, + } + } + return undefined + }, [claim.cost, claim.currencyAmount?.currency, claim.type, investmentAmount, supportedChain]) + // Params: modal cbs, amountToApprove: token user is investing e.g, spender: vcow token contract - return useApproveCallback(openTransactionConfirmationModal, closeModals, amountToApprove, vCowContract) + return useApproveCallback({ + openTransactionConfirmationModal, + closeModals, + spender: vCowContract, + amountToApprove: approveAmounts?.amountToApprove, + amountToCheckAgainstAllowance: approveAmounts?.amountToCheckAgainstAllowance, + }) } diff --git a/src/custom/hooks/useApproveCallback/useApproveCallbackMod.ts b/src/custom/hooks/useApproveCallback/useApproveCallbackMod.ts index 83eefd19f..77242d376 100644 --- a/src/custom/hooks/useApproveCallback/useApproveCallbackMod.ts +++ b/src/custom/hooks/useApproveCallback/useApproveCallbackMod.ts @@ -1,12 +1,12 @@ import { MaxUint256 } from '@ethersproject/constants' import { TransactionResponse } from '@ethersproject/providers' import { BigNumber } from '@ethersproject/bignumber' -import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core' -import { Trade as V2Trade } from '@uniswap/v2-sdk' -import { Trade as V3Trade } from '@uniswap/v3-sdk' +import { Currency, CurrencyAmount /* , Percent, TradeType */ } from '@uniswap/sdk-core' +// import { Trade as V2Trade } from '@uniswap/v2-sdk' +// import { Trade as V3Trade } from '@uniswap/v3-sdk' import { useCallback, useMemo } from 'react' -import { SWAP_ROUTER_ADDRESSES, V2_ROUTER_ADDRESS } from 'constants/addresses' +// import { SWAP_ROUTER_ADDRESSES, V2_ROUTER_ADDRESS } from 'constants/addresses' import { useHasPendingApproval, useTransactionAdder } from 'state/enhancedTransactions/hooks' import { calculateGasMargin } from 'utils/calculateGasMargin' import { useTokenContract } from 'hooks/useContract' @@ -24,18 +24,51 @@ export enum ApprovalState { APPROVED = 'APPROVED', } -// returns a variable indicating the state of the approval and a function which approves if necessary or early returns -export function useApproveCallback( - openTransactionConfirmationModal: (message: string) => void, - closeModals: () => void, - amountToApprove?: CurrencyAmount, +export interface ApproveCallbackParams { + openTransactionConfirmationModal: (message: string) => void + closeModals: () => void + amountToApprove?: CurrencyAmount spender?: string -): [ApprovalState, (optionalParams?: OptionalApproveCallbackParams) => Promise] { + amountToCheckAgainstAllowance?: CurrencyAmount +} + +// returns a variable indicating the state of the approval and a function which approves if necessary or early returns +export function useApproveCallback({ + openTransactionConfirmationModal, + closeModals, + amountToApprove, + spender, + amountToCheckAgainstAllowance, +}: ApproveCallbackParams): [ApprovalState, (optionalParams?: OptionalApproveCallbackParams) => Promise] { const { account, chainId } = useActiveWeb3React() const token = amountToApprove?.currency?.isToken ? amountToApprove.currency : undefined const currentAllowance = useTokenAllowance(token, account ?? undefined, spender) const pendingApproval = useHasPendingApproval(token?.address, spender) + // TODO: Nice to have, can be deleted + { + process.env.NODE_ENV !== 'production' && + console.debug(` + $$$$Approval metrics: + ==== + CurrentAllowance: ${currentAllowance?.toExact()} + raw: ${currentAllowance?.quotient.toString()} + ==== + amountToCheckAgainstApproval: ${amountToCheckAgainstAllowance?.toExact()} + raw: ${amountToCheckAgainstAllowance?.quotient.toString()} + ==== + amountToApprove: ${amountToApprove?.toExact()} + raw: ${amountToApprove?.quotient.toString()} + ==== + Needs approval?: ${ + !amountToCheckAgainstAllowance && !amountToApprove + ? 'Unknown - no amounts' + : currentAllowance && amountToApprove + ? currentAllowance.lessThan(amountToCheckAgainstAllowance || amountToApprove) + : 'unknown no currentAllowance' + } + `) + } // check the current approval status const approvalState: ApprovalState = useMemo(() => { if (!amountToApprove || !spender) return ApprovalState.UNKNOWN @@ -43,14 +76,13 @@ export function useApproveCallback( // we might not have enough data to know whether or not we need to approve if (!currentAllowance) return ApprovalState.UNKNOWN - // Return approval state - if (currentAllowance.lessThan(amountToApprove)) { - return pendingApproval ? ApprovalState.PENDING : ApprovalState.NOT_APPROVED - } else { - // Enough allowance - return ApprovalState.APPROVED - } - }, [amountToApprove, currentAllowance, pendingApproval, spender]) + // amountToApprove will be defined if currentAllowance is + return currentAllowance.lessThan(amountToCheckAgainstAllowance || amountToApprove) + ? pendingApproval + ? ApprovalState.PENDING + : ApprovalState.NOT_APPROVED + : ApprovalState.APPROVED + }, [amountToApprove, amountToCheckAgainstAllowance, currentAllowance, pendingApproval, spender]) const tokenContract = useTokenContract(token?.address) const addTransaction = useTransactionAdder() @@ -138,29 +170,29 @@ export function useApproveCallback( } // wraps useApproveCallback in the context of a swap -export function useApproveCallbackFromTrade( - openTransactionConfirmationModal: (message: string) => void, - closeModals: () => void, - trade: V2Trade | V3Trade | undefined, - allowedSlippage: Percent -) { - const { chainId } = useActiveWeb3React() - const v3SwapRouterAddress = chainId ? SWAP_ROUTER_ADDRESSES[chainId] : undefined - - const amountToApprove = useMemo( - () => (trade && trade.inputAmount.currency.isToken ? trade.maximumAmountIn(allowedSlippage) : undefined), - [trade, allowedSlippage] - ) - return useApproveCallback( - openTransactionConfirmationModal, - closeModals, - amountToApprove, - chainId - ? trade instanceof V2Trade - ? V2_ROUTER_ADDRESS[chainId] - : trade instanceof V3Trade - ? v3SwapRouterAddress - : undefined - : undefined - ) -} +// export function useApproveCallbackFromTrade( +// openTransactionConfirmationModal: (message: string) => void, +// closeModals: () => void, +// trade: V2Trade | V3Trade | undefined, +// allowedSlippage: Percent +// ) { +// const { chainId } = useActiveWeb3React() +// const v3SwapRouterAddress = chainId ? SWAP_ROUTER_ADDRESSES[chainId] : undefined + +// const amountToApprove = useMemo( +// () => (trade && trade.inputAmount.currency.isToken ? trade.maximumAmountIn(allowedSlippage) : undefined), +// [trade, allowedSlippage] +// ) +// return useApproveCallback( +// openTransactionConfirmationModal, +// closeModals, +// amountToApprove, +// chainId +// ? trade instanceof V2Trade +// ? V2_ROUTER_ADDRESS[chainId] +// : trade instanceof V3Trade +// ? v3SwapRouterAddress +// : undefined +// : undefined +// ) +// } diff --git a/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx b/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx index 808f26f3b..6391f0594 100644 --- a/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx +++ b/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx @@ -7,11 +7,11 @@ import { InvestTokenGroup, TokenLogo, InvestSummary, InvestInput, InvestAvailabl import { formatSmartLocaleAware } from 'utils/format' import Row from 'components/Row' import CheckCircle from 'assets/cow-swap/check.svg' -import { InvestOptionProps } from '.' -import { ApprovalState } from 'hooks/useApproveCallback' +import { InvestmentFlowProps } from '.' +import { ApprovalState, useApproveCallbackFromClaim } from 'hooks/useApproveCallback' import { useCurrencyBalance } from 'state/wallet/hooks' import { useActiveWeb3React } from 'hooks/web3' -import { useClaimDispatchers, useClaimState } from 'state/claim/hooks' +import { ClaimType, useClaimDispatchers, useClaimState } from 'state/claim/hooks' import { StyledNumericalInput } from 'components/CurrencyInputPanel/CurrencyInputPanelMod' import { ButtonConfirmed } from 'components/Button' @@ -23,6 +23,8 @@ import { calculateInvestmentAmounts, calculatePercentage } from 'state/claim/hoo import { AMOUNT_PRECISION, PERCENTAGE_PRECISION } from 'constants/index' import { useGasPrices } from 'state/gas/hooks' import { AVG_APPROVE_COST_GWEI } from 'components/swap/EthWethWrap/helpers' +import { EnhancedUserClaimData } from '../types' +import { OperationType } from 'components/TransactionConfirmationModal' const ErrorMsgs = { InsufficientBalance: (symbol = '') => `Insufficient ${symbol} balance to cover investment amount`, @@ -33,14 +35,44 @@ const ErrorMsgs = { `You might not have enough ${symbol} to pay for the network transaction fee (estimated ${amount} ${symbol})`, } -export default function InvestOption({ approveData, claim, optionIndex }: InvestOptionProps) { +type InvestOptionProps = { + claim: EnhancedUserClaimData + optionIndex: number + openModal: InvestmentFlowProps['modalCbs']['openModal'] + closeModal: InvestmentFlowProps['modalCbs']['closeModal'] +} + +const _claimApproveMessageMap = (type: ClaimType) => { + switch (type) { + case ClaimType.GnoOption: + return 'Approving GNO for investing in vCOW' + case ClaimType.Investor: + return 'Approving USDC for investing in vCOW' + // Shouldn't happen, type safe + default: + return 'Unknown token approval. Please check configuration.' + } +} + +export default function InvestOption({ claim, optionIndex, openModal, closeModal }: InvestOptionProps) { const { currencyAmount, price, cost: maxCost } = claim + + const { account, chainId } = useActiveWeb3React() const { updateInvestAmount, updateInvestError } = useClaimDispatchers() const { investFlowData, activeClaimAccount, estimatedGas } = useClaimState() - const { handleSetError, handleCloseError, ErrorModal } = useErrorModal() + const investmentAmount = investFlowData[optionIndex].investedAmount - const { account, chainId } = useActiveWeb3React() + // Approve hooks + const [approveState, approveCallback] = useApproveCallbackFromClaim({ + openTransactionConfirmationModal: () => openModal(_claimApproveMessageMap(claim.type), OperationType.APPROVE_TOKEN), + closeModals: closeModal, + claim, + }) + + const isEtherApproveState = approveState === ApprovalState.UNKNOWN + + const { handleSetError, handleCloseError, ErrorModal } = useErrorModal() const [percentage, setPercentage] = useState('0') const [typedValue, setTypedValue] = useState('') @@ -72,7 +104,7 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest const isSelfClaiming = account === activeClaimAccount const noBalance = !balance || balance.equalTo('0') - const isApproved = approveData?.approveState === ApprovalState.APPROVED + const isApproved = approveState === ApprovalState.APPROVED const gasCost = useMemo(() => { if (!estimatedGas || !isNative) { @@ -97,9 +129,6 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest setTypedValue(value.toExact() || '') }, [balance, maxCost, noBalance]) - // Cache approveData methods - const approveCallback = approveData?.approveCallback - const approveState = approveData?.approveState // Save "local" approving state (pre-BC) for rendering spinners etc const [approving, setApproving] = useState(false) const handleApprove = useCallback(async () => { @@ -121,8 +150,8 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest }, [approveCallback, handleCloseError, handleSetError, token?.symbol]) const vCowAmount = useMemo( - () => calculateInvestmentAmounts(claim, investedAmount)?.vCowAmount, - [claim, investedAmount] + () => calculateInvestmentAmounts(claim, investmentAmount)?.vCowAmount, + [claim, investmentAmount] ) // if there is investmentAmount in redux state for this option set it as typedValue @@ -238,9 +267,9 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest Token approval - {approveData ? ( + {!isEtherApproveState ? ( - {approveData.approveState !== ApprovalState.APPROVED ? ( + {approveState !== ApprovalState.APPROVED ? ( `${currencyAmount?.currency?.symbol} not approved` ) : ( @@ -257,8 +286,8 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest )} - {/* Approve button - @biocom styles for this found in ./styled > InputSummary > ${ButtonPrimary}*/} - {approveData && approveState !== ApprovalState.APPROVED && ( + {/* Token Approve buton - not shown for ETH */} + {!isEtherApproveState && approveState !== ApprovalState.APPROVED && ( {approving || approveState === ApprovalState.PENDING ? ( - ) : approveData ? ( + ) : ( Approve {currencyAmount?.currency?.symbol} - ) : null} + )} )} diff --git a/src/custom/pages/Claim/InvestmentFlow/index.tsx b/src/custom/pages/Claim/InvestmentFlow/index.tsx index b10a227f1..95f31e046 100644 --- a/src/custom/pages/Claim/InvestmentFlow/index.tsx +++ b/src/custom/pages/Claim/InvestmentFlow/index.tsx @@ -16,7 +16,6 @@ import { ClaimSummaryView } from 'pages/Claim/ClaimSummary' import { Stepper } from 'components/Stepper' import { - ClaimType, useClaimState, useUserEnhancedClaimData, useClaimDispatchers, @@ -26,7 +25,6 @@ import { ClaimStatus } from 'state/claim/actions' 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' @@ -38,6 +36,7 @@ import { ExplorerDataType } from 'utils/getExplorerLink' import { BadgeVariant } from 'components/Badge' import { DollarSign, Icon, Send } from 'react-feather' +import { OperationType } from 'components/TransactionConfirmationModal' const STEPS_DATA = [ { @@ -53,34 +52,11 @@ const STEPS_DATA = [ }, ] -export type InvestOptionProps = { - claim: EnhancedUserClaimData - optionIndex: number - approveData: - | { approveState: ApprovalState; approveCallback: (optionalParams?: OptionalApproveCallbackParams) => void } - | undefined -} - -type InvestmentFlowProps = Pick & { +export type InvestmentFlowProps = Pick & { isAirdropOnly: boolean - gnoApproveData: InvestOptionProps['approveData'] - usdcApproveData: InvestOptionProps['approveData'] -} - -type TokenApproveName = 'gnoApproveData' | 'usdcApproveData' -type TokenApproveData = { - [key in TokenApproveName]: InvestOptionProps['approveData'] | undefined -} - -// map claim type to token approve data -function _claimToTokenApproveData(claimType: ClaimType, tokenApproveData: TokenApproveData) { - switch (claimType) { - case ClaimType.GnoOption: - return tokenApproveData.gnoApproveData - case ClaimType.Investor: - return tokenApproveData.usdcApproveData - default: - return undefined + modalCbs: { + openModal: (message: string, operationType: OperationType) => void + closeModal: () => void } } @@ -149,7 +125,7 @@ function AccountDetails({ label, account, connectedAccount, Icon }: AccountDetai ) } -export default function InvestmentFlow({ hasClaims, isAirdropOnly, ...tokenApproveData }: InvestmentFlowProps) { +export default function InvestmentFlow({ hasClaims, isAirdropOnly, modalCbs }: InvestmentFlowProps) { const { account } = useActiveWeb3React() const { selected, activeClaimAccount, claimStatus, isInvestFlowActive, investFlowStep, investFlowData } = useClaimState() @@ -233,12 +209,7 @@ export default function InvestmentFlow({ hasClaims, isAirdropOnly, ...tokenAppro

{selectedClaims.map((claim, index) => ( - + ))} {hasError && Fix the errors before continuing} diff --git a/src/custom/pages/Claim/index.tsx b/src/custom/pages/Claim/index.tsx index 79b9ae8ef..146432ca7 100644 --- a/src/custom/pages/Claim/index.tsx +++ b/src/custom/pages/Claim/index.tsx @@ -1,5 +1,4 @@ import { useCallback, useEffect, useMemo } from 'react' -import { CurrencyAmount, MaxUint256 } from '@uniswap/sdk-core' import { useActiveWeb3React } from 'hooks/web3' import { useUserEnhancedClaimData, useUserUnclaimedAmount, useClaimCallback, ClaimInput } from 'state/claim/hooks' import { PageWrapper } from 'pages/Claim/styled' @@ -21,18 +20,12 @@ import InvestmentFlow from './InvestmentFlow' import { useClaimDispatchers, useClaimState } from 'state/claim/hooks' import { ClaimStatus } from 'state/claim/actions' -import { useApproveCallbackFromClaim } from 'hooks/useApproveCallback' import { OperationType } from 'components/TransactionConfirmationModal' import useTransactionConfirmationModal from 'hooks/useTransactionConfirmationModal' -import { GNO, USDC_BY_CHAIN } from 'constants/tokens' -import { isSupportedChain } from 'utils/supportedChainId' import { useErrorModal } from 'hooks/useErrorMessageAndModal' import FooterNavButtons from './FooterNavButtons' -const GNO_CLAIM_APPROVE_MESSAGE = 'Approving GNO for investing in vCOW' -const USDC_CLAIM_APPROVE_MESSAGE = 'Approving USDC for investing in vCOW' - /* TODO: Replace URLs with the actual final URL destinations */ export const COW_LINKS = { vCowPost: 'https://cow.fi/', @@ -40,7 +33,7 @@ export const COW_LINKS = { } export default function Claim() { - const { account, chainId } = useActiveWeb3React() + const { account } = useActiveWeb3React() const { // address/ENS address @@ -188,20 +181,6 @@ export default function Claim() { OperationType.APPROVE_TOKEN ) - const [gnoApproveState, gnoApproveCallback] = useApproveCallbackFromClaim( - () => openModal(GNO_CLAIM_APPROVE_MESSAGE, OperationType.APPROVE_TOKEN), - closeModal, - // approve max unit256 amount - isSupportedChain(chainId) ? CurrencyAmount.fromRawAmount(GNO[chainId], MaxUint256) : undefined - ) - - const [usdcApproveState, usdcApproveCallback] = useApproveCallbackFromClaim( - () => openModal(USDC_CLAIM_APPROVE_MESSAGE, OperationType.APPROVE_TOKEN), - closeModal, - // approve max unit256 amount - isSupportedChain(chainId) ? CurrencyAmount.fromRawAmount(USDC_BY_CHAIN[chainId], MaxUint256) : undefined - ) - return ( {/* Approve confirmation modal */} @@ -231,18 +210,7 @@ export default function Claim() { {/* IS Airdrop + investing (advanced) */} {/* Investing vCOW flow (advanced) */} - + openTransactionConfirmationModal(message, OperationType.APPROVE_TOKEN), + const [approvalState, approveCallback] = useApproveCallbackFromTrade({ + openTransactionConfirmationModal: (message: string) => + openTransactionConfirmationModal(message, OperationType.APPROVE_TOKEN), closeModals, trade, - allowedSlippage - ) + allowedSlippage, + }) const prevApprovalState = usePrevious(approvalState) const { state: signatureState, diff --git a/src/custom/state/claim/hooks/utils.ts b/src/custom/state/claim/hooks/utils.ts index f26333856..8760c4f03 100644 --- a/src/custom/state/claim/hooks/utils.ts +++ b/src/custom/state/claim/hooks/utils.ts @@ -164,17 +164,32 @@ export type PaidClaimTypeToPriceMap = { [type in ClaimType]: { token: Token; amount: string } | undefined } +export function claimTypeToToken(type: ClaimType, chainId: SupportedChainId) { + switch (type) { + case ClaimType.GnoOption: + return GNO[chainId] + case ClaimType.Investor: + return USDC_BY_CHAIN[chainId] + case ClaimType.UserOption: + return GpEther.onChain(chainId) + case ClaimType.Advisor: + case ClaimType.Airdrop: + case ClaimType.Team: + return undefined + } +} + /** * Helper function to get vCow price based on claim type and chainId */ export function claimTypeToTokenAmount(type: ClaimType, chainId: SupportedChainId, prices: VCowPrices) { switch (type) { case ClaimType.GnoOption: - return { token: GNO[chainId], amount: prices.gno as string } + return { token: claimTypeToToken(ClaimType.GnoOption, chainId) as Token, amount: prices.gno as string } case ClaimType.Investor: - return { token: USDC_BY_CHAIN[chainId], amount: prices.usdc as string } + return { token: claimTypeToToken(ClaimType.Investor, chainId) as Token, amount: prices.usdc as string } case ClaimType.UserOption: - return { token: GpEther.onChain(chainId), amount: prices.native as string } + return { token: claimTypeToToken(ClaimType.UserOption, chainId) as GpEther, amount: prices.native as string } default: return undefined } diff --git a/src/custom/state/swap/extension.ts b/src/custom/state/swap/extension.ts index a15d5a440..082644396 100644 --- a/src/custom/state/swap/extension.ts +++ b/src/custom/state/swap/extension.ts @@ -15,6 +15,12 @@ interface TradeParams { export const stringToCurrency = (amount: string, currency: Currency) => CurrencyAmount.fromRawAmount(currency, JSBI.BigInt(amount)) +export const tryAtomsToCurrency = (atoms: string | undefined, currency: Currency | undefined) => { + if (!atoms || !currency) return undefined + + return stringToCurrency(atoms, currency) +} + /** * useTradeExactInWithFee * @description wraps useTradeExactIn and returns an extended trade object with the fee adjusted values