# Devnet

End-to-end procedure for standing the ksUSD vault up on devnet.

> Updated 2026-05-17.

***

## Program ID

| Network | Program                          | Address                                        |
| ------- | -------------------------------- | ---------------------------------------------- |
| Devnet  | `keystone_finance` (ksUSD vault) | `HvsAc157bJ7Pd4uGr7xssHMifGs6RMbPu14ZMsiEABWT` |

* IDL location: `target/idl/keystone_finance.json` (after `anchor idl build`)
* Regenerate whenever the program source changes
* Consumers: marketing site, devnet scripts, docs all read this file

***

## Prerequisites

* Solana CLI configured for devnet (`solana config set --url devnet`)
* A funded devnet wallet at `~/.config/solana/devnet.json` (\~0.1 SOL for rent + tx fees)
* Anchor 0.31.1+ and the rustup-managed cargo on PATH:

  ```bash
  PATH="$HOME/.cargo/bin:$PATH"
  ```

***

## 1. Build + deploy

```bash
PATH="$HOME/.cargo/bin:$PATH" anchor build

solana program deploy \
  --program-id target/deploy/keystone_finance-keypair.json \
  --url devnet \
  target/deploy/keystone_finance.so

# Refresh the on-chain IDL.
PATH="$HOME/.cargo/bin:$PATH" anchor idl build -o target/idl/keystone_finance.json
anchor idl upgrade HvsAc157bJ7Pd4uGr7xssHMifGs6RMbPu14ZMsiEABWT \
  -f target/idl/keystone_finance.json
```

> If the BPF toolchain isn't installed locally, skip the `.so` rebuild and just refresh the IDL — the program binary already on devnet is current.

***

## 2. Initialize the vault

```bash
npx tsx scripts/devnet/init.neutral.ts
```

Performs:

1. Derive vault PDA at `[b"vault"]`
2. Generate a fresh ksUSD share-mint keypair
3. Call `initialize` with default risk parameters:
   * 10% liquidity buffer
   * +2% / −12% funding thresholds
   * 20% perf fee · 5% reserve skim
   * $1M deposit cap
   * 12 h dwell · 0.5% slippage
   * 5% drawdown guard · 2 consecutive-settles required
   * 5% LST depeg
4. Pin the reserve USDC ATA

* Idempotent on the vault PDA — if it already exists, the script reverts cleanly with `account_already_initialized`
* To re-init, deploy under a fresh program ID

***

## 3. Pin oracles

```bash
# scripts/devnet/test-oracle.ts — confirms Pyth pull-oracle feeds are reachable;
# use it as a template, then call set_oracles with the chosen pull-oracle pubkeys.
```

* `set_oracles` records the SOL/USD and jitoSOL/USD pull-oracle accounts on the vault
* Required before any strategy instruction that reads prices

***

## 4. (Optional) Enable Drift

```bash
# scripts/devnet/enable-drift.ts — needs Drift devnet account scaffolding.
# Calls drift_cpi::initialize_user_stats + initialize_user for the vault.
```

* Required before any perp position can be opened
* Until run, the vault can still process: `deposit` · `withdraw_instant` · `request_withdrawal` · `process_withdrawal`
* These only touch USDC / ksUSD / the queue PDA — no Drift dependency

***

## 5. (Optional) Enable reverse basis

```bash
# scripts/devnet/enable-reverse.ts — needs Kamino devnet obligation seeds.
# Calls kamino::init_kamino_obligation for the vault.
```

> Required only if reverse-basis mode will ever be used. Vault can run normal + idle without it.

***

## 6. (Optional) Enable Kamino lending for idle + reserve USDC

* Pins the Kamino USDC reserve
* Creates the two cToken ATAs:
  * `vault_lend_collateral_ata` — idle leg
  * `reserve_lend_collateral_ata` — reserve leg
* Required before `lend_idle_usdc` / `unlend_usdc` / `lend_reserve` / `unlend_reserve`

***

## 7. Round-trip test

```bash
npx tsx scripts/devnet/test-roundtrip.ts
```

Exercises the user flow end-to-end:

1. Verifies the vault exists; mints test USDC to the wallet if it holds USDC mint authority.
2. `deposit` 100 USDC → mint ksUSD; verifies first-deposit math is 1:1 at $1.00.
3. `withdraw_instant` 25 ksUSD → receive \~25 USDC back; verifies par redemption.
4. `request_withdrawal` 10 ksUSD → creates a `WithdrawalRequest` PDA.
5. `process_withdrawal` → pays out USDC, closes the PDA, refunds rent.

> Strategy paths (`open_position`, `open_reverse`, `settle`, etc.) are deferred to the keeper bot — they require Drift devnet accounts and Jupiter routes, easier to script with the dedicated keeper.

***

## Troubleshooting

| Symptom                                            | Cause                                               | Fix                                                                                   |
| -------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `wallet not found`                                 | No keypair at `~/.config/solana/devnet.json`        | `solana-keygen new --outfile ~/.config/solana/devnet.json`                            |
| `account_already_initialized` on init              | Vault PDA already exists from a prior run           | Either keep the existing vault, or deploy a fresh program ID                          |
| `insufficient SOL`                                 | Wallet < 0.05 SOL                                   | `solana airdrop 2` (devnet)                                                           |
| `InvalidMint` on deposit                           | User's USDC ATA is on the wrong mint                | Vault was initialized with a specific USDC mint — fetch `vault.usdcMint` and use that |
| `BootstrapResidualUsdc` on first deposit           | Vault USDC ATA has stray USDC from a prior test run | Drain the ATA before the first depositor mints                                        |
| `LendingNotEnabled` on `lend_idle_usdc`            | `enable_lending` not run yet                        | Run it as part of devnet setup                                                        |
| `StaleOracle` on strategy instruction              | Pyth feed not pinned, or feed not updating          | Run `set_oracles`; verify the pinned pull-oracle is the one currently being updated   |
| IDL out of date (legacy instructions still listed) | Forgot to `anchor idl build` after a source change  | Rebuild the IDL with the rustup cargo on PATH                                         |

***

## Related

* [Quick start](/for-developers/quick-start.md) · [Instructions reference](/for-developers/instructions.md)
* [Admin operations](/for-operators/admin-ops.md) · [Keeper bot](/for-operators/keeper-bot.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keystonefi.xyz/deployment/devnet.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
