1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
//! Vault contract
use cosmwasm_std::{Addr, Uint128};
use serde::{Deserialize, Deserializer};
use std::collections::HashMap;
/// Message to instantiate the contract
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
#[serde(rename_all = "snake_case")]
pub struct InstantiateMsg {
/// Denomination of the USDC token
pub usdc_denom: String,
/// Governance address (as string, validated later)
pub governance: String,
/// Initial allocation percentages to markets
pub markets_allocation_bps: HashMap<String, u16>,
}
/// Configuration structure for the vault
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub struct Config {
/// Denomination of the USDC token
pub usdc_denom: String,
/// Address authorized for critical actions (like pausing the contract)
pub governance: Addr,
/// Allocation percentages to markets in basis points (100 bps = 1%)
#[serde(deserialize_with = "deserialize_markets_allocation_bps")]
pub markets_allocation_bps: HashMap<Addr, u16>,
/// state::PAUSED
pub paused: bool,
}
/// Executable messages for the contract
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
/// Deposit USDC and receive USDCLP
Deposit {},
/// Request withdrawal by burning USDCLP
RequestWithdrawal {
/// Amount to withdraw
amount: Uint128,
},
/// Redistribute excess funds to markets
RedistributeFunds {},
/// Collect yields from markets
CollectYield {},
/// Process a pending withdrawal
ProcessWithdrawal {},
/// Withdraw funds from a market
WithdrawFromMarket {
/// From Market
market: String,
/// Amount
amount: Uint128,
},
/// Pause the contract in an emergency
EmergencyPause {},
/// Resume contract operations
ResumeOperations {},
/// Update allocation percentages
UpdateAllocations {
/// New allocations for Markets
#[serde(deserialize_with = "deserialize_markets_allocation_bps")]
new_allocations: HashMap<Addr, u16>,
},
/// Add a new market to the vault
AddMarket {
/// Market address to add
market: String,
},
}
/// Query messages for the contract
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
/// Query the USDC balance in the vault
GetVaultBalance {},
/// Query a user's pending withdrawal
GetPendingWithdrawal {
/// User to get pending withdrawal
user: String,
},
/// Query total assets (balance + allocations)
GetTotalAssets {},
/// Query market allocations
GetMarketAllocations {
/// Start from market
start_after: Option<String>,
},
/// Query the vault's configuration
GetConfig {},
}
fn deserialize_markets_allocation_bps<'de, D>(
deserializer: D,
) -> Result<HashMap<Addr, u16>, D::Error>
where
D: Deserializer<'de>,
{
let string_map = HashMap::<String, u16>::deserialize(deserializer)?;
let addr_map = string_map
.into_iter()
.map(|(k, v)| (Addr::unchecked(k), v))
.collect();
Ok(addr_map)
}