A compact Solana program that pools user SOL deposits into a raffle/prize mechanism while earning yield via Marinade (liquid staking). Users deposit SOL to receive tickets, an admin stakes pooled SOL into Marinade for yield, and winners are selected from ticket holders to claim part of the pool.
Halopot is a small, practical on-chain application demonstrating how to:
- Pool user deposits in SOL, representing those deposits as tickets,
- Stake pooled SOL through Marinade (mSOL) to earn yield while maintaining liquidity with Marinade’s liquid unstaking, and
- Run a simple raffle-style prize flow (deposit → pick winner → claim prize → withdraw).
It is intentionally minimal so it can be used as a learning project or bootstrapped into a more feature-rich product.
- Program (Rust + Anchor): All on-chain logic lives in
programs/escrow.instructions/contains handlers likedeposit,withdraw,stakeandunstake.states/defines on-chain state (e.g.,PoolState, ticket data).
- Integration with Marinade: the program uses Marinade CPI (
marinade-cpi) to perform liquid stake and liquid un-stake operations. - TypeScript client & IDL: the generated
idl/andtypes/make it easy to interact with the program from off-chain code.
Diagram: see the architecture image in the repository for a visual overview.
- On-chain: Rust, Anchor (Anchor framework),
marinade-cpifor Marinade integration - Off-chain / tooling: TypeScript, Node, pnpm/npm
- Dev tooling: Solana CLI,
solana-test-validator, Anchor CLI
Prerequisites:
- Rust (use project's
rust-toolchain.toml), +cargo - Anchor CLI (install per Anchor docs), and Solana CLI (
solana) - Node.js + pnpm or npm
Quickstart:
- Clone and install deps
git clone <repo-url>
cd halopot
pnpm install # or npm install- Run a local validator (optional;
anchor testwill spawn a test validator automatically):
solana-test-validator --reset
# in another terminal
anchor test # runs tests and builds the program- Build program
anchor build- Deploy (localnet)
anchor deploy --provider.cluster localnet
# or run migrations: `anchor test` usually handles deploy for tests- Run tests
anchor test
# or run TypeScript tests if present
pnpm testNotes:
migrations/deploy.tscontains deploy logic for scripts you may want to adapt for integration and staging.- Use the IDL in
idl/halopot.jsonand the types intypes/halopot.tsfor building off-chain clients.
- Users call
deposit(1 SOL per ticket in this implementation) — SOL is transferred into the program PDA. - Admin calls
stakewhich performs a Marinade CPI deposit to convert SOL → mSOL that accrues yield. - Admin or program picks winners (
pick_winner) and the winner canclaim_prize. - To give users a way to exit, there is a
withdrawflow (burn ticket, get SOL back) and the program provides aliquid_unstakeCPI integration to redeem mSOL to SOL if needed.
Thanks for thinking about contributing! A few ground rules:
- Keep changes small and focused — make it easy to review.
- Add tests for behavior you change or add (we use Anchor tests; see
anchor test). - Follow existing code style: Rust + Anchor best-practices for on-chain code and TypeScript for off-chain tooling.
Suggested workflow:
- Fork & branch from
main. - Run tests locally and make sure all existing tests pass.
- Open a PR with a clear description and include tests and/or screenshots where helpful.
- This project is intended for learning and prototyping. If you plan to run anything with real funds, review security, audits, and Marinade integration assumptions thoroughly.
- To update dependencies, update
Cargo.tomlandpackage.jsonthen re-run builds and tests.
If you'd like, I can add an example script that uses the IDL + @coral-xyz/anchor to deposit/stake/unstake against a local validator, or add a CONTRIBUTING.md template. Want me to add either of those?