mantra-dex-std 2.2.0

Types used by the MANTRA-dex contracts suite
Documentation
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
use std::fmt;

use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Addr, Coin, Decimal, Deps, StdError, StdResult, Uint128};
use cw_ownable::{cw_ownable_execute, cw_ownable_query};

use crate::coin::is_factory_token;
use crate::fee::PoolFee;

/// The type of swap operation to perform.
#[cw_serde]
pub enum SwapOperation {
    /// A swap operation that uses the MantraSwap router.
    MantraSwap {
        /// The token denom to swap in.
        token_in_denom: String,
        /// The token denom returning from the swap.
        token_out_denom: String,
        /// The identifier of the pool to use for the swap.
        pool_identifier: String,
    },
}

impl SwapOperation {
    /// Retrieves the `token_in_denom` used for this swap operation.
    pub fn get_input_asset_info(&self) -> &String {
        match self {
            SwapOperation::MantraSwap { token_in_denom, .. } => token_in_denom,
        }
    }

    pub fn get_target_asset_info(&self) -> String {
        match self {
            SwapOperation::MantraSwap {
                token_out_denom, ..
            } => token_out_denom.clone(),
        }
    }

    pub fn get_pool_identifer(&self) -> String {
        match self {
            SwapOperation::MantraSwap {
                pool_identifier, ..
            } => pool_identifier.clone(),
        }
    }
}

impl fmt::Display for SwapOperation {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            SwapOperation::MantraSwap {
                token_in_denom,
                token_out_denom,
                pool_identifier,
            } => write!(
                f,
                "MantraSwap {{ token_in_info: {token_in_denom}, token_out_info: {token_out_denom}, pool_identifier: {pool_identifier} }}"
            ),
        }
    }
}

/// Contains the pool information
#[cw_serde]
pub struct PoolInfo {
    /// The identifier for the pool.
    pub pool_identifier: String,
    /// The asset denoms for the pool.
    pub asset_denoms: Vec<String>,
    /// The LP denom of the pool.
    pub lp_denom: String,
    /// The decimals for the given asset denoms, provided in the same order as asset_denoms.
    pub asset_decimals: Vec<u8>,
    /// The total amount of assets in the pool.
    pub assets: Vec<Coin>,
    /// The type of pool to create.
    pub pool_type: PoolType,
    /// The fees for the pool.
    pub pool_fees: PoolFee,
    /// The status of the pool
    pub status: PoolStatus,
}

/// Possible pool types, it can be either a constant product (xyk) pool or a stable swap pool.
#[cw_serde]
pub enum PoolType {
    /// A stable swap pool.
    StableSwap {
        /// The amount of amplification to perform on the constant product part of the swap formula.
        amp: u64,
    },
    /// xyk pool
    ConstantProduct,
}

impl PoolType {
    /// Gets a string representation of the pair type
    pub fn get_label(&self) -> &str {
        match self {
            PoolType::ConstantProduct => "ConstantProduct",
            PoolType::StableSwap { .. } => "StableSwap",
        }
    }
}

/// The pool status tells what actions are enabled for this pool.
#[cw_serde]
pub struct PoolStatus {
    /// Whether swaps are enabled
    pub swaps_enabled: bool,
    /// Whether deposits are enabled
    pub deposits_enabled: bool,
    /// Whether withdrawals are enabled
    pub withdrawals_enabled: bool,
}

impl Default for PoolStatus {
    fn default() -> Self {
        PoolStatus {
            swaps_enabled: true,
            deposits_enabled: true,
            withdrawals_enabled: true,
        }
    }
}

/// The contract configuration.
#[cw_serde]
pub struct Config {
    /// The address where the collected fees go to.
    pub fee_collector_addr: Addr,
    /// The address of the farm manager contract.
    pub farm_manager_addr: Addr,
    /// How much it costs to create a pool. It helps prevent spamming of new pools.
    pub pool_creation_fee: Coin,
}

#[cw_serde]
pub struct InstantiateMsg {
    /// The address where the collected fees go to.
    pub fee_collector_addr: String,
    /// The address of the farm manager contract.
    pub farm_manager_addr: String,
    /// How much it costs to create a pool. It helps prevent spamming of new pools.
    pub pool_creation_fee: Coin,
}

#[cw_serde]
pub struct MigrateMsg {}

