# Loopring’s Uni-directional Order Model

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 pay out`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 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 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 = 10 XYZ/ABC). 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 11 XYZ/ABC.

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 a ETH/USD market in a traditional exchange .

- If a user wants to sell 10 ETH at price 300 USD/ETH. This order can 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 expressed as
`Order(10, ETH, 3000, USD, true)`

. - If a user wants to buy 10 ETH at price 300 USD/ETH, This order can 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 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 Changllanges

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 converted both ways. A user may get confused when he/she provided a price but the system displays a slightly different price after the conversion.