fix partial withdraw

This commit is contained in:
Adrian Brzeziński 2024-02-27 17:13:31 +01:00
parent a60b189367
commit 19ee5bb07b
2 changed files with 85 additions and 8 deletions

View File

@ -100,13 +100,39 @@ function UnstakeForm({ token: selectedToken }: UnstakeFormProps) {
const { connected, publicKey } = useWallet()
const stakeBankAmount =
mangoAccount && stakeBank && mangoAccount.getTokenBalance(stakeBank)
const borrowAmount =
mangoAccount && borrowBank && mangoAccount.getTokenBalance(borrowBank)
const leverage = useMemo(() => {
try {
if (stakeBankAmount && borrowAmount) {
const lev = stakeBankAmount
.div(
stakeBankAmount.sub(
borrowAmount.abs().div(stakeBank.getAssetPrice()),
),
)
.toNumber()
return Math.sign(lev) !== -1 ? lev : 1
}
return 1
} catch (e) {
console.log(e)
return 1
}
}, [stakeBankAmount, borrowAmount, stakeBank])
const tokenMax = useMemo(() => {
if (!stakeBank || !mangoAccount) return { maxAmount: 0.0, maxDecimals: 6 }
return {
maxAmount: mangoAccount.getTokenBalanceUi(stakeBank),
maxAmount: mangoAccount.getTokenBalanceUi(stakeBank) / leverage,
maxDecimals: stakeBank.mintDecimals,
}
}, [stakeBank, mangoAccount])
}, [stakeBank, mangoAccount, leverage])
const setMax = useCallback(() => {
const max = floorToDecimal(tokenMax.maxAmount, tokenMax.maxDecimals)
@ -168,18 +194,22 @@ function UnstakeForm({ token: selectedToken }: UnstakeFormProps) {
mangoAccount.getTokenBalanceUi(borrowBank),
)
const amountToRepay = (leverage - 1) * Number(inputAmount)
const { signature: tx } = await unstakeAndSwap(
client,
group,
mangoAccount,
stakeBank.mint,
amountToRepay,
)
notify({
title: 'Swap Transaction confirmed.',
type: 'success',
txid: tx,
})
await sleep(300)
await sleep(500)
await actions.fetchMangoAccounts(mangoAccount.owner)
await actions.fetchWalletTokens(publicKey)
mangoAccount = mangoStore.getState().mangoAccount.current
@ -207,7 +237,12 @@ function UnstakeForm({ token: selectedToken }: UnstakeFormProps) {
await actions.fetchMangoAccounts(mangoAccount.owner)
await actions.fetchWalletTokens(publicKey)
} catch (e) {
console.error('Error depositing:', e)
console.error('Error withdrawing:', e)
notify({
title: 'Error withdrawing',
description: `${e}`,
type: 'error',
})
setSubmitting(false)
if (!isMangoError(e)) return
notify({
@ -217,7 +252,7 @@ function UnstakeForm({ token: selectedToken }: UnstakeFormProps) {
type: 'error',
})
}
}, [borrowBank, stakeBank, publicKey, inputAmount])
}, [ipAllowed, stakeBank, borrowBank, publicKey, inputAmount, leverage])
const maxWithdraw =
group && mangoAccount && stakeBank
@ -351,6 +386,27 @@ function UnstakeForm({ token: selectedToken }: UnstakeFormProps) {
/>
</span>
</div>
<div className="flex justify-between">
<p className="text-th-fgd-4">
Staked Amount with borrow
</p>
<span className="font-bold text-th-fgd-1">
<BankAmountWithValue
amount={tokenMax.maxAmount * leverage}
bank={stakeBank}
/>
</span>
</div>
<div className="flex justify-between">
<p className="text-th-fgd-4">Leverage</p>
<span className="font-bold text-th-fgd-1">
<FormatNumericValue
value={leverage}
decimals={2}
/>
x
</span>
</div>
<div className="flex justify-between">
<p className="text-th-fgd-4">USDC borrowed</p>
{borrowBank ? (

View File

@ -14,6 +14,7 @@ import {
createAssociatedTokenAccountIdempotentInstruction,
getAssociatedTokenAddress,
toNative,
toNativeI80F48,
toUiDecimals,
} from '@blockworks-foundation/mango-v4'
import { TOKEN_PROGRAM_ID } from '@solana/spl-governance'
@ -36,6 +37,7 @@ import {
} from '@solana/web3.js'
import { floorToDecimal } from './numbers'
import { BOOST_ACCOUNT_PREFIX } from './constants'
import { notify } from './notifications'
export const withdrawAndClose = async (
client: MangoClient,
@ -111,6 +113,7 @@ export const unstakeAndSwap = async (
group: Group,
mangoAccount: MangoAccount,
stakeMintPk: PublicKey,
amountToRepay?: number,
): Promise<MangoSignatureStatus> => {
console.log('unstake and swap')
@ -123,15 +126,27 @@ export const unstakeAndSwap = async (
throw Error('Unable to find borrow bank or stake bank or mango account')
}
const borrowed = mangoAccount.getTokenBalance(borrowBank)
console.log(borrowed)
let swapAlts: AddressLookupTableAccount[] = []
if (borrowed.toNumber() < 0) {
const toRepay = Math.ceil(
(amountToRepay
? toNativeI80F48(amountToRepay, stakeBank.mintDecimals).mul(
stakeBank.getAssetPrice(),
)
: borrowed.abs()
)
.add(I80F48.fromNumber(100))
.toNumber(),
)
console.log('borrowedSol amount: ', borrowed.toNumber())
console.log('borrow needed to repay for withdraw', toRepay)
const { bestRoute: selectedRoute } = await fetchJupiterRoutes(
stakeMintPk.toString(),
borrowBank.mint.toString(),
Math.ceil(borrowed.abs().add(I80F48.fromNumber(100)).toNumber()),
toRepay,
500,
'ExactOut',
)
@ -749,12 +764,18 @@ const fetchJupiterRoutes = async (
`https://quote-api.jup.ag/v6/quote?${paramsString}`,
)
const res = await response.json()
if (res.error) {
throw res.error
}
return {
bestRoute: res as RouteInfo | null,
}
} catch (e) {
console.log(e, 'Error finding jupiter route')
notify({
title: `Error finding jupiter route ${e}`,
type: 'info',
})
return {
bestRoute: null,
}