> For the complete documentation index, see [llms.txt](https://docs.keystonefi.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keystonefi.xyz/keystone-finance/check-position.md).

# Check Position & NAV

How to read your `ksUSD` balance, the current share price, and the total value of what the vault holds (its NAV).

Your balance never changes on its own. What changes is the share price, so the same balance is worth more over time.

***

## Your position

```ts
import { PublicKey } from "@solana/web3.js";
import { getAccount, getAssociatedTokenAddressSync } from "@solana/spl-token";

const [vaultPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("vault")],
  PROGRAM_ID
);

const vault = await program.account.vault.fetch(vaultPda);
const userKsusdAta = getAssociatedTokenAddressSync(vault.ksusdMint, user.publicKey);
const ksusdAccount = await getAccount(connection, userKsusdAta);

const shares = BigInt(ksusdAccount.amount.toString());
console.log("Your ksUSD:", Number(shares) / 1e6);   // 6 decimals
```

***

## Current share price

```ts
// Mirrors the on-chain Vault::share_price_1e9() helper.
const cachedNav = BigInt(vault.cachedNavUsdc.toString());
const queuePending = BigInt(vault.queuePendingUsdc.toString());
const reserveFund = BigInt(vault.reserveFundUsdc.toString());
const pendingPerfFees = BigInt(vault.pendingPerfFeesUsdc.toString());
const totalShares = BigInt(vault.totalShares.toString());

// Gross basis: what the high-water mark is measured against.
const grossEffectiveNav = cachedNav - queuePending - reserveFund;
// Net basis: what deposits and withdrawals actually price against.
const effectiveNav = grossEffectiveNav - pendingPerfFees;

const sharePrice1e9 = totalShares === 0n
  ? 1_000_000_000n
  : (effectiveNav * 1_000_000_000n) / totalShares;                 // 1e9-scaled

const sharePriceUsdc = Number(sharePrice1e9) / 1e9;                // dollars per ksUSD
console.log("Share price:", sharePriceUsdc.toFixed(6));
```

The share price starts at `1.000000` and rises as carry accrues. It only goes down in a drawdown.

Performance fees apply only to new gains above the highest price the vault has previously reached, tracked as `hwm_share_price_1e9`. So recovering from a dip is free.

***

## Your USDC-equivalent value

```ts
const yourUsdc = (shares * BigInt(Math.round(sharePrice1e9))) / 1_000_000_000n;
console.log("Withdrawable USDC:", Number(yourUsdc) / 1e6);
```

***

## Vault-level NAV

```ts
console.log("Cached NAV (USDC):       ", Number(vault.cachedNavUsdc.toString()) / 1e6);
console.log("Effective NAV (USDC):    ", Number(effectiveNav) / 1e6);
console.log("Queue pending (USDC):    ", Number(vault.queuePendingUsdc.toString()) / 1e6);
console.log("Reserve fund (USDC):     ", Number(vault.reserveFundUsdc.toString()) / 1e6);
console.log("Accrued perf fees (USDC):", Number(vault.pendingPerfFeesUsdc.toString()) / 1e6);
console.log("Total shares (ksUSD):    ", Number(vault.totalShares.toString()) / 1e6);
console.log("Position mode:           ", vault.positionMode);   // Idle / Normal / WindDown
console.log("Liquidity buffer bps:    ", vault.liquidityBufferBps);
console.log("Last settle ts:          ", new Date(Number(vault.lastSettleTs) * 1000));
console.log("Last NAV attest ts:      ", new Date(Number(vault.lastNavAttestTs) * 1000));
console.log("Funding EMA (bps):       ", vault.fundingAprSmoothedBps);
console.log("Peak share price 1e9:    ", vault.peakSharePrice1e9.toString());
console.log("HWM share price 1e9:     ", vault.hwmSharePrice1e9.toString());
console.log("Paused:                  ", vault.paused);
```

`cached_nav_usdc` refreshes on every deposit, withdrawal, and fee collection, and whenever someone runs `settle` or `attest_nav`. In between it holds the last recorded snapshot, so any profit or loss sitting open on the perp venue shows up at the next refresh rather than in real time.

***

## Pending queued withdrawal (if any)

```ts
// Derive your most recent withdrawal request PDA.
const [requestPda] = PublicKey.findProgramAddressSync(
  [
    Buffer.from("withdrawal_request"),
    vaultPda.toBuffer(),
    new BN(myRequestId).toArrayLike(Buffer, "le", 8),  // recorded when you called request_withdrawal
  ],
  PROGRAM_ID
);

const req = await program.account.withdrawalRequest.fetchNullable(requestPda);
if (req) {
  console.log("USDC owed:    ", Number(req.usdcOwed.toString()) / 1e6);
  console.log("Requested at: ", new Date(Number(req.requestedTs) * 1000));
  console.log("Processed:    ", req.processed);
}
```

The request account closes once `process_withdrawal` runs, and its rent deposit comes back to you.

***

## Related

* [Deposit](/keystone-finance/deposit.md) · [Withdraw](/keystone-finance/withdraw.md)
* [NAV & share pricing](/reference/nav-calculation.md)
* [Account structure](/for-developers/accounts.md) — full `Vault` and `WithdrawalRequest` layouts
* [Events](/for-developers/events.md) — programmatic subscription to NAV-changing events
