white_whale_std/pool_network/
trio.rs

1use cosmwasm_schema::{cw_serde, QueryResponses};
2use cosmwasm_std::{Addr, Decimal, StdError, StdResult, Uint128};
3use cw20::Cw20ReceiveMsg;
4
5use crate::fee::Fee;
6
7use crate::pool_network::asset::{Asset, AssetInfo, TrioInfo};
8
9#[cw_serde]
10pub struct InstantiateMsg {
11    /// Asset infos
12    pub asset_infos: [AssetInfo; 3],
13    /// Token contract code id for initialization
14    pub token_code_id: u64,
15    pub asset_decimals: [u8; 3],
16    pub pool_fees: PoolFee,
17    pub fee_collector_addr: String,
18    pub amp_factor: u64,
19    /// If true, the pair will use the token factory to create the LP token. If false, it will
20    /// use a cw20 token instead.
21    pub token_factory_lp: bool,
22}
23
24#[cw_serde]
25pub enum ExecuteMsg {
26    /// Used to trigger the [Cw20HookMsg] messages
27    Receive(Cw20ReceiveMsg),
28    /// Provides liquidity to the pool
29    ProvideLiquidity {
30        assets: [Asset; 3],
31        slippage_tolerance: Option<Decimal>,
32        receiver: Option<String>,
33    },
34    /// Withdraws liquidity from the pool. Used only when the LP is a token factory token.
35    WithdrawLiquidity {},
36    /// Swap an offer asset to the other
37    Swap {
38        offer_asset: Asset,
39        ask_asset: AssetInfo,
40        belief_price: Option<Decimal>,
41        max_spread: Option<Decimal>,
42        to: Option<String>,
43    },
44    /// Updates the trio pool config
45    UpdateConfig {
46        owner: Option<String>,
47        fee_collector_addr: Option<String>,
48        pool_fees: Option<PoolFee>,
49        feature_toggle: Option<FeatureToggle>,
50        amp_factor: Option<RampAmp>,
51    },
52    /// Collects the Protocol fees accrued by the pool
53    CollectProtocolFees {},
54}
55
56#[cw_serde]
57pub struct RampAmp {
58    pub future_a: u64,
59    pub future_block: u64,
60}
61
62#[cw_serde]
63pub enum Cw20HookMsg {
64    /// Sell a given amount of asset
65    Swap {
66        ask_asset: AssetInfo,
67        belief_price: Option<Decimal>,
68        max_spread: Option<Decimal>,
69        to: Option<String>,
70    },
71    /// Withdraws liquidity
72    WithdrawLiquidity {},
73}
74
75#[cw_serde]
76#[derive(QueryResponses)]
77pub enum QueryMsg {
78    /// Retrieves the info for the trio.
79    #[returns(TrioInfo)]
80    Trio {},
81    /// Retrieves the configuration of the pool.
82    #[returns(ConfigResponse)]
83    Config {},
84    /// Retrieves the protocol fees that have been accrued. If `all_time` is `true`, it will return
85    /// the fees collected since the inception of the pool. On the other hand, if `all_time` is set
86    /// to `false`, only the fees that has been accrued by the pool but not collected by the fee
87    /// collector will be returned.
88    #[returns(ProtocolFeesResponse)]
89    ProtocolFees {
90        asset_id: Option<String>,
91        all_time: Option<bool>,
92    },
93    /// Retrieves the fees that have been burned by the pool.
94    #[returns(ProtocolFeesResponse)]
95    BurnedFees { asset_id: Option<String> },
96    /// Retrieves the pool information.
97    #[returns(PoolResponse)]
98    Pool {},
99    /// Simulates a swap.
100    #[returns(SimulationResponse)]
101    Simulation {
102        offer_asset: Asset,
103        ask_asset: Asset,
104    },
105    /// Simulates a reverse swap, i.e. given the ask asset, how much of the offer asset is needed to
106    /// perform the swap.
107    #[returns(ReverseSimulationResponse)]
108    ReverseSimulation {
109        ask_asset: Asset,
110        offer_asset: Asset,
111    },
112}
113
114/// Pool feature toggle
115#[cw_serde]
116pub struct FeatureToggle {
117    pub withdrawals_enabled: bool,
118    pub deposits_enabled: bool,
119    pub swaps_enabled: bool,
120}
121
122/// Fees used by the pools on the pool network
123#[cw_serde]
124pub struct PoolFee {
125    pub protocol_fee: Fee,
126    pub swap_fee: Fee,
127    pub burn_fee: Fee,
128    #[cfg(feature = "osmosis")]
129    pub osmosis_fee: Fee,
130}
131
132impl PoolFee {
133    /// Checks that the given [PoolFee] is valid, i.e. the fees provided are valid, and they don't
134    /// exceed 100% together
135    pub fn is_valid(&self) -> StdResult<()> {
136        self.protocol_fee.is_valid()?;
137        self.swap_fee.is_valid()?;
138        self.burn_fee.is_valid()?;
139
140        let total_fee = self.aggregate()?;
141
142        // Check if the total fee exceeds 100%
143        if total_fee >= Decimal::percent(100) {
144            return Err(StdError::generic_err("Invalid fees"));
145        }
146
147        Ok(())
148    }
149
150    /// aggregates all the fees into a single decimal
151    pub fn aggregate(&self) -> StdResult<Decimal> {
152        let total_fee = {
153            let base_fee = self
154                .protocol_fee
155                .share
156                .checked_add(self.swap_fee.share)?
157                .checked_add(self.burn_fee.share)?;
158
159            #[cfg(feature = "osmosis")]
160            {
161                base_fee.checked_add(self.osmosis_fee.share)?
162            }
163
164            #[cfg(not(feature = "osmosis"))]
165            {
166                base_fee
167            }
168        };
169
170        Ok(total_fee)
171    }
172}
173
174#[cw_serde]
175pub struct Config {
176    pub owner: Addr,
177    pub fee_collector_addr: Addr,
178    pub pool_fees: PoolFee,
179    pub feature_toggle: FeatureToggle,
180    pub initial_amp: u64,
181    pub future_amp: u64,
182    pub initial_amp_block: u64,
183    pub future_amp_block: u64,
184}
185
186pub type ConfigResponse = Config;
187
188/// We define a custom struct for each query response
189#[cw_serde]
190pub struct PoolResponse {
191    pub assets: Vec<Asset>,
192    pub total_share: Uint128,
193}
194
195/// SimulationResponse returns swap simulation response
196#[cw_serde]
197pub struct SimulationResponse {
198    pub return_amount: Uint128,
199    pub spread_amount: Uint128,
200    pub swap_fee_amount: Uint128,
201    pub protocol_fee_amount: Uint128,
202    pub burn_fee_amount: Uint128,
203    #[cfg(feature = "osmosis")]
204    pub osmosis_fee_amount: Uint128,
205}
206
207/// ProtocolFeesResponse returns protocol fees response
208#[cw_serde]
209pub struct ProtocolFeesResponse {
210    pub fees: Vec<Asset>,
211}
212
213/// ReverseSimulationResponse returns reverse swap simulation response
214#[cw_serde]
215pub struct ReverseSimulationResponse {
216    pub offer_amount: Uint128,
217    pub spread_amount: Uint128,
218    pub swap_fee_amount: Uint128,
219    pub protocol_fee_amount: Uint128,
220    pub burn_fee_amount: Uint128,
221    #[cfg(feature = "osmosis")]
222    pub osmosis_fee_amount: Uint128,
223}
224
225/// We currently take no arguments for migrations
226#[cw_serde]
227pub struct MigrateMsg {}