#[cw_ownable_execute]
#[cw_serde]
pub enum ExecuteMsg {
    /// Creates a new pool.
    CreatePool {
        /// The asset denoms for the pool.
        asset_denoms: Vec<String>,
        /// The decimals for the given asset denoms, provided in the same order as `asset_denoms`.
        asset_decimals: Vec<u8>,
        /// The fees for the pool.
        pool_fees: PoolFee,
        /// The type of pool to create.
        pool_type: PoolType,
        /// The identifier for the pool.
        pool_identifier: Option<String>,
    },
    /// Provides liquidity to the pool
    ProvideLiquidity {
        /// A percentage value representing the acceptable slippage for the operation.
        /// When provided, if the slippage exceeds this value, the liquidity provision will not be
        /// executed.
        slippage_tolerance: Option<Decimal>,
        /// The maximum allowable spread between the bid and ask prices for the pool.
        /// When provided, if the spread exceeds this value, the liquidity provision will not be
        /// executed.
        max_spread: Option<Decimal>,
        /// The receiver of the LP
        receiver: Option<String>,
        /// The identifier for the pool to provide liquidity for.
        pool_identifier: String,
        /// The amount of time in seconds to unlock tokens if taking part on the farms. If not passed,
        /// the tokens will not be locked and the LP tokens will be returned to the user.
        unlocking_duration: Option<u64>,
        /// The identifier of the position to lock the LP tokens in the farm manager, if any.
        lock_position_identifier: Option<String>,
    },
    /// Swap an offer asset to the other
    Swap {
        /// The return asset of the swap.
        ask_asset_denom: String,
        /// The belief price of the swap.
        belief_price: Option<Decimal>,
        /// The maximum spread to incur when performing the swap. If the spread exceeds this value,
        /// the swap will not be executed. Max 50%.
        max_spread: Option<Decimal>,
        /// The recipient of the output tokens. If not provided, the tokens will be sent to the sender
        /// of the message.
        receiver: Option<String>,
        /// The identifier for the pool to swap in.
        pool_identifier: String,
    },
    /// Withdraws liquidity from the pool.
    WithdrawLiquidity { pool_identifier: String },
    /// Execute multiple [`SwapOperation`]s to allow for multi-hop swaps.
    ExecuteSwapOperations {
        /// The operations that should be performed in sequence.
        ///
        /// The amount in each swap will be the output from the previous swap.
        ///
        /// The first swap will use whatever funds are sent in the MessageInfo.
        operations: Vec<SwapOperation>,
        /// The minimum amount of the output (i.e., final swap operation token) required for the message to succeed.
        minimum_receive: Option<Uint128>,
        /// The (optional) recipient of the output tokens.
        ///
        /// If left unspecified, tokens will be sent to the sender of the message.
        receiver: Option<String>,
        /// The maximum spread to incur when performing the swap. If the spread exceeds this value,
        /// the swap will not be executed. Max 50%.
        max_spread: Option<Decimal>,
    },
    /// Updates the configuration of the contract.
    /// If a field is not specified (i.e., set to `None`), it will not be modified.
    UpdateConfig {
        /// The new fee collector contract address.
        fee_collector_addr: Option<String>,
        /// The new farm manager contract address.
        farm_manager_addr: Option<String>,
        /// The new fee that must be paid when a pool is created.
        pool_creation_fee: Option<Coin>,
        /// Toggles features for a given pool, allowing fine-tuned
        /// control over which operations are allowed, i.e. swap, deposits, withdrawals
        feature_toggle: Option<FeatureToggle>,
    },
}

#[cw_ownable_query]
#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
    /// Retrieves the contract's config.
    #[returns(ConfigResponse)]
    Config {},
    /// Retrieves the decimals for the given asset.
    #[returns(AssetDecimalsResponse)]
    AssetDecimals {
        /// The pool identifier to do the query for.
        pool_identifier: String,
        /// The queried denom in the given pool_identifier.
        denom: String,
    },
    /// Simulates a swap.
    #[returns(SimulationResponse)]
    Simulation {
        /// The offer asset to swap.
        offer_asset: Coin,
        /// The ask asset denom to get.
        ask_asset_denom: String,
        /// The pool identifier to swap in.
        pool_identifier: String,
    },
    /// Simulates a reverse swap, i.e. given the ask asset, how much of the offer asset is needed
    /// to perform the swap.
    #[returns(ReverseSimulationResponse)]
    ReverseSimulation {
        /// The ask asset to get after the swap.
        ask_asset: Coin,
        /// The offer asset denom to input.
        offer_asset_denom: String,
        /// The pool identifier to swap in.
        pool_identifier: String,
    },
    /// Simulates swap operations.
    #[returns(SimulateSwapOperationsResponse)]
    SimulateSwapOperations {
        /// The amount to swap.
        offer_amount: Uint128,
        /// The operations to perform.
        operations: Vec<SwapOperation>,
    },
    /// Simulates a reverse swap operations, i.e. given the ask asset, how much of the offer asset
    /// is needed to perform the swap.
    #[returns(ReverseSimulateSwapOperationsResponse)]
    ReverseSimulateSwapOperations {
        /// The amount to get after the swap.
        ask_amount: Uint128,
        /// The operations to perform.
        operations: Vec<SwapOperation>,
    },
    /// Retrieves the pool information for the given pool identifier.
    #[returns(PoolsResponse)]
    Pools {
        /// An optional parameter specifying the pool identifier to do the query for. If not
        /// provided, it will return all pools based on the pagination parameters.
        pool_identifier: Option<String>,
        /// An optional parameter specifying what pool (identifier) to start searching after.
        start_after: Option<String>,
        /// The amount of pools to return. If unspecified, will default to a value specified by
        /// the contract.
        limit: Option<u32>,
    },
}

