leverage and usdc fixes
This commit is contained in:
parent
a382829e72
commit
01fecedcff
|
@ -3,16 +3,12 @@ import mangoStore from '@store/mangoStore'
|
||||||
import { Keypair } from '@solana/web3.js'
|
import { Keypair } from '@solana/web3.js'
|
||||||
import useMangoAccount from 'hooks/useMangoAccount'
|
import useMangoAccount from 'hooks/useMangoAccount'
|
||||||
import useInterval from './shared/useInterval'
|
import useInterval from './shared/useInterval'
|
||||||
import {
|
import { LAST_WALLET_NAME, PRIORITY_FEE_KEY, SECONDS } from 'utils/constants'
|
||||||
LAST_WALLET_NAME,
|
|
||||||
PRIORITY_FEE_KEY,
|
|
||||||
SECONDS,
|
|
||||||
STAKEABLE_TOKENS_DATA,
|
|
||||||
} from 'utils/constants'
|
|
||||||
import useNetworkSpeed from 'hooks/useNetworkSpeed'
|
import useNetworkSpeed from 'hooks/useNetworkSpeed'
|
||||||
import { useWallet } from '@solana/wallet-adapter-react'
|
import { useWallet } from '@solana/wallet-adapter-react'
|
||||||
import useLocalStorageState from 'hooks/useLocalStorageState'
|
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||||
import { DEFAULT_PRIORITY_FEE_LEVEL } from './settings/RpcSettings'
|
import { DEFAULT_PRIORITY_FEE_LEVEL } from './settings/RpcSettings'
|
||||||
|
import { getStakableTokensDataForTokenName } from 'utils/tokens'
|
||||||
|
|
||||||
const set = mangoStore.getState().set
|
const set = mangoStore.getState().set
|
||||||
const actions = mangoStore.getState().actions
|
const actions = mangoStore.getState().actions
|
||||||
|
@ -20,9 +16,8 @@ const actions = mangoStore.getState().actions
|
||||||
const HydrateStore = () => {
|
const HydrateStore = () => {
|
||||||
const { mangoAccountPk } = useMangoAccount()
|
const { mangoAccountPk } = useMangoAccount()
|
||||||
const selectedToken = mangoStore((s) => s.selectedToken)
|
const selectedToken = mangoStore((s) => s.selectedToken)
|
||||||
const clientContext = STAKEABLE_TOKENS_DATA.find(
|
const clientContext =
|
||||||
(x) => x.name === selectedToken,
|
getStakableTokensDataForTokenName(selectedToken).clientContext
|
||||||
)!.clientContext
|
|
||||||
|
|
||||||
const connection = mangoStore((s) => s.connection)
|
const connection = mangoStore((s) => s.connection)
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,11 @@ import TabUnderline from './shared/TabUnderline'
|
||||||
import StakeForm from '@components/StakeForm'
|
import StakeForm from '@components/StakeForm'
|
||||||
import UnstakeForm from '@components/UnstakeForm'
|
import UnstakeForm from '@components/UnstakeForm'
|
||||||
import mangoStore from '@store/mangoStore'
|
import mangoStore from '@store/mangoStore'
|
||||||
import { STAKEABLE_TOKENS, STAKEABLE_TOKENS_DATA } from 'utils/constants'
|
import { STAKEABLE_TOKENS } from 'utils/constants'
|
||||||
import { formatTokenSymbol } from 'utils/tokens'
|
import {
|
||||||
|
formatTokenSymbol,
|
||||||
|
getStakableTokensDataForTokenName,
|
||||||
|
} from 'utils/tokens'
|
||||||
import { useViewport } from 'hooks/useViewport'
|
import { useViewport } from 'hooks/useViewport'
|
||||||
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid'
|
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid'
|
||||||
import DespositForm from './DepositForm'
|
import DespositForm from './DepositForm'
|
||||||
|
@ -104,7 +107,7 @@ const Stake = () => {
|
||||||
<DespositForm
|
<DespositForm
|
||||||
token="USDC"
|
token="USDC"
|
||||||
clientContext={
|
clientContext={
|
||||||
STAKEABLE_TOKENS_DATA.find((x) => x.name === 'USDC')!
|
getStakableTokensDataForTokenName('USDC')
|
||||||
.clientContext
|
.clientContext
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -113,7 +116,7 @@ const Stake = () => {
|
||||||
<UnstakeForm
|
<UnstakeForm
|
||||||
token="USDC"
|
token="USDC"
|
||||||
clientContext={
|
clientContext={
|
||||||
STAKEABLE_TOKENS_DATA.find((x) => x.name === 'USDC')!
|
getStakableTokensDataForTokenName('USDC')
|
||||||
.clientContext
|
.clientContext
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -125,9 +128,8 @@ const Stake = () => {
|
||||||
<StakeForm
|
<StakeForm
|
||||||
token={selectedToken}
|
token={selectedToken}
|
||||||
clientContext={
|
clientContext={
|
||||||
STAKEABLE_TOKENS_DATA.find(
|
getStakableTokensDataForTokenName(selectedToken)
|
||||||
(x) => x.name === selectedToken,
|
.clientContext
|
||||||
)!.clientContext
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -135,9 +137,8 @@ const Stake = () => {
|
||||||
<UnstakeForm
|
<UnstakeForm
|
||||||
token={selectedToken}
|
token={selectedToken}
|
||||||
clientContext={
|
clientContext={
|
||||||
STAKEABLE_TOKENS_DATA.find(
|
getStakableTokensDataForTokenName(selectedToken)
|
||||||
(x) => x.name === selectedToken,
|
.clientContext
|
||||||
)!.clientContext
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -112,7 +112,7 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) {
|
||||||
leverage,
|
leverage,
|
||||||
)
|
)
|
||||||
const leverageMax = useLeverageMax(selectedToken)
|
const leverageMax = useLeverageMax(selectedToken)
|
||||||
console.log(leverageMax)
|
|
||||||
const [stakeBank, borrowBank] = useMemo(() => {
|
const [stakeBank, borrowBank] = useMemo(() => {
|
||||||
const stakeBank =
|
const stakeBank =
|
||||||
clientContext === 'jlp'
|
clientContext === 'jlp'
|
||||||
|
@ -175,9 +175,17 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) {
|
||||||
const borrowPrice = borrowBank?.uiPrice
|
const borrowPrice = borrowBank?.uiPrice
|
||||||
const stakePrice = stakeBank?.uiPrice
|
const stakePrice = stakeBank?.uiPrice
|
||||||
if (!borrowPrice || !stakePrice || !Number(inputAmount)) return 0
|
if (!borrowPrice || !stakePrice || !Number(inputAmount)) return 0
|
||||||
|
if (clientContext === 'jlp') {
|
||||||
const borrowAmount =
|
const borrowAmount =
|
||||||
stakeBank?.uiPrice * Number(inputAmount) * (leverage - 1)
|
stakeBank?.uiPrice * Number(inputAmount) * (leverage - 1)
|
||||||
return borrowAmount
|
return borrowAmount
|
||||||
|
} else {
|
||||||
|
const priceDifference = (stakePrice - borrowPrice) / borrowPrice
|
||||||
|
const borrowAmount =
|
||||||
|
(1 + priceDifference) * Number(inputAmount) * Math.min(leverage - 1, 1)
|
||||||
|
|
||||||
|
return borrowAmount
|
||||||
|
}
|
||||||
}, [leverage, borrowBank, stakeBank, inputAmount])
|
}, [leverage, borrowBank, stakeBank, inputAmount])
|
||||||
|
|
||||||
const availableVaultBalance = useMemo(() => {
|
const availableVaultBalance = useMemo(() => {
|
||||||
|
@ -213,7 +221,7 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) {
|
||||||
const accNumber = getNextAccountNumber(mangoAccounts)
|
const accNumber = getNextAccountNumber(mangoAccounts)
|
||||||
|
|
||||||
if (!group) return
|
if (!group) return
|
||||||
console.log(mangoAccounts)
|
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.submittingBoost = true
|
state.submittingBoost = true
|
||||||
})
|
})
|
||||||
|
|
|
@ -101,10 +101,11 @@ function UnstakeForm({
|
||||||
borrowBankAmount &&
|
borrowBankAmount &&
|
||||||
borrowBankAmount.toNumber() < 0
|
borrowBankAmount.toNumber() < 0
|
||||||
) {
|
) {
|
||||||
const lev = stakeBankAmount
|
const stakeAmountValue = stakeBankAmount.mul(stakeBank.getAssetPrice())
|
||||||
|
const lev = stakeAmountValue
|
||||||
.div(
|
.div(
|
||||||
stakeBankAmount.sub(
|
stakeAmountValue.sub(
|
||||||
borrowBankAmount.abs().div(stakeBank.getAssetPrice()),
|
borrowBankAmount.abs().mul(borrowBank.getAssetPrice()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toNumber()
|
.toNumber()
|
||||||
|
@ -259,10 +260,14 @@ function UnstakeForm({
|
||||||
if (!mangoAccount || !stakeBank) return 0
|
if (!mangoAccount || !stakeBank) return 0
|
||||||
const group = clientContext === 'jlp' ? jlpGroup : lstGroup
|
const group = clientContext === 'jlp' ? jlpGroup : lstGroup
|
||||||
if (!group) return 0
|
if (!group) return 0
|
||||||
|
try {
|
||||||
return mangoAccount.getMaxWithdrawWithBorrowForTokenUi(
|
return mangoAccount.getMaxWithdrawWithBorrowForTokenUi(
|
||||||
group,
|
group,
|
||||||
stakeBank.mint,
|
stakeBank.mint,
|
||||||
)
|
)
|
||||||
|
} catch (e) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
}, [jlpGroup, lstGroup, mangoAccount, stakeBank, clientContext])
|
}, [jlpGroup, lstGroup, mangoAccount, stakeBank, clientContext])
|
||||||
|
|
||||||
const showInsufficientBalance =
|
const showInsufficientBalance =
|
||||||
|
@ -414,7 +419,9 @@ function UnstakeForm({
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<p className="text-th-fgd-4">USDC borrowed</p>
|
<p className="text-th-fgd-4">
|
||||||
|
{borrowBank.name} borrowed
|
||||||
|
</p>
|
||||||
{borrowBank ? (
|
{borrowBank ? (
|
||||||
<span
|
<span
|
||||||
className={`font-bold ${
|
className={`font-bold ${
|
||||||
|
|
|
@ -87,9 +87,7 @@ export default function useBankRates(selectedToken: string, leverage: number) {
|
||||||
|
|
||||||
// Total APY, comparing the end value (deposits - borrows) to the starting value (1)
|
// Total APY, comparing the end value (deposits - borrows) to the starting value (1)
|
||||||
const APY = (deposits - borrows - 1) * 100
|
const APY = (deposits - borrows - 1) * 100
|
||||||
console.log(selectedToken, {
|
|
||||||
stakeRates,
|
|
||||||
})
|
|
||||||
// Comparisons to outside
|
// Comparisons to outside
|
||||||
const nonMangoAPY = tokenStakeRateAPY * leverage * 100
|
const nonMangoAPY = tokenStakeRateAPY * leverage * 100
|
||||||
const diffToNonMango = APY - nonMangoAPY
|
const diffToNonMango = APY - nonMangoAPY
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import useMangoGroup from './useMangoGroup'
|
import useMangoGroup from './useMangoGroup'
|
||||||
import { floorToDecimal } from 'utils/numbers'
|
import { floorToDecimal } from 'utils/numbers'
|
||||||
import {
|
import { JLP_BORROW_TOKEN, LST_BORROW_TOKEN } from 'utils/constants'
|
||||||
JLP_BORROW_TOKEN,
|
import { getStakableTokensDataForTokenName } from 'utils/tokens'
|
||||||
LST_BORROW_TOKEN,
|
|
||||||
STAKEABLE_TOKENS_DATA,
|
|
||||||
} from 'utils/constants'
|
|
||||||
|
|
||||||
export default function useLeverageMax(selectedToken: string) {
|
export default function useLeverageMax(selectedToken: string) {
|
||||||
const { jlpGroup, lstGroup } = useMangoGroup()
|
const { jlpGroup, lstGroup } = useMangoGroup()
|
||||||
|
@ -35,8 +32,7 @@ export default function useLeverageMax(selectedToken: string) {
|
||||||
const x = stakeInitAssetWeight.toNumber() / borrowInitLiabWeight.toNumber()
|
const x = stakeInitAssetWeight.toNumber() / borrowInitLiabWeight.toNumber()
|
||||||
|
|
||||||
if (
|
if (
|
||||||
STAKEABLE_TOKENS_DATA.find((x) => x.name === selectedToken)
|
getStakableTokensDataForTokenName(selectedToken).clientContext === 'jlp'
|
||||||
?.clientContext === 'jlp'
|
|
||||||
) {
|
) {
|
||||||
const leverageFactor = 1 / (1 - x)
|
const leverageFactor = 1 / (1 - x)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ export const STAKEABLE_TOKENS_DATA: {
|
||||||
active: boolean
|
active: boolean
|
||||||
mint_address: string
|
mint_address: string
|
||||||
clientContext: ClientContextKeys
|
clientContext: ClientContextKeys
|
||||||
|
borrowToken: 'USDC' | 'SOL'
|
||||||
}[] = [
|
}[] = [
|
||||||
{
|
{
|
||||||
name: 'JLP',
|
name: 'JLP',
|
||||||
|
@ -17,6 +18,7 @@ export const STAKEABLE_TOKENS_DATA: {
|
||||||
active: true,
|
active: true,
|
||||||
mint_address: '27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4',
|
mint_address: '27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4',
|
||||||
clientContext: 'jlp',
|
clientContext: 'jlp',
|
||||||
|
borrowToken: 'USDC',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'USDC',
|
name: 'USDC',
|
||||||
|
@ -24,6 +26,7 @@ export const STAKEABLE_TOKENS_DATA: {
|
||||||
active: true,
|
active: true,
|
||||||
mint_address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
mint_address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||||
clientContext: 'jlp',
|
clientContext: 'jlp',
|
||||||
|
borrowToken: 'USDC',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'MSOL',
|
name: 'MSOL',
|
||||||
|
@ -31,6 +34,7 @@ export const STAKEABLE_TOKENS_DATA: {
|
||||||
active: true,
|
active: true,
|
||||||
mint_address: 'mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So',
|
mint_address: 'mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So',
|
||||||
clientContext: 'lst',
|
clientContext: 'lst',
|
||||||
|
borrowToken: 'SOL',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'JitoSOL',
|
name: 'JitoSOL',
|
||||||
|
@ -38,6 +42,7 @@ export const STAKEABLE_TOKENS_DATA: {
|
||||||
active: true,
|
active: true,
|
||||||
mint_address: 'J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn',
|
mint_address: 'J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn',
|
||||||
clientContext: 'lst',
|
clientContext: 'lst',
|
||||||
|
borrowToken: 'SOL',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'bSOL',
|
name: 'bSOL',
|
||||||
|
@ -45,6 +50,7 @@ export const STAKEABLE_TOKENS_DATA: {
|
||||||
active: true,
|
active: true,
|
||||||
mint_address: 'bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1',
|
mint_address: 'bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1',
|
||||||
clientContext: 'lst',
|
clientContext: 'lst',
|
||||||
|
borrowToken: 'SOL',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { PublicKey, Connection } from '@solana/web3.js'
|
import { PublicKey, Connection } from '@solana/web3.js'
|
||||||
import { TokenInstructions } from '@project-serum/serum'
|
import { TokenInstructions } from '@project-serum/serum'
|
||||||
import { toUiDecimals } from '@blockworks-foundation/mango-v4'
|
import { toUiDecimals } from '@blockworks-foundation/mango-v4'
|
||||||
|
import { STAKEABLE_TOKENS_DATA } from './constants'
|
||||||
|
|
||||||
export class TokenAccount {
|
export class TokenAccount {
|
||||||
publicKey!: PublicKey
|
publicKey!: PublicKey
|
||||||
|
@ -26,7 +27,7 @@ export class TokenAccount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function exists<T>(item: T | null | undefined): item is T {
|
export function exists<T>(item: T | null | undefined): item is T {
|
||||||
return !!item
|
return !!item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,3 +75,11 @@ export const formatTokenSymbol = (symbol: string) => {
|
||||||
}
|
}
|
||||||
return symbol === 'MSOL' ? 'mSOL' : symbol
|
return symbol === 'MSOL' ? 'mSOL' : symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getStakableTokensDataForMint = (mintPk: string) => {
|
||||||
|
return STAKEABLE_TOKENS_DATA.find((x) => x.mint_address === mintPk)!
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getStakableTokensDataForTokenName = (tokenName: string) => {
|
||||||
|
return STAKEABLE_TOKENS_DATA.find((x) => x.name === tokenName)!
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import {
|
||||||
import { floorToDecimal } from './numbers'
|
import { floorToDecimal } from './numbers'
|
||||||
import { BOOST_ACCOUNT_PREFIX } from './constants'
|
import { BOOST_ACCOUNT_PREFIX } from './constants'
|
||||||
import { notify } from './notifications'
|
import { notify } from './notifications'
|
||||||
|
import { getStakableTokensDataForMint } from './tokens'
|
||||||
|
|
||||||
export const withdrawAndClose = async (
|
export const withdrawAndClose = async (
|
||||||
client: MangoClient,
|
client: MangoClient,
|
||||||
|
@ -47,10 +48,12 @@ export const withdrawAndClose = async (
|
||||||
) => {
|
) => {
|
||||||
console.log('withdraw and close')
|
console.log('withdraw and close')
|
||||||
|
|
||||||
const borrowBank = group?.banksMapByName.get('USDC')?.[0]
|
const borrowBank = group?.banksMapByName.get(
|
||||||
|
getStakableTokensDataForMint(stakeMintPk.toBase58()).borrowToken,
|
||||||
|
)?.[0]
|
||||||
const stakeBank = group?.banksMapByMint.get(stakeMintPk.toString())?.[0]
|
const stakeBank = group?.banksMapByMint.get(stakeMintPk.toString())?.[0]
|
||||||
const instructions: TransactionInstruction[] = []
|
const instructions: TransactionInstruction[] = []
|
||||||
|
console.log(borrowBank, stakeBank, mangoAccount)
|
||||||
if (!borrowBank || !stakeBank || !mangoAccount) {
|
if (!borrowBank || !stakeBank || !mangoAccount) {
|
||||||
throw Error('Unable to find USDC bank or stake bank or mango account')
|
throw Error('Unable to find USDC bank or stake bank or mango account')
|
||||||
}
|
}
|
||||||
|
@ -117,7 +120,9 @@ export const unstakeAndSwap = async (
|
||||||
console.log('unstake and swap')
|
console.log('unstake and swap')
|
||||||
|
|
||||||
const payer = (client.program.provider as AnchorProvider).wallet.publicKey
|
const payer = (client.program.provider as AnchorProvider).wallet.publicKey
|
||||||
const borrowBank = group?.banksMapByName.get('USDC')?.[0]
|
const borrowBank = group?.banksMapByName.get(
|
||||||
|
getStakableTokensDataForMint(stakeMintPk.toBase58()).borrowToken,
|
||||||
|
)?.[0]
|
||||||
const stakeBank = group?.banksMapByMint.get(stakeMintPk.toString())?.[0]
|
const stakeBank = group?.banksMapByMint.get(stakeMintPk.toString())?.[0]
|
||||||
const instructions: TransactionInstruction[] = []
|
const instructions: TransactionInstruction[] = []
|
||||||
|
|
||||||
|
@ -208,7 +213,9 @@ export const stakeAndCreate = async (
|
||||||
name?: string,
|
name?: string,
|
||||||
): Promise<MangoSignatureStatus> => {
|
): Promise<MangoSignatureStatus> => {
|
||||||
const payer = (client.program.provider as AnchorProvider).wallet.publicKey
|
const payer = (client.program.provider as AnchorProvider).wallet.publicKey
|
||||||
const borrowBank = group?.banksMapByName.get('USDC')?.[0]
|
const borrowBank = group?.banksMapByName.get(
|
||||||
|
getStakableTokensDataForMint(stakeMintPk.toBase58()).borrowToken,
|
||||||
|
)?.[0]
|
||||||
const stakeBank = group?.banksMapByMint.get(stakeMintPk.toString())?.[0]
|
const stakeBank = group?.banksMapByMint.get(stakeMintPk.toString())?.[0]
|
||||||
const instructions: TransactionInstruction[] = []
|
const instructions: TransactionInstruction[] = []
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue