better handling of rounding issues in borrow and withdraw

This commit is contained in:
Tyler Shipe 2021-04-29 17:27:13 -04:00
parent 567e38cbcc
commit a0ef8f1e8e
4 changed files with 82 additions and 33 deletions

View File

@ -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')

View File

@ -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),
},
]
}

View File

@ -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

View File

@ -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(