> 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/start-here/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 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;
// 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 price is stored as dollars × 1e9, so `1_030_000_000` is $1.03. Everything above is one division — the dollars the vault holds for shareholders, divided by the ksUSD outstanding. See [NAV & share pricing](/how-it-works/strategy-and-modes/nav-calculation.md) for why three items come out of NAV before that division.

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

Your balance times the price — the same arithmetic `withdraw_instant` runs:

```ts
// shares and sharePrice1e9 are both BigInt; dividing by 1e9 undoes the price scale.
const yourUsdc = (shares * 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("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](/start-here/deposit.md) · [Withdraw](/start-here/withdraw.md)
* [NAV & share pricing](/how-it-works/strategy-and-modes/nav-calculation.md)
* [Account structure](/build-on-it/quick-start/accounts.md) — full `Vault` and `WithdrawalRequest` layouts
* [Events](/build-on-it/quick-start/events.md) — programmatic subscription to NAV-changing events
