Loopring Protocol introduced an innovative way of modeling orders, which I called the ** Unidirectional Order Model,** or UDOM for short. As you can notice in our whitepaper, UDOM makes it easier to express order-rings in a clean and concise way. UDOM is not new though, as in 2014 when I founded Coinport Cryptocurrency Exchange, this model was coded into our match-engine which is open-sourced ever since. It might have been discussed, in other terms, by other researchers and engineers as well.

UDOM expresses orders as token-exchange requests, instead of buys(bids) and sells(asks). An order in a simplified version of UDOM can be denoted as a tuple of 5 elements:

`Order(amountS, tokenS, amountB, tokenB, buyNoMoreThanTokenB)`

where:

`amountS`

: is the amount of`tokenS`

to pay out (sell) to the counterpart`tokenS`

: represents the type of token/asset to payout`amountB`

: is the amount of`tokenB`

to get (buy) from the counterpart`tokenB`

: represents the type of token/asset to get (buy)`buyNoMoreThanTokenB`

: determine the stop criteria for a complete-fill, which will be explained later.

So where is the price? Well, UDOM doesn’t include a price (which must be a floating-point number by nature), instead, it uses a term `rate`

which is expressed as `amountS/amountB`

. The rate is not a floating-point number but an expression, it will only be evaluated with other unsigned integer numbers on demand, to keep all intermediate results as unsigned integers. This will make the calculation accurate.

### About “buyNoMoreThanTokenB”

UDOM’s `buyNoMoreThanTokenB`

parameter determines when an order is considered as completely filled. Take `Order(12, ABC, 120, XYZ)`

(without the `buyNoMoreThanTokenB`

parameter) as an example, this order expresses selling 12 token ABC for 120 token XYZ (rate = 0.1 ABC/XYZ). If there is a very large order that would like to pay 12 XYZ per ABC bought, these two orders can match each other. The problem is how much to match.

If we ignore fees, Loopring uses the middle rate as the fill rate — in this case, the fill rate would be 0.90909 ABC/XYZ.

In case `buyNoMoreThanTokenB == true`

, the actual fill amounts for the order would be:

*120/11=10.91 ABC sold**120 XYZ received*

In case `buyNoMoreThanTokenB == false`

, the actual fill amounts for the order would be:

*ABC sold : 12**12 x 11 = 132 XYZ received*

As you can notice: `buyNoMoreThanTokenB`

applies a cap on either `amountS`

or `amountB`

.

## Examples

Assuming there is an ETH/USD market in a traditional exchange.

- If a user wants to sell 10 ETH at price 300 USD/ETH. This order can be expressed as
`Order(10, ETH, 3000, USD, false)`

. - If a user wants to sell ETH at price 300 USD/ETH to get 3000 USD. This order can be expressed as
`Order(10, ETH, 3000, USD, true)`

. - If a user wants to buy 10 ETH at price 300 USD/ETH, This order can be expressed as
`Order(3000, USD, 10, ETH, true)`

. - If a user wants to spend 3000 USD to buy as many ETH as possible at price 300 USD/ETH, This order can be expressed as
`Order(3000, USD, 10, ETH, false)`

.

Traditional buy-sell modeling can express the 1st and the 3rd order, but not the other two.

## UDOM’s Challenges

UDOM orders need to be translated into buy-sell orders back and forth so UI can display orders in an intuitive way for end-users.

Price and rate also need to convert both ways. A user may get confused when he/she provided a price but the system displays a slightly different price after the conversion.