You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Solidity does not handle float arithmetic and therefore errors are introduced when numbers of different order of magnitude are multiplied divided.
The rounding error check functions prevents trades that would cause the exact traded amounts to be too far off from the original expected amount.
/// @dev Checks if rounding error > 0.1%.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator.
/// @return Rounding error is present.
function isRoundingError(uint numerator, uint denominator, uint target)
public
pure
returns (bool)
{
uint remainder = mulmod(target, numerator, denominator);
if (remainder == 0) return false;
// No rounding error.
uint errPercentageTimes1000000 = (remainder.mul(1000000)).div(numerator.mul(target));
return errPercentageTimes1000000 > 1000;
}
The isRoundingError function checks whether (numerator/denominator) x target returns a value that is close to the result that would be expected in a float multiplication and currently checks whether the error is above 0.1%
trade amount = 1000
Then the rounding error is equal to 0.001 = 0.1%
First, if i am not mistaken, this creates drastic conditions to fill orders, for example the following order will return a rounding error event and will not be accepted
buy amount = 1000
sell amount = 3000
trade amount = 500
Then the rounding error is equal to 0.004 = 0.4%
Secondly, this creates unfillable orders such as in the following case.
Alice puts up a trade with
buy amount = 1000
sell amount = 3000
A trade is sent with
amount = 990
The rounding error is equal to 0.
A trade is sent that fills the remaining order.
amount = 10
The rounding error is equal to 0.1 = 10%.
I think in this case no trade can fill the remaining order.
This doesn't seem like an issue for most tokens with 18 decimals. But it might be worth looking into.
I believe the main issue is that the matching-engine needs to be aware of this and remove unfillable orders appropriately.
The text was updated successfully, but these errors were encountered:
Solidity does not handle float arithmetic and therefore errors are introduced when numbers of different order of magnitude are multiplied divided.
The rounding error check functions prevents trades that would cause the exact traded amounts to be too far off from the original expected amount.
The isRoundingError function checks whether (numerator/denominator) x target returns a value that is close to the result that would be expected in a float multiplication and currently checks whether the error is above 0.1%
In our case:
For example, if
Then the rounding error is equal to 0.001 = 0.1%
First, if i am not mistaken, this creates drastic conditions to fill orders, for example the following order will return a rounding error event and will not be accepted
Then the rounding error is equal to 0.004 = 0.4%
Secondly, this creates unfillable orders such as in the following case.
The rounding error is equal to 0.
The rounding error is equal to 0.1 = 10%.
I think in this case no trade can fill the remaining order.
This doesn't seem like an issue for most tokens with 18 decimals. But it might be worth looking into.
I believe the main issue is that the matching-engine needs to be aware of this and remove unfillable orders appropriately.
The text was updated successfully, but these errors were encountered: