Current make_order has this interface:
pub fn make_order(
origin: OriginFor<T>,
asset_id_1: u32,
asset_id_2: u32,
offered_amount: BalanceOf<T>,
requested_amount: BalanceOf<T>,
price: BalanceOf<T>,
order_type: OrderType,
expiration_block: BlockNumberFor<T>,
) -> DispatchResultWithPostInfo {
BalanceOf here is u128 - an integer.
A little bit further in this function this check is executed:
match order_type {
OrderType::SELL => {
ensure!(
offered_amount * price == requested_amount,
Error::<T>::PriceDoNotMatchOfferedRequestedAmount
);
}
OrderType::BUY => {
ensure!(
offered_amount == requested_amount * price,
Error::<T>::PriceDoNotMatchOfferedRequestedAmount
);
}
}
We should not do this check because offered_amount and requested_amount can be integers which represent assets with different precisions. We must convert them to a common precision before we can do multiplication or division.
Example:
I create assets A and B, and I want to SELL 5000A for 500B. With current design it is not possible, because:
offered_amount * price == requested_amount,
5000 * price == 500
price would have to be 0.1, but it has an integer type! So this trade is impossible.
The task contains these sub-tasks:
Current
make_orderhas this interface:BalanceOfhere isu128- an integer.A little bit further in this function this check is executed:
We should not do this check because
offered_amountandrequested_amountcan be integers which represent assets with different precisions. We must convert them to a common precision before we can do multiplication or division.Example:
I create assets A and B, and I want to SELL 5000A for 500B. With current design it is not possible, because:
price would have to be
0.1, but it has an integer type! So this trade is impossible.The task contains these sub-tasks:
offered_amountandrequested_amountmake_order- because user providedoffered_amountandrequested_amount.