Skip to main content

andromeda_ecosystem/
vault.rs

1use andromeda_std::amp::recipient::Recipient;
2use andromeda_std::amp::AndrAddr;
3use andromeda_std::{ado_base::withdraw::Withdrawal, error::ContractError};
4use andromeda_std::{andr_exec, andr_instantiate, andr_query};
5use cosmwasm_schema::{cw_serde, QueryResponses};
6use cosmwasm_std::{
7    to_json_binary, wasm_execute, Binary, Coin, CosmosMsg, ReplyOn, Storage, SubMsg, Uint128,
8};
9use cw_storage_plus::Map;
10
11use std::fmt;
12
13/// Mapping between (Address, Funds Denom) and the amount
14pub const BALANCES: Map<(&str, &str), Uint128> = Map::new("balances");
15pub const STRATEGY_CONTRACT_ADDRESSES: Map<String, String> =
16    Map::new("strategy_contract_addresses");
17
18#[cw_serde]
19pub enum StrategyType {
20    Anchor,
21    // NoStrategy, //Can be used if we wish to add a default strategy
22}
23
24#[cw_serde]
25#[serde(rename_all = "snake_case")]
26pub struct YieldStrategy {
27    pub strategy_type: StrategyType,
28    pub address: AndrAddr,
29}
30
31impl StrategyType {
32    pub fn deposit(
33        &self,
34        storage: &dyn Storage,
35        funds: Coin,
36        recipient: Recipient,
37    ) -> Result<SubMsg, ContractError> {
38        let address = STRATEGY_CONTRACT_ADDRESSES.load(storage, self.to_string());
39        match address {
40            Err(_) => Err(ContractError::NotImplemented {
41                msg: Some(String::from("This strategy is not supported by this vault")),
42            }),
43            Ok(addr) => {
44                let msg = wasm_execute(
45                    addr,
46                    &ExecuteMsg::Deposit {
47                        recipient: Some(recipient.address),
48                        msg: recipient.msg,
49                    },
50                    vec![funds],
51                )?;
52                let sub_msg = SubMsg {
53                    id: 1,
54                    msg: CosmosMsg::Wasm(msg),
55                    gas_limit: None,
56                    reply_on: ReplyOn::Error,
57                };
58
59                Ok(sub_msg)
60            }
61        }
62    }
63}
64
65impl fmt::Display for StrategyType {
66    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67        match self {
68            StrategyType::Anchor => write!(f, "anchor"),
69        }
70    }
71}
72
73#[cw_serde]
74#[derive(Default)]
75pub struct DepositMsg {
76    pub strategy: Option<StrategyType>,
77    pub amount: Option<Coin>,
78    pub deposit_msg: Option<Binary>,
79}
80
81impl DepositMsg {
82    pub fn to_json_binary(&self) -> Result<Binary, ContractError> {
83        Ok(to_json_binary(self)?)
84    }
85
86    pub fn with_amount(&mut self, amount: Coin) -> &mut Self {
87        self.amount = Some(amount);
88        self
89    }
90
91    pub fn with_strategy(&mut self, strategy: StrategyType) -> &mut Self {
92        self.strategy = Some(strategy);
93        self
94    }
95}
96
97#[andr_instantiate]
98#[cw_serde]
99pub struct InstantiateMsg {}
100
101#[andr_exec]
102#[cw_serde]
103pub enum ExecuteMsg {
104    WithdrawVault {
105        recipient: Option<Recipient>,
106        withdrawals: Vec<Withdrawal>,
107        strategy: Option<StrategyType>,
108    },
109    UpdateStrategy {
110        strategy: StrategyType,
111        address: AndrAddr,
112    },
113    // Originally was an Andromeda Msg
114    Withdraw {
115        recipient: Option<Recipient>,
116        tokens_to_withdraw: Option<Vec<Withdrawal>>,
117    },
118    // Originally was an Andromeda Msg
119    Deposit {
120        recipient: Option<::andromeda_std::amp::AndrAddr>,
121        msg: Option<::cosmwasm_std::Binary>,
122    },
123}
124
125#[andr_query]
126#[cw_serde]
127#[derive(QueryResponses)]
128pub enum QueryMsg {
129    #[returns(cosmwasm_std::Binary)]
130    VaultBalance {
131        address: AndrAddr,
132        strategy: Option<StrategyType>,
133        denom: Option<String>,
134    },
135    #[returns(cosmwasm_std::Binary)]
136    StrategyAddress { strategy: StrategyType },
137}
138
139#[cw_serde]
140pub struct StrategyAddressResponse {
141    pub strategy: StrategyType,
142    pub address: String,
143}