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 QueueWithdrawalTo assets from the vault.
19 /// Sender must have enough shares to queue the requested amount to the `controller`.
20 /// Once the withdrawal is queued,
21 /// the `controller` can redeem the withdrawal after the lock period.
22 /// Once the withdrawal is locked,
23 /// the `sender` cannot cancel the withdrawal.
24 /// The time-lock is enforced by the vault and cannot be changed retroactively.
25 ///
26 /// ### Lock Period Extension
27 /// New withdrawals will extend the lock period of any existing withdrawals.
28 /// You can queue the withdrawal to a different `controller` than the `sender` to avoid this.
29 QueueWithdrawalTo(QueueWithdrawalToParams),
30
31 /// ExecuteMsg RedeemWithdrawalTo all queued shares into assets from the vault for withdrawal.
32 /// After the lock period, the `sender` (must be the `controller` of the original withdrawal)
33 /// can redeem the withdrawal to the `recipient`
34 RedeemWithdrawalTo(RedeemWithdrawalToParams),
35
36 /// ExecuteMsg SlashLocked moves the assets from the vault to the `vault-router` contract for custody.
37 /// Part of the [https://build.satlayer.xyz/architecture/slashing](Programmable Slashing) lifecycle.
38 /// This function can only be called by `vault-router`, and takes an absolute `amount` of assets to be moved.
39 /// The amount is calculated and enforced by the router.
40 /// Further utility of the assets, post-locked, is implemented and enforced on the router level.
41 SlashLocked(Amount),
42
43 /// ExecuteMsg ApproveProxy allows the `proxy`
44 /// to queue withdrawal and redeem withdrawal on behalf of the `owner`.
45 SetApproveProxy(SetApproveProxyParams),
46}
47
48#[cw_serde]
49/// This struct represents amount of assets.
50pub struct Amount(pub Uint128);
51
52impl Amount {
53 /// Validate the amount: [`Uint128`] field.
54 /// The amount must be greater than zero.
55 pub fn validate(&self, _api: &dyn Api) -> Result<(), VaultError> {
56 if self.0.is_zero() {
57 return Err(VaultError::zero("Amount cannot be zero"));
58 }
59 Ok(())
60 }
61}
62
63/// This struct is used to represent the controller and amount fields together.
64#[cw_serde]
65pub struct QueueWithdrawalToParams {
66 /// the controller is the address that can redeem the withdrawal after the lock period
67 pub controller: Addr,
68 /// the owner is the address that owns the shares being withdrawn
69 pub owner: Addr,
70 /// the amount is the amount of shares to be withdrawn
71 pub amount: Uint128,
72}
73
74impl QueueWithdrawalToParams {
75 /// Validate the controller: [`Addr`] and amount: [`Uint128`] fields.
76 /// The controller must be a valid [`Addr`], and the amount must be greater than zero.
77 pub fn validate(&self, api: &dyn Api) -> Result<(), VaultError> {
78 if self.amount.is_zero() {
79 return Err(VaultError::zero("Amount cannot be zero"));
80 }
81
82 api.addr_validate(self.controller.as_str())?;
83 api.addr_validate(self.owner.as_str())?;
84 Ok(())
85 }
86}
87
88/// This struct is used to represent the recipient and amount fields together.
89#[cw_serde]
90pub struct RecipientAmount {
91 pub recipient: Addr,
92 pub amount: Uint128,
93}
94
95impl RecipientAmount {
96 /// Validate the recipient: [`Addr`] and amount: [`Uint128`] fields.
97 /// The recipient must be a valid [`Addr`], and the amount must be greater than zero.
98 pub fn validate(&self, api: &dyn Api) -> Result<(), VaultError> {
99 if self.amount.is_zero() {
100 return Err(VaultError::zero("Amount cannot be zero"));
101 }
102
103 api.addr_validate(self.recipient.as_str())?;
104 Ok(())
105 }
106}
107
108/// This struct is used to represent a recipient for RedeemWithdrawalTo.
109#[cw_serde]
110pub struct RedeemWithdrawalToParams {
111 pub controller: Addr,
112 pub recipient: Addr,
113}
114
115impl RedeemWithdrawalToParams {
116 /// The recipient must be a valid [`Addr`].
117 /// The controller must be a valid [`Addr`].
118 pub fn validate(&self, api: &dyn Api) -> Result<(), VaultError> {
119 api.addr_validate(self.controller.as_str())?;
120 api.addr_validate(self.recipient.as_str())?;
121 Ok(())
122 }
123}
124
125#[cw_serde]
126pub struct SetApproveProxyParams {
127 /// The proxy address that is being approved.
128 pub proxy: Addr,
129 /// whether the proxy is approved or not.
130 pub approve: bool,
131}
132
133impl SetApproveProxyParams {
134 /// Validate the proxy: [`Addr`] field.
135 /// The proxy must be a valid [`Addr`].
136 pub fn validate(&self, api: &dyn Api) -> Result<(), VaultError> {
137 api.addr_validate(self.proxy.as_str())?;
138 Ok(())
139 }
140}
141
142#[cw_serde]
143#[derive(QueryResponses)]
144pub enum VaultQueryMsg {
145 /// QueryMsg Shares: get the shares of a staker.
146 #[returns(SharesResponse)]
147 Shares { staker: String },
148
149 /// QueryMsg Assets: get the assets of a staker, converted from shares.
150 #[returns(AssetsResponse)]
151 Assets { staker: String },
152
153 /// QueryMsg ConvertToAssets: convert shares to assets.
154 #[returns(ConvertToAssetsResponse)]
155 ConvertToAssets { shares: Uint128 },
156
157 /// QueryMsg ConvertToShares: convert assets to shares.
158 #[returns(ConvertToSharesResponse)]
159 ConvertToShares { assets: Uint128 },
160
161 /// QueryMsg TotalShares: get the total shares in circulation.
162 #[returns(TotalSharesResponse)]
163 TotalShares {},
164
165 /// QueryMsg TotalAssets: get the total assets under vault.
166 #[returns(TotalAssetsResponse)]
167 TotalAssets {},
168
169 /// QueryMsg QueuedWithdrawal: get the queued withdrawal and unlock timestamp under vault.
170 #[returns(QueuedWithdrawalResponse)]
171 QueuedWithdrawal { controller: String },
172
173 /// QueryMsg VaultInfo: get the vault information.
174 #[returns(VaultInfoResponse)]
175 VaultInfo {},
176}
177
178/// The response to the `Shares` query.
179/// This is just a wrapper around `Uint128`, so that the schema can be generated.
180#[cw_serde]
181pub struct SharesResponse(Uint128);
182
183/// The response to the `Assets` query.
184/// This is just a wrapper around `Uint128`, so that the schema can be generated.
185#[cw_serde]
186pub struct AssetsResponse(Uint128);
187
188/// The response to the `ConvertToAssets` query.
189/// This is just a wrapper around `Uint128`, so that the schema can be generated.
190#[cw_serde]
191pub struct ConvertToAssetsResponse(Uint128);
192
193/// The response to the `ConvertToShares` query.
194/// This is just a wrapper around `Uint128`, so that the schema can be generated.
195#[cw_serde]
196pub struct ConvertToSharesResponse(Uint128);
197
198/// The response to the `TotalShares` query.
199/// This is just a wrapper around `Uint128`, so that the schema can be generated.
200#[cw_serde]
201pub struct TotalSharesResponse(Uint128);
202
203/// The response to the `TotalAssets` query.
204/// This is just a wrapper around `Uint128`, so that the schema can be generated.
205#[cw_serde]
206pub struct TotalAssetsResponse(Uint128);
207
208/// The response to the `QueuedWithdrawal` query.
209/// This is just a wrapper around `QueuedWithdrawalInfo`, so that the schema can be generated.
210#[cw_serde]
211pub struct QueuedWithdrawalResponse(QueuedWithdrawalInfo);
212
213#[cw_serde]
214pub struct VaultInfoResponse {
215 /// The total shares in circulation
216 pub total_shares: Uint128,
217
218 /// The total assets under management
219 pub total_assets: Uint128,
220
221 /// The `vault-router` contract address
222 pub router: Addr,
223
224 /// The `pauser` contract address
225 pub pauser: Addr,
226
227 /// The `operator` that this vault is delegated to
228 pub operator: Addr,
229
230 /// Asset identifier, using the CAIP-19 format.
231 pub asset_id: String,
232
233 /// The asset type, either `AssetType::Cw20` or `AssetType::Bank`.
234 pub asset_type: AssetType,
235
236 /// The asset reference stores the cw20 contract address or the bank denom.
237 pub asset_reference: String,
238
239 /// The name of the vault contract, see [`cw2::set_contract_version`] for more information.
240 pub contract: String,
241
242 /// The version of the vault contract, see [`cw2::set_contract_version`] for more information.
243 pub version: String,
244}
245
246#[cw_serde]
247pub enum AssetType {
248 Cw20,
249 Bank,
250}