Skip to main content
Solana programs are compiled binaries running on-chain. When you interact with a protocol, you’re trusting that the deployed binary matches the open-source code you can read. Most protocols ask you to take their word for it. We don’t. Every layer of the Percolator protocol is independently verifiable:
1

Verifiable builds

The exact same Docker container and locked dependencies produce the exact same binary every time. CI publishes the SHA-256 hash — you can reproduce it yourself.
2

On-chain comparison

Dump the deployed program from Solana, hash it, and compare. If the hashes match, the code you read is the code that runs.
3

SDK audit

The TypeScript SDK that builds your transactions has been verified byte-for-byte against the Rust source — every instruction tag, every account ordering, every encoding.
4

Formal verification

143 Kani model-checking proofs verify the risk engine’s safety invariants mathematically, not just by testing.

What is an SBF Build?

Solana programs compile to SBF (Solana Bytecode Format) — a variant of eBPF designed for the Solana runtime. The compiled .so file is what gets deployed on-chain and executed by validators. The problem: Rust builds are not deterministic across machines. Different OS versions, toolchains, or dependency resolution can produce different binaries from the same source code. This means you can’t just cargo build on your laptop and compare. The solution: verifiable builds use a pinned Docker image with an exact Rust version, exact Solana tools, and a locked Cargo.lock to guarantee the same source always produces the same bytes. If the hashes match, the deployed program is byte-for-byte identical to the open-source code.

Verified Builds

Percolator Program

Latest CI run — click to see build logs and artifact hash

Matcher Program

Latest CI run — click to see build logs and artifact hash

Percolator Program

Matcher Program

What the CI Does

Each verified build workflow runs these steps inside GitHub Actions:
  1. Checkout — Clone the verifiable-build branch with full history
  2. Docker build — Spin up solanafoundation/solana-verifiable-build (pinned version), install the exact Rust toolchain
  3. Compile — cargo-build-sbf --force-tools-install --sbf-out-dir target/deploy -- --locked ensures the Cargo.lock is respected exactly
  4. Hash — shasum -a 256 produces the deterministic SHA-256 of the .so binary
  5. Upload — The artifact (.so + .sha256) is published to GitHub Actions for anyone to download
The --locked flag is critical — it prevents Cargo from resolving newer dependency versions that could change the output.

Verify It Yourself

A scripts/verify.sh helper in the repo does this in one command.
You can also use solana-verify for automated verification: solana-verify verify-from-repo --program-id <ID> --url https://github.com/purpletrade/percolator-prog

Upstream Transparency

Both repositories include an upstream-sync.yml CI workflow that checks for divergence from Anatoly Yakovenko’s original source. Every change we make is visible in the commit history:

Security Metadata

Both programs embed solana-security-txt in the on-chain binary — contact info, source repo, and security policy discoverable directly from explorers. Programs are verified on OtterSec and display green verification badges on Solscan:

Formal Verification

The risk engine (purpletrade/percolator) is verified using Kani model checking — 143 proofs that mathematically verify safety invariants:

Conservation

No value created from nothing. Deposits + insurance = withdrawable capital + positions.

Isolation

No cross-account contagion. One account’s state cannot corrupt another’s.

No Over-Withdrawal

Users cannot extract more than deposited capital plus earned PnL.

SDK Source Audit

The TypeScript SDK at src/lib/percolator/ has been verified instruction-by-instruction against the Rust source at aeyakovenko/percolator-prog.
Tag 21 (AdminForceCloseAccount) exists in the Rust source but is intentionally omitted from the SDK as it is an admin-only emergency function.
Every instruction’s data payload verified against the Rust decode functions. All little-endian with exact byte offsets:
  • u8, u16, u32, u64: Standard LE integers
  • i64, i128: Signed integers (twos complement, LE)
  • u128: 16-byte LE (prices in PushOraclePrice)
  • [u8; 32]: Raw pubkey bytes (UpdateAdmin, SetOracleAuthority)
Each instruction’s accounts verified against process_instruction in percolator.rs. Example for TradeCpi:
All 21 instruction account orderings match.
Vault authority:
LP PDA:
Checked against #[repr(C)] layout rules with alignment and padding.

Methodology

  1. Read the complete Rust source (percolator.rs, ~4,400 lines)
  2. Extract every instruction’s decode logic, account ordering, and data format
  3. Compare line-by-line against the TypeScript SDK (instructions.ts, accounts.ts, slab.ts, pda.ts, errors.ts)
  4. Confirm byte-level compatibility for all encoded data

Source References

percolator-prog

Core program — verified builds, security.txt, formal proofs

percolator-match

LP matcher — verified builds, vAMM implementation

Original source

Canonical source by Anatoly Yakovenko

Risk engine

Formally verified library — 143 Kani proofs