astroport/pair.rs
1use crate::observation::OracleObservation;
2use cosmwasm_schema::{cw_serde, QueryResponses};
3
4use crate::asset::{Asset, AssetInfo, PairInfo};
5
6use crate::factory::PairType;
7use cosmwasm_std::{Addr, Binary, Decimal, Decimal256, Empty, StdError, Uint128, Uint64};
8use cw20::Cw20ReceiveMsg;
9
10/// The default swap slippage
11pub const DEFAULT_SLIPPAGE: &str = "0.005";
12/// The maximum allowed swap slippage
13pub const MAX_ALLOWED_SLIPPAGE: &str = "0.5";
14/// The maximum fee share allowed, 10%
15pub const MAX_FEE_SHARE_BPS: u16 = 1000;
16
17/// Decimal precision for TWAP results
18pub const TWAP_PRECISION: u8 = 6;
19
20/// Min safe trading size (0.00001) to calculate a price. This value considers
21/// amount in decimal form with respective token precision.
22pub const MIN_TRADE_SIZE: Decimal256 = Decimal256::raw(10000000000000);
23
24/// This structure describes the parameters used for creating a contract.
25#[cw_serde]
26pub struct InstantiateMsg {
27 /// The pair type
28 pub pair_type: PairType,
29 /// Information about assets in the pool
30 pub asset_infos: Vec<AssetInfo>,
31 /// The token contract code ID used for the tokens in the pool
32 pub token_code_id: u64,
33 /// The factory contract address
34 pub factory_addr: String,
35 /// Optional binary serialised parameters for custom pool types
36 pub init_params: Option<Binary>,
37}
38
39/// This structure describes the execute messages available in the contract.
40#[cw_serde]
41pub enum ExecuteMsgExt<C> {
42 /// Receives a message of type [`Cw20ReceiveMsg`]
43 Receive(Cw20ReceiveMsg),
44 /// ProvideLiquidity allows someone to provide liquidity in the pool
45 ProvideLiquidity {
46 /// The assets available in the pool
47 assets: Vec<Asset>,
48 /// The slippage tolerance that allows liquidity provision only if the price in the pool doesn't move too much
49 slippage_tolerance: Option<Decimal>,
50 /// Determines whether the LP tokens minted for the user is auto_staked in the Incentives contract
51 auto_stake: Option<bool>,
52 /// The receiver of LP tokens
53 receiver: Option<String>,
54 min_lp_to_receive: Option<Uint128>,
55 },
56 /// WithdrawLiquidity allows someone to withdraw liquidity from the pool
57 WithdrawLiquidity {
58 #[serde(default)]
59 assets: Vec<Asset>,
60 min_assets_to_receive: Option<Vec<Asset>>,
61 },
62 /// Swap performs a swap in the pool
63 Swap {
64 offer_asset: Asset,
65 ask_asset_info: Option<AssetInfo>,
66 belief_price: Option<Decimal>,
67 max_spread: Option<Decimal>,
68 to: Option<String>,
69 },
70 /// Update the pair configuration
71 UpdateConfig { params: Binary },
72 /// ProposeNewOwner creates a proposal to change contract ownership.
73 /// The validity period for the proposal is set in the `expires_in` variable.
74 ProposeNewOwner {
75 /// Newly proposed contract owner
76 owner: String,
77 /// The date after which this proposal expires
78 expires_in: u64,
79 },
80 /// DropOwnershipProposal removes the existing offer to change contract ownership.
81 DropOwnershipProposal {},
82 /// Used to claim contract ownership.
83 ClaimOwnership {},
84 /// Custom execute endpoints for extended pool implementations
85 Custom(C),
86}
87
88pub type ExecuteMsg = ExecuteMsgExt<Empty>;
89
90/// This structure describes a CW20 hook message.
91#[cw_serde]
92pub enum Cw20HookMsg {
93 /// Swap a given amount of asset
94 Swap {
95 ask_asset_info: Option<AssetInfo>,
96 belief_price: Option<Decimal>,
97 max_spread: Option<Decimal>,
98 to: Option<String>,
99 },
100}
101
102/// This structure describes the query messages available in the contract.
103#[cw_serde]
104#[derive(QueryResponses)]
105pub enum QueryMsg {
106 /// Returns information about a pair in an object of type [`super::asset::PairInfo`].
107 #[returns(PairInfo)]
108 Pair {},
109 /// Returns information about a pool in an object of type [`PoolResponse`].
110 #[returns(PoolResponse)]
111 Pool {},
112 /// Returns contract configuration settings in a custom [`ConfigResponse`] structure.
113 #[returns(ConfigResponse)]
114 Config {},
115 /// Returns information about the share of the pool in a vector that contains objects of type [`Asset`].
116 #[returns(Vec<Asset>)]
117 Share { amount: Uint128 },
118 /// Returns information about a swap simulation in a [`SimulationResponse`] object.
119 #[returns(SimulationResponse)]
120 Simulation {
121 offer_asset: Asset,
122 ask_asset_info: Option<AssetInfo>,
123 },
124 /// Returns information about cumulative prices in a [`ReverseSimulationResponse`] object.
125 #[returns(ReverseSimulationResponse)]
126 ReverseSimulation {
127 offer_asset_info: Option<AssetInfo>,
128 ask_asset: Asset,
129 },
130 /// Returns information about the cumulative prices in a [`CumulativePricesResponse`] object
131 #[returns(CumulativePricesResponse)]
132 CumulativePrices {},
133 /// Returns current D invariant in as a [`u128`] value
134 #[returns(Uint128)]
135 QueryComputeD {},
136 /// Returns the balance of the specified asset that was in the pool just preceeding the moment of the specified block height creation.
137 #[returns(Option<Uint128>)]
138 AssetBalanceAt {
139 asset_info: AssetInfo,
140 block_height: Uint64,
141 },
142 /// Query price from observations
143 #[returns(OracleObservation)]
144 Observe { seconds_ago: u64 },
145 /// Returns an estimation of assets received for the given amount of LP tokens
146 #[returns(Vec<Asset>)]
147 SimulateWithdraw { lp_amount: Uint128 },
148 /// Returns an estimation of shares received for the given amount of assets
149 #[returns(Uint128)]
150 SimulateProvide {
151 assets: Vec<Asset>,
152 slippage_tolerance: Option<Decimal>,
153 },
154}
155
156/// This struct is used to return a query result with the total amount of LP tokens and assets in a specific pool.
157#[cw_serde]
158pub struct PoolResponse {
159 /// The assets in the pool together with asset amounts
160 pub assets: Vec<Asset>,
161 /// The total amount of LP tokens currently issued
162 pub total_share: Uint128,
163}
164
165/// This struct is used to return a query result with the general contract configuration.
166#[cw_serde]
167pub struct ConfigResponse {
168 /// Last timestamp when the cumulative prices in the pool were updated
169 pub block_time_last: u64,
170 /// The pool's parameters
171 pub params: Option<Binary>,
172 /// The contract owner
173 pub owner: Addr,
174 /// The factory contract address
175 pub factory_addr: Addr,
176 /// Tracker contract address
177 pub tracker_addr: Option<Addr>,
178}
179
180/// Holds the configuration for fee sharing
181#[cw_serde]
182pub struct FeeShareConfig {
183 /// The fee shared with the address
184 pub bps: u16,
185 /// The share is sent to this address on every swap
186 pub recipient: Addr,
187}
188
189/// This structure holds the parameters that are returned from a swap simulation response
190#[cw_serde]
191pub struct SimulationResponse {
192 /// The amount of ask assets returned by the swap
193 pub return_amount: Uint128,
194 /// The spread used in the swap operation
195 pub spread_amount: Uint128,
196 /// The amount of fees charged by the transaction
197 pub commission_amount: Uint128,
198}
199
200/// This structure holds the parameters that are returned from a reverse swap simulation response.
201#[cw_serde]
202pub struct ReverseSimulationResponse {
203 /// The amount of offer assets returned by the reverse swap
204 pub offer_amount: Uint128,
205 /// The spread used in the swap operation
206 pub spread_amount: Uint128,
207 /// The amount of fees charged by the transaction
208 pub commission_amount: Uint128,
209}
210
211/// This structure is used to return a cumulative prices query response.
212#[cw_serde]
213pub struct CumulativePricesResponse {
214 /// The assets in the pool to query
215 pub assets: Vec<Asset>,
216 /// The total amount of LP tokens currently issued
217 pub total_share: Uint128,
218 /// The vector contains cumulative prices for each pair of assets in the pool
219 pub cumulative_prices: Vec<(AssetInfo, AssetInfo, Uint128)>,
220}
221
222/// This structure describes a migration message.
223/// We currently take no arguments for migrations.
224#[cw_serde]
225pub struct MigrateMsg {}
226
227/// This structure holds XYK pool parameters.
228#[cw_serde]
229pub struct XYKPoolParams {
230 /// Whether asset balances are tracked over blocks or not.
231 /// They will not be tracked if the parameter is ignored.
232 /// It can not be disabled later once enabled.
233 pub track_asset_balances: Option<bool>,
234}
235
236/// This structure stores a XYK pool's configuration.
237#[cw_serde]
238pub struct XYKPoolConfig {
239 /// Whether asset balances are tracked over blocks or not.
240 pub track_asset_balances: bool,
241 // The config for swap fee sharing
242 pub fee_share: Option<FeeShareConfig>,
243}
244
245/// This enum stores the option available to enable asset balances tracking over blocks.
246#[cw_serde]
247pub enum XYKPoolUpdateParams {
248 /// Enables the sharing of swap fees with an external party.
249 EnableFeeShare {
250 /// The fee shared with the fee_share_address
251 fee_share_bps: u16,
252 /// The fee_share_bps is sent to this address on every swap
253 fee_share_address: String,
254 },
255 DisableFeeShare,
256}
257
258/// This structure holds stableswap pool parameters.
259#[cw_serde]
260pub struct StablePoolParams {
261 /// The current stableswap pool amplification
262 pub amp: u64,
263 /// The contract owner
264 pub owner: Option<String>,
265}
266
267/// This structure stores a stableswap pool's configuration.
268#[cw_serde]
269pub struct StablePoolConfig {
270 /// The stableswap pool amplification
271 pub amp: Decimal,
272 // The config for swap fee sharing
273 pub fee_share: Option<FeeShareConfig>,
274}
275
276/// This enum stores the options available to start and stop changing a stableswap pool's amplification.
277#[cw_serde]
278pub enum StablePoolUpdateParams {
279 StartChangingAmp {
280 next_amp: u64,
281 next_amp_time: u64,
282 },
283 StopChangingAmp {},
284 /// Enables the sharing of swap fees with an external party.
285 EnableFeeShare {
286 /// The fee shared with the fee_share_address
287 fee_share_bps: u16,
288 /// The fee_share_bps is sent to this address on every swap
289 fee_share_address: String,
290 },
291 DisableFeeShare,
292}
293
294/// A `reply` call code ID used for sub-messages.
295#[cw_serde]
296pub enum ReplyIds {
297 CreateDenom = 1,
298 InstantiateTrackingContract = 2,
299}
300
301impl TryFrom<u64> for ReplyIds {
302 type Error = StdError;
303
304 fn try_from(value: u64) -> Result<Self, Self::Error> {
305 match value {
306 1 => Ok(ReplyIds::CreateDenom),
307 2 => Ok(ReplyIds::InstantiateTrackingContract),
308 _ => Err(StdError::ParseErr {
309 target_type: "ReplyIds".to_string(),
310 msg: "Failed to parse reply".to_string(),
311 }),
312 }
313 }
314}
315
316#[cfg(test)]
317mod tests {
318 use super::*;
319 use cosmwasm_std::{from_json, to_json_binary};
320
321 #[cw_serde]
322 pub struct LegacyConfigResponse {
323 pub block_time_last: u64,
324 pub params: Option<Binary>,
325 pub factory_addr: Addr,
326 pub owner: Addr,
327 }
328
329 #[test]
330 fn test_config_response_compatability() {
331 let ser_msg = to_json_binary(&LegacyConfigResponse {
332 block_time_last: 12,
333 params: Some(
334 to_json_binary(&StablePoolConfig {
335 amp: Decimal::one(),
336 fee_share: None,
337 })
338 .unwrap(),
339 ),
340 factory_addr: Addr::unchecked(""),
341 owner: Addr::unchecked(""),
342 })
343 .unwrap();
344
345 let _: ConfigResponse = from_json(&ser_msg).unwrap();
346 }
347}