WEP 1: Order Version 3

Author Dmitry Kiselev <[email protected]>
Last update 2019-09-23

1. Abstract

We propose adding functionality for paying order placing fees in assets other than WAVES. The matcher will specify in what assets matcher fees can be accepted. For this purpose, we propose creating several modes for the matcher.

2. Motivation and Purposes

When an order is created on Waves DEX, the user pays the matcher fee for placing the order and finding a suitable counter-order. Subsequently, the matcher pays a network fee when recording an exchange transaction to the blockchain. Currently, the matcher fee is paid in WAVES tokens. However, it’s not always convenient for users because they may not have WAVES in their balance at that moment, among other reasons.

We believe that each matcher should decide which assets it will accept as fees for placing orders. To that purpose, we would like to broaden the functionality for matcher configuration: each matcher will be able to indicate in which assets the matcher fees can be accepted. For users to be able to pay their orders in assets other than WAVES, a new order version (order version 3) will be created, in which the field matcherFeeAsset will be added.

Using the new functionality, we plan to allow paying matcher fees for Waves DEX matcher not only in WAVES, but also in BTC and ETH (other matchers will be able to adjust those parameters). We hope this will make trading more flexible and convenient.

3. Specification

3.1. Blockchain Level

The blockchain will accept all exchange transactions that contain orders with a specified matcher fee asset (sent by Waves’ matcher, a custom matcher or any user). After the broadcast, an exchange transaction will be validated by scripts of all smart accounts and smart assets participating in the transaction. In an utmost case, invocation of 7 scripts is possible: 3 account scripts (matcher, seller, buyer) + 2 asset scripts from the traded pair (amountAsset, priceAsset) + 2 asset scripts of matcher fee assets.

3.2. Matcher Level

For each matcher, a mode can be chosen:

Matcher mode Description Configuration
dynamic The matcher accepts fees in one or several assets, and the minimum fee for placing an order is calculated as follows:

min-fee = rate * (base-fee + 0.004 * n), where

rate is the value of WAVES in the asset used to pay the fee,

base-fee is a base fee in WAVES,

n is the number of scripts invoked in the process of validation, except account scripts of the orders’ senders.

The matcher configuration contains a base-fee in WAVES (currently 0.003).

The API method

GET /matcher/settings/rates

returns a list of rates for assets currently accepted for paying the fee:

{
"WAVES": 1,
 "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS": 0.0005, // BTC
 "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu": 0.015   // ETH
}

Admin API methods (for managing the rate list):

  1. Add or update rate for specified asset
PUT /matcher/settings/rates/{assetId}
  1. Remove asset from the list
DELETE /matcher/settings/rates/{assetId}
fixed The matcher accepts fees in one specific asset, and the minimum order placing fee, min-fee, is fixed. There are no surcharges for script invocation. The matcher configuration contains:
  • asset , an asset accepted for paying the matcher fee
  • min-fee , the minimum fee for placing an order (in this asset).
percent The fee is paid as a percentage of the deal value. There are no surcharges for script invocation. The matcher configuration indicates:
  • min-fee , the minimum fee as a percentage of the deal’s value.
  • asset-type , the asset in the asset pair in which the fee is charged:
    • percent-amount (fee in the amount asset)
    • percent-price (fee in price asset)
    • percent-spending (fee in spent asset; spent asset is the amountAsset in the sell order and priceAsset in the buy order)
    • percent-receiving (fee in received asset; received asset is priceAsset in the sell order and amountAsset in the buy-order)

If a user attempts to place an order with an incorrect amount or fees in the wrong asset, they will receive an error message.

4. Rationale

The suggested improvements facilitate paying order fees in assets other than WAVES and flexible configuration of the matcher, specifying in what assets the matcher fee can be accepted.

The dynamic mode is a generalisation of Waves DEX’s matcher’s current mode. This mode allows the matcher to accept fees in tokens other than WAVES. The fee amount depends on the number of scripts that will be invoked in the validation process: each script invocation for validation increases order fee by 0.004 WAVES (converted into the equivalent in matcherFeeAsset).

In fixed mode, the matcher is paid a flat fee in a specified asset, with no extra charges.

In percent mode, the minimum fee amount is stated as a percentage of the deal value. The percent-spending mode enables guaranteed purchase of at least a certain amount. In that mode, a user won’t have to buy an extra amount or make another purchase to receive a precise amount of an asset. The percent-receiving mode enables selling/buying of the maximum possible amount of an asset. It’s most suitable for users who want to buy assets for the entire amount they have in another asset.

