Skip to content

Commit

Permalink
DEX-1694 added dynamic fee config
Browse files Browse the repository at this point in the history
  • Loading branch information
Evgeniya Tsybrenko committed Oct 10, 2022
1 parent a96d71d commit eeb64aa
Show file tree
Hide file tree
Showing 27 changed files with 1,135 additions and 295 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,28 @@ class AsyncEnrichedDexApi(apiKey: String, host: => InetSocketAddress)(implicit e
.headers(headers)
}

override def addCustomFeeAssets(assets: Set[Asset], headers: Map[String, String]): AsyncEnrichedDexApi.R[HttpMessage] = mk {
basicRequest
.post(uri"$apiUri/matcher/settings/custom-fee-assets")
.followRedirects(false)
.headers(headers)
.body(Json.stringify(Json.toJson(HttpCustomFeeAssets(assets))))
}

override def addCustomFeeAssets(assets: Set[Asset]): AsyncEnrichedDexApi.R[HttpMessage] =
addCustomFeeAssets(assets, apiKeyHeaders)

override def deleteCustomFeeAssets(assets: Set[Asset], headers: Map[String, String]): AsyncEnrichedDexApi.R[HttpMessage] = mk {
basicRequest
.delete(uri"$apiUri/matcher/settings/custom-fee-assets")
.followRedirects(false)
.headers(headers)
.body(Json.stringify(Json.toJson(HttpCustomFeeAssets(assets))))
}

override def deleteCustomFeeAssets(assets: Set[Asset]): AsyncEnrichedDexApi.R[HttpMessage] =
deleteCustomFeeAssets(assets, apiKeyHeaders)

