use crate::observation::OracleObservation;
use cosmwasm_schema::{cw_serde, QueryResponses};
use crate::asset::{Asset, AssetInfo, PairInfo};
use crate::factory::PairType;
use cosmwasm_std::{Addr, Binary, Decimal, Decimal256, Empty, StdError, Uint128, Uint64};
use cw20::Cw20ReceiveMsg;
pub const DEFAULT_SLIPPAGE: &str = "0.005";
pub const MAX_ALLOWED_SLIPPAGE: &str = "0.5";
pub const MAX_FEE_SHARE_BPS: u16 = 1000;
pub const TWAP_PRECISION: u8 = 6;
pub const MIN_TRADE_SIZE: Decimal256 = Decimal256::raw(10000000000000);
#[cw_serde]
pub struct InstantiateMsg {
pub pair_type: PairType,
pub asset_infos: Vec<AssetInfo>,
pub token_code_id: u64,
pub factory_addr: String,
pub init_params: Option<Binary>,
}
#[cw_serde]
pub enum ExecuteMsgExt<C> {
Receive(Cw20ReceiveMsg),
ProvideLiquidity {
assets: Vec<Asset>,
slippage_tolerance: Option<Decimal>,
auto_stake: Option<bool>,
receiver: Option<String>,
min_lp_to_receive: Option<Uint128>,
},
WithdrawLiquidity {
#[serde(default)]
assets: Vec<Asset>,
min_assets_to_receive: Option<Vec<Asset>>,
},
Swap {
offer_asset: Asset,
ask_asset_info: Option<AssetInfo>,
belief_price: Option<Decimal>,
max_spread: Option<Decimal>,
to: Option<String>,
},
UpdateConfig { params: Binary },
ProposeNewOwner {
owner: String,
expires_in: u64,
},
DropOwnershipProposal {},
ClaimOwnership {},
Custom(C),
}
pub type ExecuteMsg = ExecuteMsgExt<Empty>;
#[cw_serde]
pub enum Cw20HookMsg {
Swap {
ask_asset_info: Option<AssetInfo>,
belief_price: Option<Decimal>,
max_spread: Option<Decimal>,
to: Option<String>,
},
}
#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
#[returns(PairInfo)]
Pair {},
#[returns(PoolResponse)]
Pool {},
#[returns(ConfigResponse)]
Config {},
#[returns(Vec<Asset>)]
Share { amount: Uint128 },
#[returns(SimulationResponse)]
Simulation {
offer_asset: Asset,
ask_asset_info: Option<AssetInfo>,
},
#[returns(ReverseSimulationResponse)]
ReverseSimulation {
offer_asset_info: Option<AssetInfo>,
ask_asset: Asset,
},
#[returns(CumulativePricesResponse)]
CumulativePrices {},
#[returns(Uint128)]
QueryComputeD {},
#[returns(Option<Uint128>)]
AssetBalanceAt {
asset_info: AssetInfo,
block_height: Uint64,
},
#[returns(OracleObservation)]
Observe { seconds_ago: u64 },
#[returns(Vec<Asset>)]
SimulateWithdraw { lp_amount: Uint128 },
#[returns(Uint128)]
SimulateProvide {
assets: Vec<Asset>,
slippage_tolerance: Option<Decimal>,
},
}
#[cw_serde]
pub struct PoolResponse {
pub assets: Vec<Asset>,
pub total_share: Uint128,
}
#[cw_serde]
pub struct ConfigResponse {
pub block_time_last: u64,
pub params: Option<Binary>,
pub owner: Addr,
pub factory_addr: Addr,
pub tracker_addr: Option<Addr>,
}
#[cw_serde]
pub struct FeeShareConfig {
pub bps: u16,
pub recipient: Addr,
}
#[cw_serde]
pub struct SimulationResponse {
pub return_amount: Uint128,
pub spread_amount: Uint128,
pub commission_amount: Uint128,
}
#[cw_serde]
pub struct ReverseSimulationResponse {
pub offer_amount: Uint128,
pub spread_amount: Uint128,
pub commission_amount: Uint128,
}
#[cw_serde]
pub struct CumulativePricesResponse {
pub assets: Vec<Asset>,
pub total_share: Uint128,
pub cumulative_prices: Vec<(AssetInfo, AssetInfo, Uint128)>,
}
#[cw_serde]
pub struct MigrateMsg {}
#[cw_serde]
pub struct XYKPoolParams {
pub track_asset_balances: Option<bool>,
}
#[cw_serde]
pub struct XYKPoolConfig {
pub track_asset_balances: bool,
pub fee_share: Option<FeeShareConfig>,
}
#[cw_serde]
pub enum XYKPoolUpdateParams {
EnableFeeShare {
fee_share_bps: u16,
fee_share_address: String,
},
DisableFeeShare,
}
#[cw_serde]
pub struct StablePoolParams {
pub amp: u64,
pub owner: Option<String>,
}
#[cw_serde]
pub struct StablePoolConfig {
pub amp: Decimal,
pub fee_share: Option<FeeShareConfig>,
}
#[cw_serde]
pub enum StablePoolUpdateParams {
StartChangingAmp {
next_amp: u64,
next_amp_time: u64,
},
StopChangingAmp {},
EnableFeeShare {
fee_share_bps: u16,
fee_share_address: String,
},
DisableFeeShare,
}
#[cw_serde]
pub enum ReplyIds {
CreateDenom = 1,
InstantiateTrackingContract = 2,
}
impl TryFrom<u64> for ReplyIds {
type Error = StdError;
fn try_from(value: u64) -> Result<Self, Self::Error> {
match value {
1 => Ok(ReplyIds::CreateDenom),
2 => Ok(ReplyIds::InstantiateTrackingContract),
_ => Err(StdError::ParseErr {
target_type: "ReplyIds".to_string(),
msg: "Failed to parse reply".to_string(),
}),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use cosmwasm_std::{from_json, to_json_binary};
#[cw_serde]
pub struct LegacyConfigResponse {
pub block_time_last: u64,
pub params: Option<Binary>,
pub factory_addr: Addr,
pub owner: Addr,
}
#[test]
fn test_config_response_compatability() {
let ser_msg = to_json_binary(&LegacyConfigResponse {
block_time_last: 12,
params: Some(
to_json_binary(&StablePoolConfig {
amp: Decimal::one(),
fee_share: None,
})
.unwrap(),
),
factory_addr: Addr::unchecked(""),
owner: Addr::unchecked(""),
})
.unwrap();
let _: ConfigResponse = from_json(&ser_msg).unwrap();
}
}