A non-custodial auto stop-loss vault powered by Pyth oracle on Solana.
Yield Guard protects DeFi investors from market crashes by automatically executing stop-loss orders when prices hit your configured threshold. The vault automatically swaps tokens to USDC via Jupiter DEX.
- Non-custodial: Assets are held by program-derived addresses (PDAs), the admin cannot withdraw funds
- Automatic Execution: Anyone can trigger stop-loss when price conditions are met
- Pyth Oracle Integration: Real-time price feeds with confidence validation
- Jupiter DEX: Best rate token swap aggregation
- Comprehensive Security: PDA protection, stale price checks, overflow protection
User
│
├─► InitializeVault (create vault for a token)
│
├─► Deposit (add tokens to vault)
│
├─► UpdateStopLoss (change threshold)
│
├─► [Price drops below threshold]
│ │
│ └─► ExecuteStopLoss (auto-swap to USDC)
│
└─► ClaimRewards (withdraw USDC)
| Instruction | Description |
|---|---|
initialize_vault |
Create a new stop-loss vault for a token |
deposit |
Deposit tokens into the vault |
withdraw |
Withdraw tokens (disabled after stop-loss triggered) |
update_stop_loss_price |
Update the stop-loss threshold |
execute_stop_loss |
Trigger stop-loss (anyone can call) |
claim_rewards |
Claim USDC after stop-loss |
Stores vault configuration and state:
authority: Vault ownertoken_mint: Token to be protectedprice_feed: Pyth price feed accountstop_loss_price: Trigger price thresholdis_stop_loss_triggered: Stop-loss executed flagtotal_value_locked: TVL in the vault
Per-user position tracking:
owner: Position ownerdeposited_amount: Token amount depositedentry_price: Price at time of depositis_liquidated: Position liquidated flag
- PDA Protection: All accounts use program-derived addresses with canonical bumps
- Oracle Validation:
- Stale price detection (max 60 seconds)
- Confidence ratio check (max 50%)
- Arithmetic Safety: All math uses checked operations
- CPI Whitelisting: Only Jupiter and Token programs can. Idemp be called 5otent Execution: Stop-loss can only trigger once
GuaRG7Ydz2gEeY5z7z9hH8f9vQxJpJcVmGpYqK3W3YxW
# Install dependencies
npm install
# Build the program
npm run build
# or
cargo build-sbf --manifest-path=programs/yield-guard/Cargo.toml
# Run tests
npm run testThe project uses a three-tier testing approach:
- Unit Tests (
tests/unit/): Fast Rust tests with Mollusk - Integration Tests (
tests/integration/): LiteSVM tests - End-to-End Tests (
tests/yield-guard.ts): TypeScript tests
# Run all tests
npm run test
# Run Rust unit tests only
npm run test:unitsolana-test-validator
anchor deployanchor deploy --provider.cluster devnetanchor deploy --provider.cluster mainnet// 1. Initialize vault
await program.methods
.initializeVault({ stopLossPrice, slippageTolerance, cooldownSeconds })
.accounts({ /* accounts */ })
.rpc();
// 2. Deposit tokens
await program.methods
.deposit(new BN(amount))
.accounts({ /* accounts */ })
.rpc();
// 3. When price drops below threshold, anyone can trigger
await program.methods
.executeStopLoss(quoteBytes) // quote from Jupiter API
.accounts({ /* accounts */ })
.rpc();
// 4. Claim USDC
await program.methods
.claimRewards()
.accounts({ /* accounts */ })
.rpc();├── programs/yield-guard/
│ ├── src/
│ │ ├── lib.rs # Main program (instructions + accounts)
│ │ ├── state.rs # Account structs + events
│ │ └── errors.rs # Error definitions
│ └── Cargo.toml
├── tests/
│ ├── yield-guard.ts # TypeScript integration tests
│ ├── unit/mod.rs # Mollusk unit tests
│ └── integration/mod.rs # LiteSVM integration tests
├── Anchor.toml # Anchor configuration
├── package.json # npm scripts
└── tsconfig.json # TypeScript config
- Anchor 0.30.1
- Solana 1.18.0
- TypeScript 5.0
This is experimental software. Before mainnet deployment:
- Get a professional security audit
- Increase test coverage
- Add upgrade authority with timelock
- Consider formal verification
MIT
Open source for hackathon participation. Contributions welcome!