Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Warning claim too much eth #2256

Merged
merged 5 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
29 changes: 25 additions & 4 deletions src/custom/components/swap/EthWethWrap/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { parseUnits } from '@ethersproject/units'
import { CurrencyAmount, Currency } from '@uniswap/sdk-core'
import { BigNumber } from '@ethersproject/bignumber'
// eslint-disable-next-line no-restricted-imports
import { t } from '@lingui/macro'
import { useGasPrices } from 'state/gas/hooks'

export const MINIMUM_TXS = '10'
export const AVG_APPROVE_COST_GWEI = '50000'
Expand All @@ -18,11 +20,12 @@ export function _isLowBalanceCheck({
nativeInput,
balance,
}: {
threshold: CurrencyAmount<Currency>
txCost: CurrencyAmount<Currency>
threshold?: CurrencyAmount<Currency>
txCost?: CurrencyAmount<Currency>
nativeInput?: CurrencyAmount<Currency>
balance?: CurrencyAmount<Currency>
}) {
if (!threshold || !txCost) return false
if (!nativeInput || !balance || nativeInput.add(txCost).greaterThan(balance)) return true
// OK if: users_balance - (amt_input + 1_tx_cost) > low_balance_threshold
return balance.subtract(nativeInput.add(txCost)).lessThan(threshold)
Expand All @@ -35,11 +38,29 @@ export const _getAvailableTransactions = ({
}: {
nativeBalance?: CurrencyAmount<Currency>
nativeInput?: CurrencyAmount<Currency>
singleTxCost: CurrencyAmount<Currency>
singleTxCost?: CurrencyAmount<Currency>
}) => {
if (!nativeBalance || !nativeInput || nativeBalance.lessThan(nativeInput.add(singleTxCost))) return null
if (!nativeBalance || !nativeInput || !singleTxCost || nativeBalance.lessThan(nativeInput.add(singleTxCost))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you cache the last nativeBalance check?

return null
}

// USER_BALANCE - (USER_WRAP_AMT + 1_TX_CST) / 1_TX_COST = AVAILABLE_TXS
const txsAvailable = nativeBalance.subtract(nativeInput.add(singleTxCost)).divide(singleTxCost)
return txsAvailable.lessThan('1') ? null : txsAvailable.toSignificant(1)
}

export function _estimateTxCost(gasPrice: ReturnType<typeof useGasPrices>, native: Currency | undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think is a bit strange to expose a function starting with an underscore. I assume this was a "private function" convention. If it's useful to expose, maybe should be without?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, not sure if this should live in a more generic place instead of inside swap -> wrapEth

if (!native) {
return {}
}
// TODO: should use DEFAULT_GAS_FEE from backup source
// when/if implemented
const gas = gasPrice?.standard || DEFAULT_GAS_FEE

const amount = BigNumber.from(gas).mul(MINIMUM_TXS).mul(AVG_APPROVE_COST_GWEI)

return {
multiTxCost: CurrencyAmount.fromRawAmount(native, amount.toString()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I felt the name was a bit hard to understand. What about recomendedMarginalEther? i also don't love it. Maybe you find a better one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just moving this fn around.
If you want to complain about the names bother @W3stside =P

But ok... I'll refactor this next week when I'm more in the mood.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its just a nit, the PR was approved :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wrote this? 😂

singleTxCost: CurrencyAmount.fromFractionalAmount(native, amount.toString(), MINIMUM_TXS),
}
}
23 changes: 2 additions & 21 deletions src/custom/components/swap/EthWethWrap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,7 @@ import { useIsTransactionPending } from 'state/enhancedTransactions/hooks'
import Modal from 'components/Modal'
import { useGasPrices } from 'state/gas/hooks'
import { useActiveWeb3React } from 'hooks/web3'
import { BigNumber } from '@ethersproject/bignumber'
import {
DEFAULT_GAS_FEE,
MINIMUM_TXS,
AVG_APPROVE_COST_GWEI,
_isLowBalanceCheck,
_setNativeLowBalanceError,
_getAvailableTransactions,
} from './helpers'
import { _isLowBalanceCheck, _setNativeLowBalanceError, _getAvailableTransactions, _estimateTxCost } from './helpers'
import { Trans } from '@lingui/macro'

const Wrapper = styled.div`
Expand Down Expand Up @@ -152,18 +144,7 @@ export default function EthWethWrap({ account, native, nativeInput, wrapped, wra
const gasPrice = useGasPrices(chainId)

// returns the cost of 1 tx and multi txs
const { multiTxCost, singleTxCost } = useMemo(() => {
// TODO: should use DEFAULT_GAS_FEE from backup source
// when/if implemented
const gas = gasPrice?.standard || DEFAULT_GAS_FEE

const amount = BigNumber.from(gas).mul(MINIMUM_TXS).mul(AVG_APPROVE_COST_GWEI)

return {
multiTxCost: CurrencyAmount.fromRawAmount(native, amount.toString()),
singleTxCost: CurrencyAmount.fromFractionalAmount(native, amount.toString(), MINIMUM_TXS),
}
}, [gasPrice, native])
const { multiTxCost, singleTxCost } = useMemo(() => _estimateTxCost(gasPrice, native), [gasPrice, native])

const isWrapPending = useIsTransactionPending(pendingHash)
const [nativeBalance, wrappedBalance] = useCurrencyBalances(account, [native, wrapped])
Expand Down
2 changes: 0 additions & 2 deletions src/custom/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ export const WETH_LOGO_URI =
export const XDAI_LOGO_URI =
'https://raw.githubusercontent.com/1Hive/default-token-list/master/src/assets/xdai/0xe91d153e0b41518a2ce8dd3d7944fa863463a97d/logo.png'

// 0.1 balance threshold
export const LOW_NATIVE_BALANCE_THRESHOLD = new Fraction('1', '10')
export const DOCS_LINK = 'https://docs.cow.fi'
export const CONTRACTS_CODE_LINK = 'https://github.com/gnosis/gp-v2-contracts'
export const CODE_LINK = 'https://github.com/gnosis/gp-swap-ui'
Expand Down
30 changes: 27 additions & 3 deletions src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@ import { useErrorModal } from 'hooks/useErrorMessageAndModal'
import { tryParseAmount } from 'state/swap/hooks'
import { calculateInvestmentAmounts, calculatePercentage } from 'state/claim/hooks/utils'
import { AMOUNT_PRECISION, PERCENTAGE_PRECISION } from 'constants/index'
import { useGasPrices } from 'state/gas/hooks'
import { _estimateTxCost } from 'components/swap/EthWethWrap/helpers'
import { useWalletInfo } from 'hooks/useWalletInfo'

const ErrorMsgs = {
InsufficientBalance: (symbol = '') => `Insufficient ${symbol} balance to cover investment amount`,
OverMaxInvestment: `Your investment amount can't be above the maximum investment allowed`,
InvestmentIsZero: `Your investment amount can't be zero`,
NotApproved: (symbol = '') => `Please approve ${symbol} token`,
InsufficientNativeBalance: (symbol = '', action = "won't") =>
`You ${action} have enough ${symbol} to pay the network transaction fee`,
}

export default function InvestOption({ approveData, claim, optionIndex }: InvestOptionProps) {
Expand All @@ -35,10 +40,12 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest

const { handleSetError, handleCloseError, ErrorModal } = useErrorModal()

const { account } = useActiveWeb3React()
const { account, chainId } = useActiveWeb3React()
const { isSmartContractWallet } = useWalletInfo()

const [percentage, setPercentage] = useState<string>('0')
const [typedValue, setTypedValue] = useState<string>('0')
const [inputWarning, setInputWarning] = useState<string>('')

const investedAmount = investFlowData[optionIndex].investedAmount
const inputError = investFlowData[optionIndex].error
Expand All @@ -60,6 +67,12 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
const token = currencyAmount?.currency
const balance = useCurrencyBalance(account || undefined, token)

const gasPrice = useGasPrices(chainId)
const { singleTxCost } = useMemo(
() => _estimateTxCost(gasPrice, token?.isNative ? token : undefined),
[gasPrice, token]
)

const isSelfClaiming = account === activeClaimAccount
const noBalance = !balance || balance.equalTo('0')

Expand Down Expand Up @@ -132,6 +145,7 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
// handle input value change
useEffect(() => {
let error = null
let warning

const parsedAmount = tryParseAmount(typedValue, token)

Expand All @@ -150,7 +164,14 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
error = ErrorMsgs.OverMaxInvestment
} else if (parsedAmount.greaterThan(balance)) {
error = ErrorMsgs.InsufficientBalance(token?.symbol)
} else if (isNative && parsedAmount && singleTxCost?.add(parsedAmount).greaterThan(balance)) {
if (isSmartContractWallet) {
warning = ErrorMsgs.InsufficientNativeBalance(token?.symbol, 'might not')
} else {
error = ErrorMsgs.InsufficientNativeBalance(token?.symbol)
}
}
setInputWarning(warning || '')

if (error) {
// if there is error set it in redux
Expand All @@ -162,7 +183,7 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
}
// basically the magic happens in this block

// update redux state to remove errro for this field
// update redux state to remove error for this field
resetInputError()

// update redux state with new investAmount value
Expand All @@ -182,6 +203,8 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
setInputError,
resetInputError,
setInvestedAmount,
isSmartContractWallet,
singleTxCost,
])

return (
Expand Down Expand Up @@ -284,7 +307,8 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
</label>
<i>Receive: {formatSmartLocaleAware(vCowAmount, AMOUNT_PRECISION) || 0} vCOW</i>
{/* Insufficient balance validation error */}
{inputError ? <small>{inputError}</small> : ''}
{inputError && <small>{inputError}</small>}
{inputWarning && <small className="warn">{inputWarning}</small>}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will probably refactor to pass a prop instead of applying a className.

</div>
</InvestInput>
</span>
Expand Down
4 changes: 4 additions & 0 deletions src/custom/pages/Claim/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,10 @@ export const InvestInput = styled.span`
color: red;
margin: 12px 0;
font-size: 15px;

&.warn {
color: orange;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@biocom might want to review colors for validations

}
}

> div > i {
Expand Down