Skip to content

Commit

Permalink
leave enough sol for transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
saml33 committed Aug 6, 2024
1 parent 8bc0f1b commit 0d19871
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 11 deletions.
28 changes: 27 additions & 1 deletion components/Stake.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useMemo, useState } from 'react'
import StakeForm from '@components/StakeForm'
import StakeForm, { MIN_SOL_BALANCE_FOR_ACCOUNT } from '@components/StakeForm'
import mangoStore from '@store/mangoStore'
import { getStakableTokensDataForTokenName } from 'utils/tokens'
import { ArrowLeftIcon, XMarkIcon } from '@heroicons/react/20/solid'
Expand All @@ -10,6 +10,9 @@ import { IconButton } from './shared/Button'
import HeroTokenButton from './HeroTokenButton'
import useStakeableTokens, { StakeableToken } from 'hooks/useStakeableTokens'
import { useTheme } from 'next-themes'
import { WRAPPED_SOL_MINT } from '@project-serum/serum/lib/token-instructions'
import usePositions from 'hooks/usePositions'
import InlineNotification from './shared/InlineNotification'

const set = mangoStore.getState().set

Expand All @@ -30,6 +33,8 @@ export const SOL_YIELD = [

const Stake = () => {
const { theme } = useTheme()
const { positions } = usePositions()
const walletTokens = mangoStore((s) => s.wallet.tokens)
const [showTokenSelect, setShowTokenSelect] = useState(false)
const selectedToken = mangoStore((s) => s.selectedToken)
const { stakeableTokens } = useStakeableTokens()
Expand All @@ -49,6 +54,18 @@ const Stake = () => {
})
}, [stakeableTokens])

const solBalance = useMemo(() => {
if (!walletTokens?.length) return 0
const solInWallet = walletTokens.find(
(token) => token.mint.toString() === WRAPPED_SOL_MINT.toString(),
)
return solInWallet ? solInWallet.uiAmount : 0
}, [walletTokens])

const isExistingPosition = useMemo(() => {
return positions.find((p) => p.bank.name === selectedToken)
}, [positions, selectedToken])

// const swapUrl = `https://app.mango.markets/swap?in=USDC&out=${selectedToken}&walletSwap=true`

return (
Expand Down Expand Up @@ -144,6 +161,15 @@ const Stake = () => {
</IconButton>
<h2>Add {selectedToken}</h2>
</div>
{solBalance < MIN_SOL_BALANCE_FOR_ACCOUNT &&
!isExistingPosition ? (
<div className="mb-4">
<InlineNotification
type="error"
desc={`You need at least ${MIN_SOL_BALANCE_FOR_ACCOUNT} SOL. Most of this is refunded when you close your position and the rest is to pay for transactions.`}
/>
</div>
) : null}
{selectedToken === 'USDC' ? (
<DespositForm
token="USDC"
Expand Down
48 changes: 38 additions & 10 deletions components/StakeForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import Button, { IconButton } from './shared/Button'
import Loading from './shared/Loading'
import MaxAmountButton from '@components/shared/MaxAmountButton'
import Tooltip from '@components/shared/Tooltip'
import SolBalanceWarnings from '@components/shared/SolBalanceWarnings'
import useSolBalance from 'hooks/useSolBalance'
import {
floorToDecimal,
Expand Down Expand Up @@ -53,11 +52,15 @@ import {
ClientContextKeys,
JLP_BORROW_TOKEN,
LST_BORROW_TOKEN,
MIN_SOL_BALANCE,
} from 'utils/constants'
import Image from 'next/image'
import useQuoteRoutes from 'hooks/useQuoteRoutes'
import { YIELD_BUTTON_CLASSES } from './Stake'
import { useTheme } from 'next-themes'
import usePositions from 'hooks/usePositions'

export const MIN_SOL_BALANCE_FOR_ACCOUNT = 0.045

const set = mangoStore.getState().set

Expand Down Expand Up @@ -106,6 +109,7 @@ export const walletBalanceForToken = (

function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) {
const { theme } = useTheme()
const { positions } = usePositions()
const { t } = useTranslation(['common', 'account'])
const [depositToken, setDepositToken] = useState(selectedToken)
const [inputAmount, setInputAmount] = useState('')
Expand Down Expand Up @@ -200,29 +204,43 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) {
return walletBalanceForToken(walletTokens, depositBank.name, clientContext)
}, [walletTokens, depositBank, clientContext])

const minSol = useMemo(() => {
const isExistingPosition = positions.find(
(p) => p.bank.name === selectedToken,
)
return isExistingPosition ? MIN_SOL_BALANCE : MIN_SOL_BALANCE_FOR_ACCOUNT
}, [positions, selectedToken])

const setMax = useCallback(() => {
if (!depositBank) return
let max = new Decimal(0)

if (depositBank.name === 'SOL') {
max = floorToDecimal(tokenMax.maxAmount - 0.01, depositBank.mintDecimals)
if (tokenMax.maxAmount > minSol) {
max = floorToDecimal(
tokenMax.maxAmount - minSol,
depositBank.mintDecimals,
)
}
} else {
max = floorToDecimal(tokenMax.maxAmount, depositBank.mintDecimals)
}
setInputAmount(max.toFixed())
setSizePercentage('100')
}, [depositBank, tokenMax])
}, [depositBank, minSol, tokenMax])

const handleSizePercentage = useCallback(
(percentage: string) => {
if (!depositBank) return
setSizePercentage(percentage)
let amount = new Decimal(0)
if (depositBank.name === 'SOL' && percentage === '100') {
amount = floorToDecimal(
new Decimal(percentage).div(100).mul(tokenMax.maxAmount),
depositBank.mintDecimals,
).sub(0.01)
if (tokenMax.maxAmount > minSol) {
amount = floorToDecimal(
new Decimal(percentage).div(100).mul(tokenMax.maxAmount),
depositBank.mintDecimals,
).sub(minSol)
}
} else {
amount = floorToDecimal(
new Decimal(percentage).div(100).mul(tokenMax.maxAmount),
Expand All @@ -231,7 +249,7 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) {
}
setInputAmount(amount.toFixed())
},
[tokenMax, depositBank],
[tokenMax, depositBank, minSol],
)

const amountToBorrow = useMemo(() => {
Expand Down Expand Up @@ -479,12 +497,12 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) {
/>
<div className="flex flex-col justify-between pt-6 md:pt-8">
<div className="pb-8">
<SolBalanceWarnings
{/* <SolBalanceWarnings
amount={inputAmount}
className="mb-4"
setAmount={setInputAmount}
selectedToken={selectedToken}
/>
/> */}
{availableVaultBalance < amountToBorrow && borrowBank && (
<div className="mb-4">
<InlineNotification
Expand Down Expand Up @@ -596,6 +614,16 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) {
)}
</div>
) : null}

{depositBank?.name === 'SOL' &&
tokenMax.maxAmount - minSol < parseFloat(inputAmount) ? (
<div className="mt-2">
<InlineNotification
type="error"
desc={`Max exceeded. You need ${minSol} SOL for this transaction. Most of this will be refunded when you close your position.`}
/>
</div>
) : null}
</>
)}
</div>
Expand Down

0 comments on commit 0d19871

Please sign in to comment.