override def deleteOrderBookWithKey(amountAsset: String, priceAsset: String, headers: Map[String, String]): R[HttpMessage] = mk {
basicRequest
.delete(uri"$apiUri/matcher/orderbook/$amountAsset/$priceAsset")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ trait DexApi[F[_]] {
def cancelAllInOrderBookWithKey(amountAsset: String, priceAsset: String, headers: Map[String, String]): F[HttpMessage]
def cancelAllInOrderBookWithKey(assetPair: AssetPair): F[HttpMessage]

def addCustomFeeAssets(assets: Set[Asset], headers: Map[String, String]): F[HttpMessage]
def addCustomFeeAssets(assets: Set[Asset]): F[HttpMessage]
def deleteCustomFeeAssets(assets: Set[Asset], headers: Map[String, String]): F[HttpMessage]
def deleteCustomFeeAssets(assets: Set[Asset]): F[HttpMessage]

def upsertAssetRate(assetId: String, rate: Double, headers: Map[String, String] = Map.empty): F[HttpMessage]
def upsertAssetRate(asset: Asset, rate: Double): F[HttpMessage]
def upsertAssetRate(asset: Asset, rate: String): F[HttpMessage]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.wavesplatform.it.sync.orders

import com.typesafe.config.{Config, ConfigFactory}
import com.wavesplatform.dex.api.http.entities.HttpCalculatedFeeResponse.CalculatedFee
import com.wavesplatform.dex.api.http.entities.HttpOrderStatus
import com.wavesplatform.dex.api.http.entities.HttpOrderStatus.Status
import com.wavesplatform.dex.domain.asset.Asset
import com.wavesplatform.dex.domain.order.OrderType
import com.wavesplatform.dex.error.FeeNotEnough

Expand Down Expand Up @@ -81,6 +83,67 @@ final class OrderCompositeFeeTestSuite extends OrderFeeBaseTestSuite {
aliceBalance2 - aliceBalance1 shouldBe 5.waves - baseFee / 2
bobBalance2 - bobBalance1 shouldBe -5.waves - baseFee
}

"add custom fee assets, but not use it until offset" in {
dex1.api.addCustomFeeAssets(Set(Asset.Waves, btc, usd))

dex1.api.calculateFee(wavesUsdPair, OrderType.SELL, 10.waves, 25.usd)
.base.value shouldBe CalculatedFee(Asset.Waves, baseFee)

dex1.api.calculateFee(wavesBtcPair, OrderType.SELL, 10.waves, 1.btc)
.base.value shouldBe CalculatedFee(Asset.Waves, 0.2.waves)

dex1.api.place(mkOrder(alice, wavesUsdnPair, OrderType.SELL, 20.waves, 5.usdn, matcherFee = baseFee)) // just for offset to be reached
dex1.api.place(mkOrder(alice, wavesUsdnPair, OrderType.SELL, 20.waves, 6.usdn, matcherFee = baseFee)) // just for offset to be reached

dex1.api.place(mkOrder(alice, wavesBtcPair, OrderType.SELL, 10.waves, 1.btc, matcherFee = 0.04.waves))
dex1.api.place(mkOrder(alice, wavesUsdPair, OrderType.SELL, 10.waves, 1.usd, matcherFee = 0.04.waves))

dex1.api.getOrderHistoryByPKWithSig(alice, activeOnly = Some(true)).foreach { item =>
dex1.api.cancelOneOrderWithKey(item.id, Some(alice.publicKey))
}

dex1.api.calculateFee(wavesBtcPair, OrderType.SELL, 10.waves, 1.btc)
.base.value shouldBe CalculatedFee(Asset.Waves, 400000L)

dex1.api.calculateFee(wavesUsdPair, OrderType.SELL, 10.waves, 1.usd)
.base.value shouldBe CalculatedFee(Asset.Waves, 400000L)

dex1.api.deleteCustomFeeAssets(Set(usd))

dex1.api.place(mkOrder(alice, wavesBtcPair, OrderType.SELL, 10.waves, 1.btc, matcherFee = 0.04.waves))
dex1.api.place(mkOrder(alice, wavesUsdPair, OrderType.SELL, 10.waves, 1.usd, matcherFee = baseFee))

dex1.api.calculateFee(wavesBtcPair, OrderType.SELL, 10.waves, 1.btc)
.base.value shouldBe CalculatedFee(Asset.Waves, 400000L)

dex1.api.calculateFee(wavesUsdPair, OrderType.SELL, 10.waves, 1.usd)
.base.value shouldBe CalculatedFee(Asset.Waves, baseFee)

}

"read all custom assets action from levelDB at start" in {
(1 to 20).foreach { i =>
val order = mkOrder(alice, wavesUsdnPair, OrderType.SELL, 1.waves, (5 + i).usdn, matcherFee = baseFee)
dex1.api.place(order)
dex1.api.cancelOrderById(order)
}

dex1.api.saveSnapshots

dex1.restart()

dex1.api.place(mkOrder(alice, wavesBtcPair, OrderType.SELL, 10.waves, 1.btc, matcherFee = 0.04.waves))
dex1.api.place(mkOrder(alice, wavesUsdPair, OrderType.SELL, 10.waves, 1.usd, matcherFee = baseFee))

dex1.api.calculateFee(wavesBtcPair, OrderType.SELL, 10.waves, 1.btc)
.base.value shouldBe CalculatedFee(Asset.Waves, 400000L)

dex1.api.calculateFee(wavesUsdPair, OrderType.SELL, 10.waves, 1.usd)
.base.value shouldBe CalculatedFee(Asset.Waves, baseFee)

}

}

private def multiplyAmountByDouble(a: Long, d: Double): Long =
Expand All @@ -89,12 +152,12 @@ final class OrderCompositeFeeTestSuite extends OrderFeeBaseTestSuite {
override protected def dexInitialSuiteConfig: Config = ConfigFactory.parseString(
s"""
|waves.dex {
| price-assets = [ "$UsdId", "$BtcId", "WAVES" ]
| price-assets = [ "$UsdId", "$UsdnId", "$BtcId", "WAVES" ]
| allowed-order-versions = [1, 2, 3]
| order-fee.-1 {
| mode = composite
| composite {
| custom {
| custom-pairs {
| "WAVES-$BtcId": {
| mode = percent
| percent {
Expand All @@ -111,17 +174,50 @@ final class OrderCompositeFeeTestSuite extends OrderFeeBaseTestSuite {
| base-taker-fee = $baseFee
| }
| }
| discount {
| asset = "$WctId"
| value = 0.1
| }
| }
| }
| order-fee.11 {
| mode = composite
| composite {
| dynamic-custom-assets = true
| custom-pairs {}
| custom-assets {
| assets = []
| settings {
| mode = "fixed"
| fixed {
| asset = "WAVES"
| min-fee = 400000
| }
| }
| }
| default {
| mode = dynamic
| dynamic {
| base-maker-fee = $baseFee
| base-taker-fee = $baseFee
| }
| }
| discount {
| asset = "$WctId"
| value = 0.1
| }
| }
| }
|}
""".stripMargin
)

override protected def beforeAll(): Unit = {
wavesNode1.start()
broadcastAndAwait(IssueUsdTx, IssueBtcTx)
broadcastAndAwait(IssueUsdTx, IssueBtcTx, IssueUsdnTx, IssueWctTx)
broadcastAndAwait(mkTransfer(bob, alice, 100.btc, btc))
dex1.start()
upsertAssetRate((usdn, 1.0), (wct, 1.0))
}

}
10 changes: 10 additions & 0 deletions dex-pb/src/main/protobuf/dex_order.proto
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ message CancelOrder {
bytes owner = 3;
};

message AddFeeCustomAssets {
repeated bytes asset_id = 1;
};

message DeleteFeeCustomAssets {
repeated bytes asset_id = 1;
};

message ValidatedCommand {
AssetPair asset_pair = 1;
bytes kamon_ctx = 2;
Expand All @@ -76,5 +84,7 @@ message ValidatedCommand {
CancelOrder cancel_order = 5;
google.protobuf.Empty cancel_all_orders = 6;
google.protobuf.Empty delete_order_book = 7;
AddFeeCustomAssets add_fee_custom_assets = 8;
DeleteFeeCustomAssets delete_fee_custom_assets = 9;
}
};
6 changes: 4 additions & 2 deletions dex/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,9 @@ waves.dex {
}

composite {
custom {
dynamic-custom-assets = false # use dynamic assets from kafka and levelDB for custom-assets section

custom-pairs {
DWgwcZTMhSvnyYCoWLRUXXSH1RSkzThXLJhww9gwkqdn-25FEqEjRkqK6yCkiT7Lz6SAYz7gUFCtxfCChnrVFD5AT {
mode = "percent"
percent {
Expand All @@ -296,7 +298,7 @@ waves.dex {
# WAVES or Issued asset ID in base 58
assets = []

# will be applied to all valid pair combinations from the 'assets' field
# will be applied to all valid pair combinations from the 'assets' field or from kafka and levelDB, if dynamic-custom-assets set to true
settings {
mode = "percent"
percent {
Expand Down
Loading

0 comments on commit eeb64aa

Please sign in to comment.