In fixed and percent modes, there are no surcharges for script invocation. If a flat fee is implemented (https://forum.wavesplatform.com/t/proposal-new-fee-calculation-model/13601), the surcharge in dynamic mode will be cancelled, and the formula for calculating the minimum fee will be simplified:

min-fee = rate * base-fee

Also, we will be able to discard fixed mode as it will be fully covered by dynamic mode.

5. Backwards Compatibility

After the introduction of order version 3, smart assets can be set as the matcher fee. Smart asset scripts have to validate all transactions with these assets, so if a smart asset is indicated as matcherFeeAssetId, that asset’s script will be invoked in the validation process.

5.1. Whitelist-like smart assets

As an example, we’ll consider whiteListAsset, an asset that can be traded only by whitelisted addresses:

{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE EXPRESSION #-}
{-# SCRIPT_TYPE ASSET #-}
 
let whiteList = Address(base58'3Mv61qe6egMSjRDZiiuvJDnf3Q1qW9tTZDB')
 
func isWhitelisted(address : Address) = {
    match(getBoolean(whiteList, toBase58String(address.bytes))) {
        case b : Boolean => extract(b)
        case _ => false
    }
}
 
func checkOrder(order : Order) = {
    isWhitelisted(order.sender)
}
 
match tx {
    case tx: ExchangeTransaction =>
        checkOrder(tx.sellOrder) && checkOrder(tx.buyOrder)
    case _ => false
}

If an option for setting this asset as matcherFeeAsset is introduced, non-whitelisted addresses will be able to bypass the restriction on owning this asset.

Let’s assume Alice and Bob are whitelisted and Carol is not. They will be able to send an exchange transaction, in which Carol is the sender (acts as the matcher), matcherFeeAsset = whiteListAsset, and order senders are Alice and Bob. That transaction will be accepted, even if it is validated by matcherFeeAsset’s script as both orders’ senders are whitelisted. As a result, WhiteListAsset will be transferred to Carol’s account, which is not whitelisted and shouldn’t be able to own that asset.

So, the use of smart assets as matcherFee should be kept in mind at the asset script developing stage:

{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE EXPRESSION #-}
{-# SCRIPT_TYPE ASSET #-}
 
let thisAsset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
let whiteList = Address(base58'3Mv61qe6egMSjRDZiiuvJDnf3Q1qW9tTZDB')
 
func isWhitelisted(address : Address) = {
    match(getBoolean(whiteList, toBase58String(address.bytes))) {
        case b : Boolean => extract(b)
        case _ => false
    }
}
 
func checkOrder(order : Order) = {
    let exhcangeTransferIsAllowed = {
        let pair = order.assetPair
        if (pair.amountAsset == thisAsset || pair.priceAsset == thisAsset) then
            isWhitelisted(order.sender)
        else true
    }
     
    let feeTransferIsAllowed =
        if (order.matcherFeeAssetId == thisAsset) then {
            let matcher = addressFromPublicKey(order.matcherPublicKey)
            isWhitelisted(matcher)
        }
        else true
 
    exhcangeTransferIsAllowed && feeTransferIsAllowed
}
 
match tx {
    case tx: ExchangeTransaction =>
        checkOrder(tx.sellOrder) && checkOrder(tx.buyOrder)
    case _ => false
}

We amended the original asset script, adding an extra check:

if (order.matcherFeeAssetId == thisAsset) then {
    isWhitelisted(matcher)
}
else true

5.2. Smart assets restricting trading parameters

Let’s consider a situation in which a smart asset that can only be sold at the price of 1 WAVES is indicated as matcherFeeAsset:

{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE EXPRESSION #-}
{-# SCRIPT_TYPE ASSET #-}
 
match tx {
    case tx: ExchangeTransaction =>
        let pair = tx.sellOrder.assetPair
        (tx.price == 100000000) && (pair.priceAsset == unit)
    case _ => false
}

If the matcher wants to accept fees for placing orders in this asset, only exchange transactions with any asset at a price of 1 WAVES will be valid (as all exchange transactions will be validated by this asset script as well), and all other exchange transactions in which the matcher fee was paid in this asset will be invalid. So, while developing smart assets, one should distinguish the situations when an asset is present in a traded asset pair, and when it is used as the matcher fee asset:

{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE EXPRESSION #-}
{-# SCRIPT_TYPE ASSET #-}
 
let thisAsset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf'
 
match tx {
    case tx: ExchangeTransaction =>
        let pair = tx.sellOrder.assetPair
        if (pair.amountAsset == thisAsset) then
            (tx.price == 100000000) && (pair.priceAsset == unit)
        else true
    case _ => false
}

We amended the original asset script, adding an extra check:

if (pair.amountAsset == thisAsset) then
    (tx.price == 100000000) && (pair.priceAsset == unit)
else true

6. Examples and Implementation

6.1. Configuration file example

# Set of allowed order versions
allowed-order-versions = [1, 2, 3]

# Settings for matcher's fee in order
order-fee {
  mode = "dynamic" # | "fixed" | "percent"
 
  dynamic {
    base-fee = 300000
  }
 
  fixed {
    asset = "WAVES" # | "some issued asset (base58)"
    min-fee = 300000
  }
 
  percent {
    asset-type = "amount" # | "price" | "spending" | "receiving"
    min-fee = 0.1 # in percents
  }
}

6.2. Example of calculating final balances for a deal with different matcher modes

Let’s see what fees the buyer, seller and matcher will pay in a sale of 10,000 WAVES at 0.0006 BTC in different matcher modes.

We’ll use the following scheme for asset transfers:

Main



Mode Config Sell Matcher Fee Buy Matcher Fee Buyer Total Seller Total Matcher Total
dynamic base-fee = 0.003 0.003 WAVES 0.003 WAVES +9999.997 WAVES

-6 BTC

+6 BTC

-10000.003 WAVES

+0.003 WAVES
dynamic base-fee = 0.003 WAVES, rate = 0.015 ETH/WAVES 0.000045 ETH 0.000045 ETH +10000 WAVES -6 BTC -0.000045 ETH +6 BTC -10000 WAVES -0.000045 ETH +0.00009 ETH -0.003 WAVES
dynamic base-fee = 0.003 WAVES, rate = 0.015 ETH/WAVES 0.003 WAVES 0.000045 ETH +10000 WAVES -6 BTC -0.000045 ETH +6 BTC -10000.003 WAVES +0.000045 ETH
fixed min-fee = 0.003 WAVES 0.003 WAVES 0.003 WAVES +9999.997 WAVES -6 BTC +6 BTC -10000.003 WAVES +0.003 WAVES
fixed min-fee = 0.006 BTC 0.006 BTC 0.006 BTC +10000 WAVES -6.006 BTC +5.994 BTC -10000 WAVES +0.012 BTC -0.003 WAVES
fixed min-fee = 0.000045 ETH 0.000045 ETH 0.000045 ETH +10000 WAVES -6 BTC -0.000045 ETH +6 BTC -10000 WAVES -0.000045 ETH +0.00009 ETH -0.003 WAVES
perccent-amount min-fee = 0.1% 10 WAVES 10 WAVES +10000 WAVES -6.006 BTC +5.994 BTC -10000 WAVES +0.012 BTC -0.003 WAVES
percent-price min-fee = 0.1% 0.006 BTC 0.006 BTC +9990 WAVES -6 BTC +6 BTC -10010 WAVES +19.997 WAVES
percent-spending min-fee = 0.1% 10 WAVES 0.006 BTC +10000 WAVES -6.006 BTC +6 BTC -10010 WAVES +9.997 WAVES +0.006 BTC
percent-receiving min-fee = 0.1% 0.006 BTC 10 WAVES +9990 WAVES -6 BTC +5.994 BTC -10000 WAVES +9.997 WAVES +0.006 BTC

In all cases the miner receives Miner Total = ExchangeTx Fee = +0.003 WAVES.

7 Likes

Yes, new WavesDEX users sometimes deposit bitcoin the first time they use it, and they don’t have waves to pay the fees and execute the trade. That’s true

But the very same users should be incentivized to hold waves and pay less fees. I’m not talking about lowering the fees, but to keep it more convenient than any other options, both for traders and matchers.

2 Likes

I agree in terms only if is work as extension of sponsored, if a issue token desire his issued token pay matcher fee, well, then he will pay value of this fee on waves in exchange of respective matcher fee token used, this will avoid some problems.

I believe yet is good way allow nodes, by configuration, if is interest, use node to accept tokens of they own choice like a reward.

1 Like