diff --git a/components/MangoProvider.tsx b/components/MangoProvider.tsx index ee03449..e6426f0 100644 --- a/components/MangoProvider.tsx +++ b/components/MangoProvider.tsx @@ -3,16 +3,12 @@ import mangoStore from '@store/mangoStore' import { Keypair } from '@solana/web3.js' import useMangoAccount from 'hooks/useMangoAccount' import useInterval from './shared/useInterval' -import { - LAST_WALLET_NAME, - PRIORITY_FEE_KEY, - SECONDS, - STAKEABLE_TOKENS_DATA, -} from 'utils/constants' +import { LAST_WALLET_NAME, PRIORITY_FEE_KEY, SECONDS } from 'utils/constants' import useNetworkSpeed from 'hooks/useNetworkSpeed' import { useWallet } from '@solana/wallet-adapter-react' import useLocalStorageState from 'hooks/useLocalStorageState' import { DEFAULT_PRIORITY_FEE_LEVEL } from './settings/RpcSettings' +import { getStakableTokensDataForTokenName } from 'utils/tokens' const set = mangoStore.getState().set const actions = mangoStore.getState().actions @@ -20,9 +16,8 @@ const actions = mangoStore.getState().actions const HydrateStore = () => { const { mangoAccountPk } = useMangoAccount() const selectedToken = mangoStore((s) => s.selectedToken) - const clientContext = STAKEABLE_TOKENS_DATA.find( - (x) => x.name === selectedToken, - )!.clientContext + const clientContext = + getStakableTokensDataForTokenName(selectedToken).clientContext const connection = mangoStore((s) => s.connection) diff --git a/components/Stake.tsx b/components/Stake.tsx index f6857d2..2eb1cbf 100644 --- a/components/Stake.tsx +++ b/components/Stake.tsx @@ -4,8 +4,11 @@ import TabUnderline from './shared/TabUnderline' import StakeForm from '@components/StakeForm' import UnstakeForm from '@components/UnstakeForm' import mangoStore from '@store/mangoStore' -import { STAKEABLE_TOKENS, STAKEABLE_TOKENS_DATA } from 'utils/constants' -import { formatTokenSymbol } from 'utils/tokens' +import { STAKEABLE_TOKENS } from 'utils/constants' +import { + formatTokenSymbol, + getStakableTokensDataForTokenName, +} from 'utils/tokens' import { useViewport } from 'hooks/useViewport' import { ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid' import DespositForm from './DepositForm' @@ -104,7 +107,7 @@ const Stake = () => { x.name === 'USDC')! + getStakableTokensDataForTokenName('USDC') .clientContext } /> @@ -113,7 +116,7 @@ const Stake = () => { x.name === 'USDC')! + getStakableTokensDataForTokenName('USDC') .clientContext } /> @@ -125,9 +128,8 @@ const Stake = () => { x.name === selectedToken, - )!.clientContext + getStakableTokensDataForTokenName(selectedToken) + .clientContext } /> ) : null} @@ -135,9 +137,8 @@ const Stake = () => { x.name === selectedToken, - )!.clientContext + getStakableTokensDataForTokenName(selectedToken) + .clientContext } /> ) : null} diff --git a/components/StakeForm.tsx b/components/StakeForm.tsx index e67fafa..9040e21 100644 --- a/components/StakeForm.tsx +++ b/components/StakeForm.tsx @@ -112,7 +112,7 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) { leverage, ) const leverageMax = useLeverageMax(selectedToken) - console.log(leverageMax) + const [stakeBank, borrowBank] = useMemo(() => { const stakeBank = clientContext === 'jlp' @@ -175,9 +175,17 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) { const borrowPrice = borrowBank?.uiPrice const stakePrice = stakeBank?.uiPrice if (!borrowPrice || !stakePrice || !Number(inputAmount)) return 0 - const borrowAmount = - stakeBank?.uiPrice * Number(inputAmount) * (leverage - 1) - return borrowAmount + if (clientContext === 'jlp') { + const borrowAmount = + stakeBank?.uiPrice * Number(inputAmount) * (leverage - 1) + 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]) const availableVaultBalance = useMemo(() => { @@ -213,7 +221,7 @@ function StakeForm({ token: selectedToken, clientContext }: StakeFormProps) { const accNumber = getNextAccountNumber(mangoAccounts) if (!group) return - console.log(mangoAccounts) + set((state) => { state.submittingBoost = true }) diff --git a/components/UnstakeForm.tsx b/components/UnstakeForm.tsx index 52d4ff1..e574416 100644 --- a/components/UnstakeForm.tsx +++ b/components/UnstakeForm.tsx @@ -101,10 +101,11 @@ function UnstakeForm({ borrowBankAmount && borrowBankAmount.toNumber() < 0 ) { - const lev = stakeBankAmount + const stakeAmountValue = stakeBankAmount.mul(stakeBank.getAssetPrice()) + const lev = stakeAmountValue .div( - stakeBankAmount.sub( - borrowBankAmount.abs().div(stakeBank.getAssetPrice()), + stakeAmountValue.sub( + borrowBankAmount.abs().mul(borrowBank.getAssetPrice()), ), ) .toNumber() @@ -259,10 +260,14 @@ function UnstakeForm({ if (!mangoAccount || !stakeBank) return 0 const group = clientContext === 'jlp' ? jlpGroup : lstGroup if (!group) return 0 - return mangoAccount.getMaxWithdrawWithBorrowForTokenUi( - group, - stakeBank.mint, - ) + try { + return mangoAccount.getMaxWithdrawWithBorrowForTokenUi( + group, + stakeBank.mint, + ) + } catch (e) { + return 0 + } }, [jlpGroup, lstGroup, mangoAccount, stakeBank, clientContext]) const showInsufficientBalance = @@ -414,7 +419,9 @@ function UnstakeForm({
-

USDC borrowed

+

+ {borrowBank.name} borrowed +

{borrowBank ? ( x.name === selectedToken) - ?.clientContext === 'jlp' + getStakableTokensDataForTokenName(selectedToken).clientContext === 'jlp' ) { const leverageFactor = 1 / (1 - x) diff --git a/utils/constants.ts b/utils/constants.ts index 6c7bb94..d824f8e 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -10,6 +10,7 @@ export const STAKEABLE_TOKENS_DATA: { active: boolean mint_address: string clientContext: ClientContextKeys + borrowToken: 'USDC' | 'SOL' }[] = [ { name: 'JLP', @@ -17,6 +18,7 @@ export const STAKEABLE_TOKENS_DATA: { active: true, mint_address: '27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4', clientContext: 'jlp', + borrowToken: 'USDC', }, { name: 'USDC', @@ -24,6 +26,7 @@ export const STAKEABLE_TOKENS_DATA: { active: true, mint_address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', clientContext: 'jlp', + borrowToken: 'USDC', }, { name: 'MSOL', @@ -31,6 +34,7 @@ export const STAKEABLE_TOKENS_DATA: { active: true, mint_address: 'mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So', clientContext: 'lst', + borrowToken: 'SOL', }, { name: 'JitoSOL', @@ -38,6 +42,7 @@ export const STAKEABLE_TOKENS_DATA: { active: true, mint_address: 'J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn', clientContext: 'lst', + borrowToken: 'SOL', }, { name: 'bSOL', @@ -45,6 +50,7 @@ export const STAKEABLE_TOKENS_DATA: { active: true, mint_address: 'bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1', clientContext: 'lst', + borrowToken: 'SOL', }, ] diff --git a/utils/tokens.ts b/utils/tokens.ts index d1e4bf6..a221b75 100644 --- a/utils/tokens.ts +++ b/utils/tokens.ts @@ -1,6 +1,7 @@ import { PublicKey, Connection } from '@solana/web3.js' import { TokenInstructions } from '@project-serum/serum' import { toUiDecimals } from '@blockworks-foundation/mango-v4' +import { STAKEABLE_TOKENS_DATA } from './constants' export class TokenAccount { publicKey!: PublicKey @@ -26,7 +27,7 @@ export class TokenAccount { } } -function exists(item: T | null | undefined): item is T { +export function exists(item: T | null | undefined): item is T { return !!item } @@ -74,3 +75,11 @@ export const formatTokenSymbol = (symbol: string) => { } 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)! +} diff --git a/utils/transactions.ts b/utils/transactions.ts index 0b45971..969c81a 100644 --- a/utils/transactions.ts +++ b/utils/transactions.ts @@ -37,6 +37,7 @@ import { import { floorToDecimal } from './numbers' import { BOOST_ACCOUNT_PREFIX } from './constants' import { notify } from './notifications' +import { getStakableTokensDataForMint } from './tokens' export const withdrawAndClose = async ( client: MangoClient, @@ -47,10 +48,12 @@ export const withdrawAndClose = async ( ) => { 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 instructions: TransactionInstruction[] = [] - + console.log(borrowBank, stakeBank, mangoAccount) if (!borrowBank || !stakeBank || !mangoAccount) { 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') 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 instructions: TransactionInstruction[] = [] @@ -208,7 +213,9 @@ export const stakeAndCreate = async ( name?: string, ): Promise => { 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 instructions: TransactionInstruction[] = []