1use anyhow::{ensure, Result};
2use async_trait::async_trait;
3use cnidarium::StateWrite;
4use cnidarium_component::ActionHandler;
56use crate::{
7 component::{PositionManager, StateReadExt},
8 lp::{action::PositionOpen, position},
9};
1011#[async_trait]
12/// Debits the initial reserves and credits an opened position NFT.
13impl ActionHandler for PositionOpen {
14type CheckStatelessContext = ();
15async fn check_stateless(&self, _context: ()) -> Result<()> {
16// Check:
17 // + reserves are at most 80 bits wide,
18 // + the trading function coefficients are at most 80 bits wide.
19 // + at least some assets are provisioned.
20 // + the trading function coefficients are non-zero,
21 // + the trading function doesn't specify a cyclic pair,
22 // + the fee is <=50%.
23self.position.check_stateless()?;
24if self.position.state != position::State::Opened {
25anyhow::bail!("attempted to open a position with a state besides `Opened`");
26 }
27Ok(())
28 }
2930async fn check_and_execute<S: StateWrite>(&self, mut state: S) -> Result<()> {
31// Only open the position if the dex is enabled in the dex params.
32let dex_params = state.get_dex_params().await?;
3334ensure!(
35 dex_params.is_enabled,
36"Dex MUST be enabled to open positions."
37);
3839 state.open_position(self.position.clone()).await?;
40Ok(())
41 }
42}