1
use crate::{
2
    admin::{delete_route, save_config, set_route, update_config, withdraw_support_funds},
3
    error::ContractError,
4
    msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg},
5
    queries::{estimate_swap_result, SwapQuantity},
6
    state::{get_all_swap_routes, get_config, read_swap_route},
7
    swap::{handle_atomic_order_reply, start_swap_flow},
8
    types::{ConfigResponse, SwapQuantityMode},
9
};
10

            
11
#[cfg(not(feature = "library"))]
12
use cosmwasm_std::entry_point;
13
use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError};
14
use cw2::{get_contract_version, set_contract_version};
15
use injective_cosmwasm::{InjectiveMsgWrapper, InjectiveQueryWrapper};
16

            
17
pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
18
pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
19

            
20
const CODE_67_LEGACY_CONTRACT_NAME: &str = "crates.io:atomic-order-example";
21
const CODE_67_LEGACY_CONTRACT_VERSION: &str = "0.1.0";
22
const CODE_1962_CONTRACT_NAME: &str = "swap-contract";
23
const CODE_1962_CONTRACT_VERSION: &str = "1.1.2";
24

            
25
pub const ATOMIC_ORDER_REPLY_ID: u64 = 1u64;
26
pub const DEPOSIT_REPLY_ID: u64 = 2u64;
27

            
28
#[cfg_attr(not(feature = "library"), entry_point)]
29
16
pub fn instantiate(
30
16
    deps: DepsMut<InjectiveQueryWrapper>,
31
16
    env: Env,
32
16
    info: MessageInfo,
33
16
    msg: InstantiateMsg,
34
16
) -> Result<Response<InjectiveMsgWrapper>, ContractError> {
35
16
    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
36
16
    save_config(deps, env, msg.admin, msg.fee_recipient)?;
37

            
38
16
    Ok(Response::new().add_attribute("method", "instantiate").add_attribute("owner", info.sender))
39
16
}
40

            
41
#[cfg_attr(not(feature = "library"), entry_point)]
42
4
pub fn execute(
43
4
    deps: DepsMut<InjectiveQueryWrapper>,
44
4
    env: Env,
45
4
    info: MessageInfo,
46
4
    msg: ExecuteMsg,
47
4
) -> Result<Response<InjectiveMsgWrapper>, ContractError> {
48
4
    match msg {
49
        ExecuteMsg::SwapMinOutput {
50
            target_denom,
51
            min_output_quantity,
52
        } => start_swap_flow(deps, env, info, target_denom, SwapQuantityMode::MinOutputQuantity(min_output_quantity)),
53
        ExecuteMsg::SwapExactOutput {
54
            target_denom,
55
            target_output_quantity,
56
        } => start_swap_flow(
57
            deps,
58
            env,
59
            info,
60
            target_denom,
61
            SwapQuantityMode::ExactOutputQuantity(target_output_quantity),
62
        ),
63
        // Admin functions:
64
        ExecuteMsg::SetRoute {
65
            source_denom,
66
            target_denom,
67
            route,
68
        } => set_route(deps, &info.sender, source_denom, target_denom, route),
69
        ExecuteMsg::DeleteRoute { source_denom, target_denom } => delete_route(deps, &info.sender, source_denom, target_denom),
70
4
        ExecuteMsg::UpdateConfig { admin, fee_recipient } => update_config(deps, env, info.sender, admin, fee_recipient),
71
        ExecuteMsg::WithdrawSupportFunds { coins, target_address } => withdraw_support_funds(deps, info.sender, coins, target_address),
72
    }
73
4
}
74

            
75
#[cfg_attr(not(feature = "library"), entry_point)]
76
pub fn reply(deps: DepsMut<InjectiveQueryWrapper>, env: Env, msg: Reply) -> Result<Response<InjectiveMsgWrapper>, ContractError> {
77
    match msg.id {
78
        ATOMIC_ORDER_REPLY_ID => handle_atomic_order_reply(deps, env, msg),
79
        _ => Err(ContractError::UnrecognizedReply(msg.id)),
80
    }
81
}
82

            
83
#[cfg_attr(not(feature = "library"), entry_point)]
84
pub fn query(deps: Deps<InjectiveQueryWrapper>, env: Env, msg: QueryMsg) -> Result<Binary, StdError> {
85
    match msg {
86
        QueryMsg::GetRoute { source_denom, target_denom } => to_json_binary(&read_swap_route(deps.storage, &source_denom, &target_denom)?),
87
        QueryMsg::GetOutputQuantity {
88
            from_quantity,
89
            source_denom,
90
            target_denom,
91
        } => to_json_binary(&estimate_swap_result(
92
            deps,
93
            &env,
94
            source_denom,
95
            target_denom,
96
            SwapQuantity::InputQuantity(from_quantity),
97
        )?),
98

            
99
        QueryMsg::GetInputQuantity {
100
            to_quantity,
101
            source_denom,
102
            target_denom,
103
        } => to_json_binary(&estimate_swap_result(
104
            deps,
105
            &env,
106
            source_denom,
107
            target_denom,
108
            SwapQuantity::OutputQuantity(to_quantity),
109
        )?),
110

            
111
        QueryMsg::GetAllRoutes { start_after, limit } => to_json_binary(&get_all_swap_routes(deps.storage, start_after, limit)?),
112

            
113
        QueryMsg::GetConfig {} => {
114
            let config = get_config(deps.storage)?;
115
            let config_response = ConfigResponse {
116
                config,
117
                contract_version: get_contract_version(deps.storage)?.version,
118
            };
119
            Ok(to_json_binary(&config_response)?)
120
        }
121
    }
122
}
123

            
124
#[cfg_attr(not(feature = "library"), entry_point)]
125
6
pub fn migrate(deps: DepsMut<InjectiveQueryWrapper>, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
126
6
    let previous_contract_version = get_contract_version(deps.storage)?;
127

            
128
6
    let migration_source = match (previous_contract_version.contract.as_str(), previous_contract_version.version.as_str()) {
129
6
        (CODE_67_LEGACY_CONTRACT_NAME, CODE_67_LEGACY_CONTRACT_VERSION) => "code_67",
130
4
        (CODE_1962_CONTRACT_NAME, CODE_1962_CONTRACT_VERSION) => "code_1962",
131
2
        _ => return Err(ContractError::MigrationError {}),
132
    };
133

            
134
4
    get_config(deps.storage)?;
135
4
    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
136

            
137
4
    Ok(Response::new()
138
4
        .add_attribute("migration_source", migration_source)
139
4
        .add_attribute("previous_contract_name", previous_contract_version.contract)
140
4
        .add_attribute("previous_contract_version", previous_contract_version.version)
141
4
        .add_attribute("new_contract_name", CONTRACT_NAME)
142
4
        .add_attribute("new_contract_version", CONTRACT_VERSION))
143
6
}