|
16 | 16 | use common::{ |
17 | 17 | chain::{output_value::OutputValue, OrderId}, |
18 | 18 | primitives::Amount, |
| 19 | + Uint256, |
19 | 20 | }; |
20 | 21 | use utils::ensure; |
21 | 22 |
|
@@ -59,34 +60,35 @@ pub fn calculate_fill_order( |
59 | 60 | } |
60 | 61 |
|
61 | 62 | fn calculate_filled_amount_impl(ask: Amount, give: Amount, fill: Amount) -> Option<Amount> { |
62 | | - (give * fill.into_atoms()).and_then(|v| v / ask.into_atoms()) |
| 63 | + let give = Uint256::from_u128(give.into_atoms()); |
| 64 | + let fill = Uint256::from_u128(fill.into_atoms()); |
| 65 | + let ask = Uint256::from_u128(ask.into_atoms()); |
| 66 | + |
| 67 | + let result = ((give * fill).expect("cannot overflow") / ask)?; |
| 68 | + let result: u128 = result.try_into().ok()?; |
| 69 | + |
| 70 | + Some(Amount::from_atoms(result)) |
63 | 71 | } |
64 | 72 |
|
65 | 73 | fn ensure_currencies_and_amounts_match( |
66 | 74 | order_id: OrderId, |
67 | | - left: &OutputValue, |
68 | | - right: &OutputValue, |
| 75 | + ask: &OutputValue, |
| 76 | + fill: &OutputValue, |
69 | 77 | ) -> Result<()> { |
70 | | - match (left, right) { |
71 | | - (OutputValue::Coin(amount1), OutputValue::Coin(amount2)) => { |
72 | | - ensure!( |
73 | | - amount1 >= amount2, |
74 | | - Error::OrderOverbid(order_id, *amount1, *amount2) |
75 | | - ); |
| 78 | + match (ask, fill) { |
| 79 | + (OutputValue::Coin(ask), OutputValue::Coin(fill)) => { |
| 80 | + ensure!(ask >= fill, Error::OrderOverbid(order_id, *ask, *fill)); |
76 | 81 | Ok(()) |
77 | 82 | } |
78 | | - (OutputValue::TokenV1(id1, amount1), OutputValue::TokenV1(id2, amount2)) => { |
79 | | - ensure!( |
80 | | - amount1 >= amount2, |
81 | | - Error::OrderOverbid(order_id, *amount1, *amount2) |
82 | | - ); |
| 83 | + (OutputValue::TokenV1(id1, ask), OutputValue::TokenV1(id2, fill)) => { |
| 84 | + ensure!(ask >= fill, Error::OrderOverbid(order_id, *ask, *fill)); |
83 | 85 | ensure!(id1 == id2, Error::CurrencyMismatch); |
84 | 86 | Ok(()) |
85 | 87 | } |
86 | 88 | (OutputValue::Coin(_), OutputValue::TokenV1(_, _)) |
87 | 89 | | (OutputValue::TokenV1(_, _), OutputValue::Coin(_)) => Err(Error::CurrencyMismatch), |
88 | 90 | (OutputValue::TokenV0(_), _) | (_, OutputValue::TokenV0(_)) => { |
89 | | - unreachable!() |
| 91 | + Err(Error::UnsupportedTokenVersion) |
90 | 92 | } |
91 | 93 | } |
92 | 94 | } |
@@ -133,7 +135,7 @@ mod tests { |
133 | 135 | #[case(0, 0, 0, None)] |
134 | 136 | #[case(0, 1, 1, None)] |
135 | 137 | #[case(0, u128::MAX, 1, None)] |
136 | | - #[case(3, u128::MAX, 2, None)] |
| 138 | + #[case(2, u128::MAX, 2, Some(u128::MAX))] |
137 | 139 | #[case(1, 0, 0, Some(0))] |
138 | 140 | #[case(1, 0, 1, Some(0))] |
139 | 141 | #[case(1, 1, 1, Some(1))] |
@@ -191,6 +193,7 @@ mod tests { |
191 | 193 | #[case(coin!(3), coin!(100), coin!(2), 66)] |
192 | 194 | #[case(coin!(3), coin!(100), coin!(3), 100)] |
193 | 195 | #[case(coin!(1), token!(u128::MAX), coin!(1), u128::MAX)] |
| 196 | + #[case(coin!(2), token!(u128::MAX), coin!(2), u128::MAX)] |
194 | 197 | fn fill_order_valid_values( |
195 | 198 | #[case] ask: OutputValue, |
196 | 199 | #[case] give: OutputValue, |
@@ -219,7 +222,6 @@ mod tests { |
219 | 222 | #[case(token!(0), coin!(1), token!(1), Error::OrderOverbid(OrderId::zero(), Amount::from_atoms(0), Amount::from_atoms(1)))] |
220 | 223 | #[case(coin!(1), token!(1), coin!(2), Error::OrderOverbid(OrderId::zero(), Amount::from_atoms(1), Amount::from_atoms(2)))] |
221 | 224 | #[case(coin!(1), token!(u128::MAX), coin!(2), Error::OrderOverbid(OrderId::zero(), Amount::from_atoms(1), Amount::from_atoms(2)))] |
222 | | - #[case(coin!(2), token!(u128::MAX), coin!(2), Error::OrderOverflow(OrderId::zero()))] |
223 | 225 | #[case(coin!(1), token!(1), token!(1), Error::CurrencyMismatch)] |
224 | 226 | #[case(coin!(1), token!(1), token!(1), Error::CurrencyMismatch)] |
225 | 227 | #[case(token!(1), token2!(1), token2!(1), Error::CurrencyMismatch)] |
|
0 commit comments