Skip to main content

gmsol_programs/model/
pool.rs

1use crate::gmsol_store::types::Pool;
2
3impl gmsol_model::Balance for Pool {
4    type Num = u128;
5
6    type Signed = i128;
7
8    /// Get the long token amount.
9    fn long_amount(&self) -> gmsol_model::Result<Self::Num> {
10        if self.is_pure() {
11            debug_assert_eq!(
12                self.short_token_amount, 0,
13                "short token amount must be zero"
14            );
15            // For pure pools, we must ensure that the long token amount
16            // plus the short token amount equals the total token amount.
17            // Therefore, we use `div_ceil` for the long token amount
18            // and `div` for the short token amount.
19            Ok(self.long_token_amount.div_ceil(2))
20        } else {
21            Ok(self.long_token_amount)
22        }
23    }
24
25    /// Get the short token amount.
26    fn short_amount(&self) -> gmsol_model::Result<Self::Num> {
27        if self.is_pure() {
28            debug_assert_eq!(
29                self.short_token_amount, 0,
30                "short token amount must be zero"
31            );
32            Ok(self.long_token_amount / 2)
33        } else {
34            Ok(self.short_token_amount)
35        }
36    }
37}
38
39impl gmsol_model::Pool for Pool {
40    fn apply_delta_to_long_amount(&mut self, delta: &Self::Signed) -> gmsol_model::Result<()> {
41        self.long_token_amount = self.long_token_amount.checked_add_signed(*delta).ok_or(
42            gmsol_model::Error::Computation("apply delta to long amount"),
43        )?;
44        Ok(())
45    }
46
47    fn apply_delta_to_short_amount(&mut self, delta: &Self::Signed) -> gmsol_model::Result<()> {
48        let amount = if self.is_pure() {
49            &mut self.long_token_amount
50        } else {
51            &mut self.short_token_amount
52        };
53        *amount = amount
54            .checked_add_signed(*delta)
55            .ok_or(gmsol_model::Error::Computation(
56                "apply delta to short amount",
57            ))?;
58        Ok(())
59    }
60
61    fn checked_apply_delta(
62        &self,
63        delta: gmsol_model::Delta<&Self::Signed>,
64    ) -> gmsol_model::Result<Self> {
65        let mut ans = *self;
66        if let Some(amount) = delta.long() {
67            ans.apply_delta_to_long_amount(amount)?;
68        }
69        if let Some(amount) = delta.short() {
70            ans.apply_delta_to_short_amount(amount)?;
71        }
72        Ok(ans)
73    }
74}