bvs_vault_base/msg.rs
1use crate::error::VaultError;
2use crate::shares::QueuedWithdrawalInfo;
3use cosmwasm_schema::{cw_serde, QueryResponses};
4use cosmwasm_std::{Addr, Api, Uint128};
5
6/// Vault `ExecuteMsg`, to be implemented by the vault contract.
7/// Callable by any `sender`, redeemable by any `recipient`.
8/// The `sender` can be the same as the `recipient` in some cases.
9#[cw_serde]
10#[derive(bvs_pauser::api::Display)]
11pub enum VaultExecuteMsg {
12 /// ExecuteMsg DepositFor assets into the vault.
13 /// Sender must transfer the assets to the vault contract (this is implementation agnostic).
14 /// The vault contract must mint shares to the `recipient`.
15 /// Vault must be whitelisted in the `vault-router` to accept deposits.
16 DepositFor(RecipientAmount),
17
18 /// ExecuteMsg WithdrawTo assets from the vault.
19 /// Sender must have enough shares to withdraw the requested amount to the `recipient`.
20 /// If the Vault is delegated to an `operator`, withdrawals must be queued.
21 /// Operator must not be validating any services for instant withdrawals.
22 WithdrawTo(RecipientAmount),
23
24 /// ExecuteMsg QueueWithdrawalTo assets from the vault.
25 /// Sender must have enough shares to queue the requested amount to the `recipient`.
26 /// Once the withdrawal is queued,
27 /// the `recipient` can redeem the withdrawal after the lock period.
28 /// Once the withdrawal is locked,
29 /// the `sender` cannot cancel the withdrawal.
30 /// The time-lock is enforced by the vault and cannot be changed retroactively.
31 ///
32 /// ### Lock Period Extension
33 /// New withdrawals will extend the lock period of any existing withdrawals.
34 /// You can queue the withdrawal to a different `recipient` than the `sender` to avoid this.
35 QueueWithdrawalTo(RecipientAmount),
36
37 /// ExecuteMsg RedeemWithdrawalTo all queued shares into assets from the vault for withdrawal.
38 /// After the lock period, the `sender` (must be the `recipient` of the original withdrawal)
39 /// can redeem the withdrawal.
40 RedeemWithdrawalTo(Recipient),
41
42 /// ExecuteMsg SlashLocked moves the assets from the vault to the `vault-router` contract for custody.
43 /// Part of the [https://build.satlayer.xyz/getting-started/slashing](Programmable Slashing) lifecycle.
44 /// This function can only be called by `vault-router`, and takes an absolute `amount` of assets to be moved.
45 /// The amount is calculated and enforced by the router.
46 /// Further utility of the assets, post-locked, is implemented and enforced on the router level.
47 SlashLocked(Amount),
48}
49
50#[cw_serde]
51/// This struct represents amount of assets.
52pub struct Amount(pub Uint128);
53
54impl Amount {
55 /// Validate the amount: [`Uint128`] field.
56 /// The amount must be greater than zero.
57 pub fn validate(&self, _api: &dyn Api) -> Result<(), VaultError> {
58 if self.0.is_zero() {
59 return Err(VaultError::zero("Amount cannot be zero"));
60 }
61 Ok(())
62 }
63}
64
65/// This struct is used to represent the recipient and amount fields together.
66#[cw_serde]
67pub struct RecipientAmount {
68 pub recipient: Addr,
69 pub amount: Uint128,
70}
71
72impl RecipientAmount {
73 /// Validate the recipient: [`Addr`] and amount: [`Uint128`] fields.
74 /// The recipient must be a valid [`Addr`], and the amount must be greater than zero.
75 pub fn validate(&self, api: &dyn Api) -> Result<(), VaultError> {
76 if self.amount.is_zero() {
77 return Err(VaultError::zero("Amount cannot be zero"));
78 }
79
80 api.addr_validate(self.recipient.as_str())?;
81 Ok(())
82 }
83}
84
85/// This struct is used to represent a recipient for RedeemWithdrawalTo.
86#[cw_serde]
87pub struct Recipient(pub Addr);
88
89impl Recipient {
90 /// Validate the recipient: [`Addr`] field.
91 /// The recipient must be a valid [`Addr`].
92 pub fn validate(&self, api: &dyn Api) -> Result<(), VaultError> {
93 api.addr_validate(self.0.as_str())?;
94 Ok(())
95 }
96}
97
98#[cw_serde]
99#[derive(QueryResponses)]
100pub enum VaultQueryMsg {
101 /// QueryMsg Shares: get the shares of a staker.
102 #[returns(SharesResponse)]
103 Shares { staker: String },
104
105 /// QueryMsg Assets: get the assets of a staker, converted from shares.
106 #[returns(AssetsResponse)]
107 Assets { staker: String },
108
109 /// QueryMsg ConvertToAssets: convert shares to assets.
110 #[returns(ConvertToAssetsResponse)]
111 ConvertToAssets { shares: Uint128 },
112
113 /// QueryMsg ConvertToShares: convert assets to shares.
114 #[returns(ConvertToSharesResponse)]
115 ConvertToShares { assets: Uint128 },
116
117 /// QueryMsg TotalShares: get the total shares in circulation.
118 #[returns(TotalSharesResponse)]
119 TotalShares {},
120
121 /// QueryMsg TotalAssets: get the total assets under vault.
122 #[returns(TotalAssetsResponse)]
123 TotalAssets {},
124
125 /// QueryMsg QueuedWithdrawal: get the queued withdrawal and unlock timestamp under vault.
126 #[returns(QueuedWithdrawalResponse)]
127 QueuedWithdrawal { staker: String },
128
129 /// QueryMsg VaultInfo: get the vault information.
130 #[returns(VaultInfoResponse)]
131 VaultInfo {},
132}
133
134/// The response to the `Shares` query.
135/// This is just a wrapper around `Uint128`, so that the schema can be generated.
136#[cw_serde]
137pub struct SharesResponse(Uint128);
138
139/// The response to the `Assets` query.
140/// This is just a wrapper around `Uint128`, so that the schema can be generated.
141#[cw_serde]
142pub struct AssetsResponse(Uint128);
143
144/// The response to the `ConvertToAssets` query.
145/// This is just a wrapper around `Uint128`, so that the schema can be generated.
146#[cw_serde]
147pub struct ConvertToAssetsResponse(Uint128);
148
149/// The response to the `ConvertToShares` query.
150/// This is just a wrapper around `Uint128`, so that the schema can be generated.
151#[cw_serde]
152pub struct ConvertToSharesResponse(Uint128);
153
154/// The response to the `TotalShares` query.
155/// This is just a wrapper around `Uint128`, so that the schema can be generated.
156#[cw_serde]
157pub struct TotalSharesResponse(Uint128);
158
159/// The response to the `TotalAssets` query.
160/// This is just a wrapper around `Uint128`, so that the schema can be generated.
161#[cw_serde]
162pub struct TotalAssetsResponse(Uint128);
163
164/// The response to the `QueuedWithdrawal` query.
165/// This is just a wrapper around `QueuedWithdrawalInfo`, so that the schema can be generated.
166#[cw_serde]
167pub struct QueuedWithdrawalResponse(QueuedWithdrawalInfo);
168
169#[cw_serde]
170pub struct VaultInfoResponse {
171 /// The total shares in circulation
172 pub total_shares: Uint128,
173
174 /// The total assets under management
175 pub total_assets: Uint128,
176
177 /// The `vault-router` contract address
178 pub router: Addr,
179
180 /// The `pauser` contract address
181 pub pauser: Addr,
182
183 /// The `operator` that this vault is delegated to
184 pub operator: Addr,
185
186 /// Asset identifier, using the CAIP-19 format.
187 pub asset_id: String,
188
189 /// The asset type, either `AssetType::Cw20` or `AssetType::Bank`.
190 pub asset_type: AssetType,
191
192 /// The asset reference stores the cw20 contract address or the bank denom.
193 pub asset_reference: String,
194
195 /// The name of the vault contract, see [`cw2::set_contract_version`] for more information.
196 pub contract: String,
197
198 /// The version of the vault contract, see [`cw2::set_contract_version`] for more information.
199 pub version: String,
200}
201
202#[cw_serde]
203pub enum AssetType {
204 Cw20,
205 Bank,
206}