better handling of rounding issues in borrow and withdraw
This commit is contained in:
parent
567e38cbcc
commit
a0ef8f1e8e
|
@ -7,7 +7,8 @@ import useMangoStore from '../stores/useMangoStore'
|
|||
import useMarketList from '../hooks/useMarketList'
|
||||
import {
|
||||
getSymbolForTokenMintAddress,
|
||||
formatBalanceDisplay,
|
||||
displayDepositsForMarginAccount,
|
||||
floorToDecimal,
|
||||
} from '../utils/index'
|
||||
import useConnection from '../hooks/useConnection'
|
||||
import { borrowAndWithdraw, withdraw } from '../utils/mango'
|
||||
|
@ -59,7 +60,11 @@ const WithdrawModal = ({ isOpen, onClose }) => {
|
|||
const getMaxForSelectedAccount = () => {
|
||||
const marginAccount = useMangoStore.getState().selectedMarginAccount.current
|
||||
const mangoGroup = useMangoStore.getState().selectedMangoGroup.current
|
||||
return marginAccount.getUiDeposit(mangoGroup, tokenIndex)
|
||||
return displayDepositsForMarginAccount(
|
||||
marginAccount,
|
||||
mangoGroup,
|
||||
tokenIndex
|
||||
)
|
||||
}
|
||||
|
||||
const setMaxForSelectedAccount = () => {
|
||||
|
@ -72,26 +77,27 @@ const WithdrawModal = ({ isOpen, onClose }) => {
|
|||
}
|
||||
|
||||
const setMaxBorrowForSelectedAccount = async () => {
|
||||
// get index prices
|
||||
const prices = await selectedMangoGroup.getPrices(connection)
|
||||
const assetsValBeforeTokenBal = selectedMarginAccount.getAssetsVal(
|
||||
selectedMangoGroup,
|
||||
prices
|
||||
)
|
||||
// get value of margin account assets minus the selected token
|
||||
const assetsVal =
|
||||
assetsValBeforeTokenBal - getMaxForSelectedAccount() * prices[tokenIndex]
|
||||
|
||||
selectedMarginAccount.getAssetsVal(selectedMangoGroup, prices) -
|
||||
getMaxForSelectedAccount() * prices[tokenIndex]
|
||||
const currentLiabs = selectedMarginAccount.getLiabsVal(
|
||||
selectedMangoGroup,
|
||||
prices
|
||||
)
|
||||
// multiply by 0.99 and subtract 0.01 to account for rounding issues
|
||||
const liabsAvail = (assetsVal / 1.2 - currentLiabs) * 0.99 - 0.01
|
||||
|
||||
const amountToWithdraw =
|
||||
liabsAvail / prices[tokenIndex] + getMaxForSelectedAccount()
|
||||
const decimals = mintDecimals[getTokenIndex(mintAddress)]
|
||||
|
||||
if (amountToWithdraw > 0) {
|
||||
setInputAmount(
|
||||
formatBalanceDisplay(amountToWithdraw, decimals).toString()
|
||||
floorToDecimal(
|
||||
amountToWithdraw,
|
||||
mintDecimals[getTokenIndex(mintAddress)]
|
||||
).toString()
|
||||
)
|
||||
} else {
|
||||
setInputAmount('0')
|
||||
|
|
|
@ -3,6 +3,11 @@ import { Balances } from '../@types/types'
|
|||
import { nativeToUi } from '@blockworks-foundation/mango-client'
|
||||
import useMarketList from './useMarketList'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import {
|
||||
displayBorrowsForMarginAccount,
|
||||
displayDepositsForMarginAccount,
|
||||
floorToDecimal,
|
||||
} from '../utils'
|
||||
|
||||
export function useBalances(): Balances[] {
|
||||
const { baseCurrency, quoteCurrency, market } = useMarket()
|
||||
|
@ -47,10 +52,14 @@ export function useBalances(): Balances[] {
|
|||
const tokenIndex = marketIndex
|
||||
|
||||
const net = (borrows, currencyIndex) => {
|
||||
return (
|
||||
const amount =
|
||||
marginAccount.getNativeDeposit(mangoGroup, currencyIndex) +
|
||||
borrows -
|
||||
marginAccount.getNativeBorrow(mangoGroup, currencyIndex)
|
||||
|
||||
return floorToDecimal(
|
||||
nativeToUi(amount, mangoGroup.mintDecimals[currencyIndex]),
|
||||
mangoGroup.mintDecimals[currencyIndex]
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -59,31 +68,38 @@ export function useBalances(): Balances[] {
|
|||
market,
|
||||
key: `${baseCurrency}${quoteCurrency}${baseCurrency}`,
|
||||
coin: baseCurrency,
|
||||
marginDeposits:
|
||||
mangoGroup && marginAccount
|
||||
? marginAccount.getUiDeposit(mangoGroup, baseCurrencyIndex)
|
||||
: null,
|
||||
borrows: marginAccount.getUiBorrow(mangoGroup, baseCurrencyIndex),
|
||||
marginDeposits: displayDepositsForMarginAccount(
|
||||
marginAccount,
|
||||
mangoGroup,
|
||||
baseCurrencyIndex
|
||||
),
|
||||
borrows: displayBorrowsForMarginAccount(
|
||||
marginAccount,
|
||||
mangoGroup,
|
||||
baseCurrencyIndex
|
||||
),
|
||||
orders: nativeToUi(nativeBaseLocked, mangoGroup.mintDecimals[tokenIndex]),
|
||||
openOrders,
|
||||
unsettled: nativeToUi(
|
||||
nativeBaseUnsettled,
|
||||
mangoGroup.mintDecimals[tokenIndex]
|
||||
),
|
||||
net: nativeToUi(
|
||||
net(nativeBaseLocked, tokenIndex),
|
||||
mangoGroup.mintDecimals[tokenIndex]
|
||||
),
|
||||
net: net(nativeBaseLocked, tokenIndex),
|
||||
},
|
||||
{
|
||||
market,
|
||||
key: `${quoteCurrency}${baseCurrency}${quoteCurrency}`,
|
||||
coin: quoteCurrency,
|
||||
marginDeposits:
|
||||
mangoGroup && marginAccount
|
||||
? marginAccount.getUiDeposit(mangoGroup, quoteCurrencyIndex)
|
||||
: null,
|
||||
borrows: marginAccount.getUiBorrow(mangoGroup, quoteCurrencyIndex),
|
||||
marginDeposits: displayDepositsForMarginAccount(
|
||||
marginAccount,
|
||||
mangoGroup,
|
||||
quoteCurrencyIndex
|
||||
),
|
||||
borrows: displayBorrowsForMarginAccount(
|
||||
marginAccount,
|
||||
mangoGroup,
|
||||
quoteCurrencyIndex
|
||||
),
|
||||
openOrders,
|
||||
orders: nativeToUi(
|
||||
nativeQuoteLocked,
|
||||
|
@ -93,10 +109,7 @@ export function useBalances(): Balances[] {
|
|||
nativeQuoteUnsettled,
|
||||
mangoGroup.mintDecimals[quoteCurrencyIndex]
|
||||
),
|
||||
net: nativeToUi(
|
||||
net(nativeQuoteLocked, quoteCurrencyIndex),
|
||||
mangoGroup.mintDecimals[quoteCurrencyIndex]
|
||||
),
|
||||
net: net(nativeQuoteLocked, quoteCurrencyIndex),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
|
@ -24,6 +24,26 @@ export const percentFormat = new Intl.NumberFormat(undefined, {
|
|||
maximumFractionDigits: 2,
|
||||
})
|
||||
|
||||
export function displayDepositsForMarginAccount(
|
||||
marginAccount,
|
||||
mangoGroup,
|
||||
tokenIndex
|
||||
) {
|
||||
const deposit = marginAccount.getUiDeposit(mangoGroup, tokenIndex)
|
||||
const decimals = mangoGroup.mintDecimals[tokenIndex]
|
||||
return floorToDecimal(deposit, decimals)
|
||||
}
|
||||
|
||||
export function displayBorrowsForMarginAccount(
|
||||
marginAccount,
|
||||
mangoGroup,
|
||||
tokenIndex
|
||||
) {
|
||||
const borrow = marginAccount.getUiBorrow(mangoGroup, tokenIndex)
|
||||
const decimals = mangoGroup.mintDecimals[tokenIndex]
|
||||
return ceilToDecimal(borrow, decimals)
|
||||
}
|
||||
|
||||
export function floorToDecimal(
|
||||
value: number,
|
||||
decimals: number | undefined | null
|
||||
|
@ -33,6 +53,15 @@ export function floorToDecimal(
|
|||
: Math.floor(value)
|
||||
}
|
||||
|
||||
export function ceilToDecimal(
|
||||
value: number,
|
||||
decimals: number | undefined | null
|
||||
) {
|
||||
return decimals
|
||||
? Math.ceil(value * 10 ** decimals) / 10 ** decimals
|
||||
: Math.ceil(value)
|
||||
}
|
||||
|
||||
export function roundToDecimal(
|
||||
value: number,
|
||||
decimals: number | undefined | null
|
||||
|
|
|
@ -389,9 +389,10 @@ export async function borrowAndWithdraw(
|
|||
const tokenBalance = marginAccount.getUiDeposit(mangoGroup, tokenIndex)
|
||||
const borrowQuantity = withdrawQuantity - tokenBalance
|
||||
|
||||
const nativeBorrowQuantity = uiToNative(
|
||||
borrowQuantity,
|
||||
mangoGroup.mintDecimals[tokenIndex]
|
||||
const nativeBorrowQuantity = new BN(
|
||||
Math.ceil(
|
||||
borrowQuantity * Math.pow(10, mangoGroup.mintDecimals[tokenIndex])
|
||||
)
|
||||
)
|
||||
|
||||
const borrowInstruction = makeBorrowInstruction(
|
||||
|
|
Loading…
Reference in New Issue