/// The response for the `Config` query.
#[cw_serde]
pub struct ConfigResponse {
    /// The contract configuration.
    pub config: Config,
}

/// The response for the `Pools` query.
#[cw_serde]
pub struct PoolsResponse {
    /// The pools information responses.
    pub pools: Vec<PoolInfoResponse>,
}

#[cw_serde]
pub struct PoolInfoResponse {
    /// The pool information for the given pool identifier.
    pub pool_info: PoolInfo,
    /// The total LP tokens in the pool.
    pub total_share: Coin,
}

/// The response for the `AssetDecimals` query.
#[cw_serde]
pub struct AssetDecimalsResponse {
    /// The pool identifier to do the query for.
    pub pool_identifier: String,
    /// The queried denom in the given pool_identifier.
    pub denom: String,
    /// The decimals for the requested denom.
    pub decimals: u8,
}

/// SimulationResponse returns swap simulation response
#[cw_serde]
pub struct SimulationResponse {
    /// The return amount of the ask asset given the offer amount.
    pub return_amount: Uint128,
    /// The spread amount of the swap.
    pub spread_amount: Uint128,
    /// The swap fee amount of the swap.
    pub swap_fee_amount: Uint128,
    /// The protocol fee amount of the swap.
    pub protocol_fee_amount: Uint128,
    /// The burn fee amount of the swap.
    pub burn_fee_amount: Uint128,
    /// The extra fees amount of the swap.
    pub extra_fees_amount: Uint128,
}

/// ReverseSimulationResponse returns reverse swap simulation response
#[cw_serde]
pub struct ReverseSimulationResponse {
    /// The amount of the offer asset needed to get the ask amount.
    pub offer_amount: Uint128,
    /// The spread amount of the swap.
    pub spread_amount: Uint128,
    /// The swap fee amount of the swap.
    pub swap_fee_amount: Uint128,
    /// The protocol fee amount of the swap.
    pub protocol_fee_amount: Uint128,
    /// The burn fee amount of the swap.
    pub burn_fee_amount: Uint128,
    /// The extra fees amount of the swap.
    pub extra_fees_amount: Uint128,
}

/// Pool feature toggle, can control whether swaps, deposits, and withdrawals are enabled.
#[cw_serde]
pub struct FeatureToggle {
    /// The identifier of the pool to toggle the status of.
    pub pool_identifier: String,
    /// Whether or not swaps are enabled
    pub withdrawals_enabled: Option<bool>,
    /// Whether or not deposits are enabled
    pub deposits_enabled: Option<bool>,
    /// Whether or not swaps are enabled
    pub swaps_enabled: Option<bool>,
}

/// The response for the `SimulateSwapOperations` query.
#[cw_serde]
pub struct SimulateSwapOperationsResponse {
    /// The return amount of the ask asset after the swap operations.
    pub return_amount: Uint128,
    /// The spreads of the swap.
    pub spreads: Vec<Coin>,
    /// The swap fees of the swap.
    pub swap_fees: Vec<Coin>,
    /// The protocol fees of the swap.
    pub protocol_fees: Vec<Coin>,
    /// The burn fees of the swap.
    pub burn_fees: Vec<Coin>,
    /// The extra fees of the swap.
    pub extra_fees: Vec<Coin>,
}

/// The response for the `ReverseSimulateSwapOperations` query.
#[cw_serde]
pub struct ReverseSimulateSwapOperationsResponse {
    /// The amount of the initial token needed to get the final token after the swap operations.
    pub offer_amount: Uint128,
    /// The spreads of the swap.
    pub spreads: Vec<Coin>,
    /// The swap fees of the swap.
    pub swap_fees: Vec<Coin>,
    /// The protocol fees of the swap.
    pub protocol_fees: Vec<Coin>,
    /// The burn fees of the swap.
    pub burn_fees: Vec<Coin>,
    /// The extra fees of the swap.
    pub extra_fees: Vec<Coin>,
}

/// Gets the total supply of the given liquidity asset
pub fn get_total_share(deps: &Deps, liquidity_asset: String) -> StdResult<Uint128> {
    if is_factory_token(liquidity_asset.as_str()) {
        //bank query total
        return Ok(deps.querier.query_supply(&liquidity_asset)?.amount);
    }

    Err(StdError::generic_err("Invalid LP token"))
}