Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update/docs: FAQs, CLI Installation, remove YBX references #1065

Merged
merged 11 commits into from
Feb 12, 2025
12 changes: 11 additions & 1 deletion apps/marginfi-v2-docs/src/app/faqs/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,19 @@ In this guide, we will answer commonly asked questions regarding the marginfi pr

<Note>
If you do not see an answer to your question on this page, please contact marginfi support by joining
our [Discord server](https://discord.gg/pJ3U7gHJFe).
at <Button href="https://support.marginfi.com" variant="text"><>support.marginfi.com</></Button>.
</Note>

## Why can't I borrow the full amount shown as my maximum borrowing capacity? {{ tag: '', label: '' }}

The actual borrowing limit is slightly lower than the theoretical maximum to account for price fluctuations. We use an Exponential Moving Average (EMA) price rather than the spot price when calculating initial borrowing limits. This creates a small safety buffer that helps protect your position from immediate liquidation due to minor price movements. When prices have been stable for a period, you may be able to borrow closer to the theoretical maximum.

## How are interest rates calculated? {{ tag: '', label: '' }}

Interest rates are calculated based on market demand for borrowing and lending. For lenders, the interest rate increases with higher market utilization (more borrowing). For borrowers, the rate consists of a base rate plus additional fees. We currently use a simple interest model where interest accrues linearly over time, rather than compounding.

For a more detailed explanation of how interest rates are calculated, please refer to the <Button href="https://github.com/mrgnlabs/marginfi-v2/blob/3b7bf0aceb684a762c8552412001c8d355033119/programs/marginfi/src/state/marginfi_group.rs#L1018C1-L1043C32" variant="text"><>source code</></Button>.

## Is my native stake still earning rewards when I deposit it into marginfi? {{ tag: '', label: '' }}

Yes. When you collateralize yur native stake account using marginfi's Staked Collateral feature, your native stake is still earning your staked validator's APY. **There is no lending yield on your native stake account**, just staking yield.
Expand Down
10 changes: 7 additions & 3 deletions apps/marginfi-v2-docs/src/app/rust-sdk/page.mdx
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
export const metadata = {
title: 'Rust (CLI) SDK',
title: '(Rust) CLI',
description:
'On this page, we’ll learn how to get started with the marginfi Rust CLI.',
'On this page, we’ll learn how to get started with the marginfi CLI.',
}

# The marginfi Rust CLI

With the marginfi <Button href="https://github.com/mrgnlabs/marginfi-v2/tree/main/clients/rust/marginfi-cli" variant="text"><>CLI tool</></Button>, you can interact with the marginfi protocol directly from your terminal, taking advantage of its borrowing and lending services. Built in Rust, this command-line interface simplifies the process of managing your marginfi activities. Whether you want to create a new bank, make deposits to existing banks, or perform other operations, the marginfi CLI provides a streamlined experience. {{ className: 'lead' }}

<Note>
Access the Rust (CLI) SDK source code using <Button href="https://github.com/mrgnlabs/marginfi-v2/tree/main/clients/rust/marginfi-cli" variant="text"><>this link</></Button>.
Access the (Rust) CLI source code using <Button href="https://github.com/mrgnlabs/marginfi-v2/tree/main/clients/rust/marginfi-cli" variant="text"><>this link</></Button>.
</Note>

---

## Installation {{ tag: '', label: '' }}

<Note>
If you are not using a Mac or Linux machine, we recommend installing everything via <Button href="https://learn.microsoft.com/en-us/windows/wsl/install" variant="text"><>WSL (Windows Subsystem for Linux)</></Button>.
</Note>

To get started, install the latest stable Rust toolchain and set it to default:

```bash
Expand Down
8 changes: 8 additions & 0 deletions apps/marginfi-v2-docs/src/app/staked-collateral/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ New pools require one epoch (2-3 days) before lending can begin, with stake pool

This architecture particularly benefits institutional users who prefer native staking over liquid staking tokens for tax considerations. The immutable pool settings and absence of controlling entities provide additional security assurances for all participants.

## Earning Yield on Your Stake {{ tag: '', label: '' }}

Users staking SOL as collateral through marginfi currently receive base staking rewards, but MEV/Jito rewards integration varies by validator. When staking, users receive vouchers (similar to LSTs) representing their share of the stake pool. While these voucher amounts remain constant, their underlying value increases as the pool earns staking rewards.

MEV rewards that require manual claiming (like Jito's) aren't currently supported for all validators since the stake account is program-owned, but this functionality is being added progressively over time.

Despite not capturing all MEV rewards yet, calculations show that even max-borrowed positions with 7% APY versus 10% borrow rate would take over 2 years to reach critical health levels.

## Using Native Stake: Step by Step {{ tag: '', label: '' }}

To post your native stake as collateral on marginfi, simply navigate to <Button href="https://app.marginfi.com" variant="text"><>app.marginfi.com</></Button> and click "Select token" on the dropdown menu. Make sure the "Lend" tab is selected in the action box.
Expand Down
12 changes: 6 additions & 6 deletions apps/marginfi-v2-docs/src/components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,12 @@ export const navigation: Array<NavGroup> = [
{ title: 'Progressive Web App', href: '/pwa' },
],
},
{
title: 'White Papers',
links: [
{ title: '$YBX', href: '/ybx' },
],
},
// {
// title: 'White Papers',
// links: [
// { title: '$YBX', href: '/ybx' },
// ],
// },
]

export function Navigation(props: React.ComponentPropsWithoutRef<'nav'>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { Connection, LAMPORTS_PER_SOL, ParsedAccountData, PublicKey, StakeProgra
import { MAX_U64 } from "@mrgnlabs/mrgn-common";
import { vendor } from "@mrgnlabs/marginfi-client-v2";
import { ExtendedBankInfo, ValidatorStakeGroup } from "../types";
import { findPoolAddress, findPoolMintAddress, findPoolStakeAddress } from "@mrgnlabs/marginfi-client-v2/dist/vendor";
import {
findPoolAddress,
findPoolMintAddress,
findPoolStakeAddress,
getStakeAccount,
} from "@mrgnlabs/marginfi-client-v2/dist/vendor";

/**
* Fetches stake accounts for a given public key from API
Expand Down Expand Up @@ -188,30 +193,45 @@ const getStakePoolActiveStates = async (
const currentEpoch = await connection.getEpochInfo();
const activeStates = new Map<string, boolean>();

await Promise.all(
validatorVoteAccounts.map(async (validatorVoteAccount) => {
const poolAddress = findPoolAddress(validatorVoteAccount);
const poolStakeAddress = findPoolStakeAddress(poolAddress);
const poolMintAddress = findPoolMintAddress(poolAddress);

const stakePoolAccount = await connection.getParsedAccountInfo(poolStakeAddress);
if (!stakePoolAccount.value) {
activeStates.set(poolMintAddress.toBase58(), false);
return;
}

const parsedData = (stakePoolAccount.value.data as any).parsed;
if (!parsedData?.info?.stake?.delegation) {
activeStates.set(poolMintAddress.toBase58(), false);
return;
}

const activationEpoch = parsedData.info.stake.delegation.activationEpoch;
const isActive = currentEpoch.epoch > Number(activationEpoch);
activeStates.set(poolMintAddress.toBase58(), isActive);
})
const poolMintAddressRecord: Record<string, PublicKey> = {};
const poolStakeAddressRecord: Record<string, PublicKey> = {};

validatorVoteAccounts.forEach((validatorVoteAccount) => {
const poolAddress = findPoolAddress(validatorVoteAccount);
const poolStakeAddress = findPoolStakeAddress(poolAddress);
const poolMintAddress = findPoolMintAddress(poolAddress);

poolMintAddressRecord[validatorVoteAccount.toBase58()] = poolMintAddress;
poolStakeAddressRecord[poolStakeAddress.toBase58()] = validatorVoteAccount;
});

const poolStakeAddressKeys = Object.keys(poolStakeAddressRecord);

const poolStakeAccounts = Object.fromEntries(
(await connection.getMultipleAccountsInfo(poolStakeAddressKeys.map((key) => new PublicKey(key)))).map(
(ai, index) => [poolStakeAddressRecord[poolStakeAddressKeys[index]], ai?.data ? getStakeAccount(ai.data) : null]
)
);

validatorVoteAccounts.map(async (validatorVoteAccount) => {
const stakeAccount = poolStakeAccounts[validatorVoteAccount.toBase58()];
const poolMintAddress = poolMintAddressRecord[validatorVoteAccount.toBase58()];

if (!stakeAccount) {
activeStates.set(poolMintAddress.toBase58(), false);
return;
}

if (!stakeAccount.stake?.delegation) {
activeStates.set(poolMintAddress.toBase58(), false);
return;
}

const activationEpoch = stakeAccount.stake.delegation.activationEpoch;
const isActive = currentEpoch.epoch > Number(activationEpoch);
activeStates.set(poolMintAddress.toBase58(), isActive);
});

return activeStates;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ export async function calculateLooping(props: CalculateLoopingProps): Promise<Lo
// outputMint: bank.info.state.mint.toBase58(),
// });

const result = await calculateLoopingParams(props);
const params = {
...props,
setupBankAddresses: [props.depositBank.address, props.borrowBank.address],
};

const result = await calculateLoopingParams(params);

return result;
}
11 changes: 10 additions & 1 deletion packages/mrgn-utils/src/actions/flashloans/builders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
TransactionBroadcastType,
TransactionType,
uiToNative,
WSOL_MINT,
} from "@mrgnlabs/mrgn-common";

import { deserializeInstruction, getAdressLookupTableAccounts, getSwapQuoteWithRetry } from "../helpers";
Expand Down Expand Up @@ -384,6 +385,8 @@ export async function loopingBuilder({
swapLUTs.push(...(await getAdressLookupTableAccounts(connection, addressLookupTableAddresses)));
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");

const borrowOpts = !borrowBank.info.rawBank.mint.equals(WSOL_MINT) ? { createAtas: true } : undefined;

const { transactions, txOverflown } = await marginfiAccount.makeLoopTxV2({
depositAmount: actualDepositAmount,
borrowAmount,
Expand All @@ -394,7 +397,13 @@ export async function loopingBuilder({
lookupTables: swapLUTs,
},
blockhash,
setupBankAddresses,
depositOpts: {
wrapAndUnwrapSol: true,
},
borrowOpts,
// commented out as looping requires ata to be created within borrow tx
// otherwise setupBankAddresses are used to create atas
// setupBankAddresses,
});

return { transactions, txOverflown, lastValidBlockHeight };
Expand Down
Loading