Mainnet Checklist

Start small, scale progressively. Complete each phase before advancing.


Program IDs

All four programs use the same key on mainnet and devnet. Keep your upgrade keypairs secure.

Program
ID

Keystone Core

rDd3hjjEdH2xJWH9RnQupX7ZTPxrzmBZhL76eS8dW8c

Keystone Alpha

2JTb5UiM6mAYDUmnSiTgZXTTEJAJs98YRDcKLU6AGeZN

Keystone Neutral

BxKFa6GRKYgNKxRzJ4kXCHiDo2PodpNtKVWhJTZMtAXR

Keystone Defense

FKtpFEd4B5jGRkgLf5AN2eZMikmkEJYf59XzR6YbTxPA


Step 1 — Build Programs

Alpha, Neutral, and Defense are built without the devnet feature flag for mainnet.

# From repo root
cargo build-sbf --manifest-path programs/keystone-core/Cargo.toml
cargo build-sbf --manifest-path programs/keystone-alpha/Cargo.toml
cargo build-sbf --manifest-path programs/keystone-neutral/Cargo.toml
cargo build-sbf --manifest-path programs/keystone-defense/Cargo.toml

# Binaries land in:
# target/deploy/keystone_core.so
# target/deploy/keystone_alpha.so
# target/deploy/keystone_neutral.so
# target/deploy/keystone_defense.so

Devnet builds add -- --features devnet to skip Pyth ownership validation and use a mock $100 SOL price. Do not add that flag for mainnet.


Step 2 — Deploy Programs

Verify each deployed program:


Step 3 — Initialize Everything

One script handles the full initialization sequence in the correct order:

What it does (each step is idempotent — safe to re-run):

Step
Action

1a

initialize_fund × 3 on Keystone Alpha (fund_id 1, 2, 3)

1b

initialize_fund × 3 on Keystone Neutral (fund_id 1, 2, 3)

1c

initialize_fund × 3 on Keystone Defense (fund_id 1, 2, 3)

2

initialize_portfolio + register_fund_atas × 3 on Keystone Core

3

set_core_gate × 9 — locks all sub-funds to Core-only access

After completion, all 9 sub-fund instances accept deposits and withdrawals only through Core. Direct access is rejected with DirectDepositsDisabled (6051).

Estimated rent: ~0.2 SOL per fund state + ATAs + gate PDAs ≈ 2–2.5 SOL total.


Step 4 — Configure Neutral Fund (Manual)

These settings cannot be applied via initialize_fund or update_fund_params — they require either a custom instruction or are set at the time of first position open.

4a. Jupiter Perps pool and custody addresses

BasisFundState stores jupiter_pool, jupiter_sol_custody, and jupiter_collateral_custody. Every deploy_capital / close_position / settle_funding call validates that the accounts you pass match these on-chain keys.

Set them once after initialization (using the fund's admin keypair). This requires a one-off script or a Solana account write to the fund state. See Admin Operations for the current recommended approach.

4b. Enable Marginfi idle-capital parking (optional)

Creates a Marginfi account owned by fund_authority and sets lending_enabled = true. After this, the keeper can call park_capital when the position is closed and deploy_capital will auto-withdraw from Marginfi when redeploying.

4c. Enable reverse basis (optional)

Creates a Kamino obligation owned by fund_authority. Required before the keeper can call deploy_reverse.

4d. Enable positive-APY guards


Step 5 — Start Keepers


Deployment Phases

Phase 1: Soft Launch (Weeks 1–4)

Phase 2: Beta (Weeks 5–8)

Phase 3: Post-Audit (Week 12+)


Pre-Launch Checklist

Code

Oracle

Protocol Integrations

Infrastructure


Rollback

Each program is upgradeable via its upgrade keypair. In an emergency:

See Admin Operations for pause/unpause instructions.

Last updated