1
use cosmwasm_schema::cw_serde;
2
use cosmwasm_std::{Addr, Coin, Decimal256, StdResult};
3
use injective_cosmwasm::MarketId;
4
use injective_math::FPDecimal;
5

            
6
#[cw_serde]
7
pub enum SwapEstimationAmount {
8
    InputQuantity(FPCoin),
9
    ReceiveQuantity(FPCoin),
10
}
11

            
12
#[cw_serde]
13
pub struct FPCoin {
14
    pub amount: FPDecimal,
15
    pub denom: String,
16
}
17

            
18
impl FPCoin {
19
4
    pub fn to_coin_floor(&self) -> StdResult<Coin> {
20
4
        let amount = Decimal256::try_from(self.amount)?.to_uint_floor();
21
2
        Ok(Coin::new(amount, self.denom.clone()))
22
4
    }
23
}
24

            
25
impl From<Coin> for FPCoin {
26
2
    fn from(value: Coin) -> Self {
27
2
        FPCoin {
28
2
            amount: value.amount.into(),
29
2
            denom: value.denom,
30
2
        }
31
2
    }
32
}
33

            
34
#[cw_serde]
35
pub struct ConfigResponse {
36
    pub config: Config,
37
    pub contract_version: String,
38
}
39

            
40
#[cw_serde]
41
pub enum SwapQuantityMode {
42
    MinOutputQuantity(FPDecimal),
43
    ExactOutputQuantity(FPDecimal),
44
}
45

            
46
#[cw_serde]
47
pub struct StepExecutionEstimate {
48
    pub worst_price: FPDecimal,
49
    pub result_denom: String,
50
    pub result_quantity: FPDecimal,
51
    pub is_buy_order: bool,
52
    pub fee_estimate: Option<FPCoin>,
53
}
54

            
55
#[cw_serde]
56
pub struct CurrentSwapOperation {
57
    // whole swap operation
58
    pub sender_address: Addr,
59
    pub swap_steps: Vec<MarketId>,
60
    pub swap_quantity_mode: SwapQuantityMode,
61
    pub input_funds: Coin,
62
    pub refund: Coin,
63
}
64

            
65
#[cw_serde]
66
pub struct CurrentSwapStep {
67
    // current step
68
    pub step_idx: u16,
69
    pub current_balance: FPCoin,
70
    pub step_target_denom: String,
71
    pub is_buy: bool,
72
    pub minimum_input_spendable_after: FPDecimal,
73
}
74

            
75
#[cw_serde]
76
pub struct SwapResults {
77
    pub market_id: MarketId,
78
    pub quantity: FPDecimal,
79
    pub price: FPDecimal,
80
    pub fee: FPDecimal,
81
}
82

            
83
#[cw_serde]
84
pub struct Config {
85
    // if fee_recipient is contract, fee discount is replayed to a sender (will not stay in the contract)
86
    pub fee_recipient: Addr,
87
    // who can change routes
88
    pub admin: Addr,
89
}
90

            
91
#[cw_serde]
92
pub struct SwapRoute {
93
    pub steps: Vec<MarketId>,
94
    pub source_denom: String,
95
    pub target_denom: String,
96
}
97

            
98
impl SwapRoute {
99
16
    pub fn steps_from(&self, denom: &str) -> Vec<MarketId> {
100
16
        if self.source_denom == denom {
101
12
            self.steps.clone()
102
        } else {
103
4
            let mut mut_steps = self.steps.clone();
104
4
            mut_steps.reverse();
105
4
            mut_steps
106
        }
107
16
    }
108
}
109

            
110
#[cw_serde]
111
pub struct SwapStep {
112
    pub market_id: MarketId,
113
    pub quote_denom: String, // quote for this step of swap, eg for swap eth/inj using eth/usdt and inj/usdt markets, quotes will be eth in 1st step and usdt in 2nd
114
}
115

            
116
#[cw_serde]
117
pub struct SwapEstimationResult {
118
    pub result_quantity: FPDecimal,
119
    pub expected_fees: Vec<FPCoin>,
120
}