KAGURA 神楽

KAGURA is a continuous-time DeFi primitive on Solana. Two on-chain Anchor programs: a tick-attestation registry, and a USDC funding vault that compounds yield every block instead of every hour.

contact: hello@kagura.network
神楽KAGURA/ docs
v0.1.0 · pre-deployment← back to sitegithub →
programs·kagura-vault

kagura-vault

continuous funding vault. 7 instructions, 1 vault state + 3 token accounts, 11 errors, 3 events.

program idHQYVFcbezorwCqPK69keUAoe4p1zgPzCVDfJq4XWymk8
size397 kb
depends onkagura-core, spl-token

accounts

state.rsrust
1#[account]2#[derive(InitSpace, Debug)]3pub struct Vault {4    pub authority: Pubkey,5    pub usdc_mint: Pubkey,6    pub share_mint: Pubkey,7    pub principal_account: Pubkey,8    pub treasury_account: Pubkey,9    pub kagura_protocol: Pubkey,10    pub funding_rate_bps: u32,11    pub last_tick_unix_ms: i64,12    pub total_ticks: u64,13    pub total_accrued_lifetime: u64,14    pub paused: bool,15    pub bump: u8,16    pub principal_auth_bump: u8,17    pub treasury_auth_bump: u8,18    pub share_mint_bump: u8,19}

pda graph

seedstext
1vault             ←  [b"kagura-vault",   authority.key()]2share_mint        ←  [b"share-mint",     vault.key()]3principal_authority  ←  [b"principal-auth", vault.key()]4treasury_authority   ←  [b"treasury-auth",  vault.key()]5principal_account ←  [b"principal",      vault.key()]    (token account)6treasury_account  ←  [b"treasury",       vault.key()]    (token account)

instructions

initialize_vault

Creates the vault state pda + share mint + two token accounts.

signaturerust
1pub fn initialize_vault(2    ctx: Context<InitializeVault>,3    funding_rate_bps: u32,4) -> Result<()>5 6// validation:7//   funding_rate_bps <= MAX_FUNDING_RATE_BPS (30_000 = 300% APR)

set_funding_rate

Vault authority changes the target apr. Bound to [0, 30_000] bps.

signaturerust
1pub fn set_funding_rate(ctx: Context<SetFundingRate>, new_rate_bps: u32) -> Result<()>

set_paused

Pauses deposits / withdraws / ticks. Reads of vault state continue working.

signaturerust
1pub fn set_paused(ctx: Context<SetVaultPaused>, paused: bool) -> Result<()>

top_up_treasury

Anyone can fund the treasury. The signer must control the source token account.

signaturerust
1pub fn top_up_treasury(ctx: Context<TopUpTreasury>, amount: u64) -> Result<()>

deposit

User deposits amount usdc, mints proportional shares.

signaturerust
1pub fn deposit(ctx: Context<Deposit>, amount: u64) -> Result<()>2 3// math:4//   shares_to_mint = amount × total_shares / vault_balance5//   (or amount, on first deposit)

withdraw

User burns shares, receives proportional usdc from principal_account.

signaturerust
1pub fn withdraw(ctx: Context<Withdraw>, shares: u64) -> Result<()>2 3// math:4//   assets_out = shares × vault_balance / total_shares

tick_funding

Cpis into kagura-core::record_tick, computes the per-tick accrual, transfers usdc from treasury → principal.

signaturerust
1pub fn tick_funding(ctx: Context<TickFunding>) -> Result<()>2 3// math:4//   tick      = kagura_core::record_tick(...)5//   accrued   = principal × rate_bps × elapsed_ms / (10_000 × 31_536_000_000)6//   transfer  = min(accrued, treasury_balance)7//   total_accrued_lifetime += transfer

events

state.rsrust
1#[event] pub struct FundingTicked {2    pub vault: Pubkey, pub tick_number: u64, pub elapsed_ms: u32,3    pub principal_before: u64, pub accrued: u64,4    pub treasury_remaining: u64, pub now_unix_ms: i64,5}6 7#[event] pub struct Deposited {8    pub vault: Pubkey, pub user: Pubkey, pub amount: u64,9    pub shares_minted: u64, pub principal_after: u64, pub total_shares_after: u64,10}11 12#[event] pub struct Withdrawn {13    pub vault: Pubkey, pub user: Pubkey, pub shares_burned: u64,14    pub amount: u64, pub principal_after: u64, pub total_shares_after: u64,15}

errors

codemessage
Unauthorizedauthority mismatch
FundingRateOutOfRangefunding rate must be between 0 and 30000 bps (0%-300%)
ZeroDepositdeposit amount must be greater than zero
ZeroWithdrawwithdraw shares must be greater than zero
InsufficientSharesinsufficient shares
TreasuryExhaustedtreasury exhausted, top up required
VaultPausedvault is paused
ClockRegressionclock regression detected
MathOverflowmath overflow
KaguraProtocolMismatchkagura protocol mismatch
ShareMintMismatchshare mint mismatch
UsdcMintMismatchusdc mint mismatch

constants

state.rsrust
1pub const VAULT_SEED:          &[u8] = b"kagura-vault";2pub const PRINCIPAL_AUTH_SEED: &[u8] = b"principal-auth";3pub const TREASURY_AUTH_SEED:  &[u8] = b"treasury-auth";4pub const SHARE_MINT_SEED:     &[u8] = b"share-mint";5pub const MAX_FUNDING_RATE_BPS: u32 = 30_000;       // 300% APR ceiling