code.vegaprotocol.io/vega@v0.79.0/core/integration/steps/the_following_trades_happened.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package steps
    17  
    18  import (
    19  	"fmt"
    20  	"time"
    21  
    22  	"code.vegaprotocol.io/vega/core/integration/stubs"
    23  	"code.vegaprotocol.io/vega/libs/num"
    24  	"code.vegaprotocol.io/vega/protos/vega"
    25  
    26  	"github.com/cucumber/godog"
    27  )
    28  
    29  func TheFollowingTradesShouldBeExecuted(
    30  	exec Execution,
    31  	broker *stubs.BrokerStub,
    32  	table *godog.Table,
    33  ) error {
    34  	var err error
    35  
    36  	for _, row := range parseExecutedTradesTable(table) {
    37  		buyer := row.MustStr("buyer")
    38  		buyerIn := buyer
    39  		seller := row.MustStr("seller")
    40  		sellerIn := seller
    41  		price := row.MustU64("price")
    42  		size := row.MustU64("size")
    43  		aggressorRaw := row.Str("aggressor side")
    44  		aggressor, aerr := Side(aggressorRaw)
    45  		if aggressorRaw != "" && aerr != nil {
    46  			return aerr
    47  		}
    48  		// remap buyer/seller to AMM IDs
    49  		if row.HasColumn("is amm") && row.MustBool("is amm") {
    50  			if id, ok := exec.GetAMMSubAccountID(buyer); ok {
    51  				buyer = id
    52  			}
    53  			if id, ok := exec.GetAMMSubAccountID(seller); ok {
    54  				seller = id
    55  			}
    56  		}
    57  
    58  		buyerFee, hasBuyerFee := row.U64B("buyer fee")
    59  		buyerInfraFee, hasBuyerInfraFee := row.U64B("buyer infrastructure fee")
    60  		buyerMakerFee, hasBuyerMakerFee := row.U64B("buyer maker fee")
    61  		buyerLiqFee, hasBuyerLiqFee := row.U64B("buyer liquidity fee")
    62  		buyerInfraFeeVolumeDiscount, hasBuyerInfraFeeVolumeDiscount := row.DecimalB("buyer infrastructure fee volume discount")
    63  		buyerMakerFeeVolumeDiscount, hasBuyerMakerFeeVolumeDiscount := row.DecimalB("buyer maker fee volume discount")
    64  		buyerLiqFeeVolumeDiscount, hasBuyerLiqFeeVolumeDiscount := row.DecimalB("buyer liquidity fee volume discount")
    65  		buyerInfraFeeReferrerDiscount, hasBuyerInfraFeeReferrerDiscount := row.DecimalB("buyer infrastructure fee referrer discount")
    66  		buyerMakerFeeReferrerDiscount, hasBuyerMakerFeeReferrerDiscount := row.DecimalB("buyer maker fee referrer discount")
    67  		buyerLiqFeeReferrerDiscount, hasBuyerLiqFeeReferrerDiscount := row.DecimalB("buyer liquidity fee referrer discount")
    68  		buyerBuyBackFee, hasBuyerBuyBackFee := row.DecimalB("buyer buyback fee")
    69  		buyerTreasuryFee, hasBuyerTreasuryFee := row.DecimalB("buyer treasury fee")
    70  		buyerHighVolumeMakerFee, hasBuyerHighVolumeMakerFee := row.DecimalB("buyer high volume maker fee")
    71  
    72  		sellerFee, hasSellerFee := row.U64B("seller fee")
    73  		sellerInfraFee, hasSellerInfraFee := row.U64B("seller infrastructure fee")
    74  		sellerMakerFee, hasSellerMakerFee := row.U64B("seller maker fee")
    75  		sellerLiqFee, hasSellerLiqFee := row.U64B("seller liquidity fee")
    76  		sellerInfraFeeVolumeDiscount, hasSellerInfraFeeVolumeDiscount := row.DecimalB("seller infrastructure fee volume discount")
    77  		sellerMakerFeeVolumeDiscount, hasSellerMakerFeeVolumeDiscount := row.DecimalB("seller maker fee volume discount")
    78  		sellerLiqFeeVolumeDiscount, hasSellerLiqFeeVolumeDiscount := row.DecimalB("seller liquidity fee volume discount")
    79  		sellerInfraFeeReferrerDiscount, hasSellerInfraFeeReferrerDiscount := row.DecimalB("seller infrastructure fee referrer discount")
    80  		sellerMakerFeeReferrerDiscount, hasSellerMakerFeeReferrerDiscount := row.DecimalB("seller maker fee referrer discount")
    81  		sellerLiqFeeReferrerDiscount, hasSellerLiqFeeReferrerDiscount := row.DecimalB("seller liquidity fee referrer discount")
    82  		sellerBuyBackFee, hasSellerBuyBackFee := row.DecimalB("seller buyback fee")
    83  		sellerTreasuryFee, hasSellerTreasuryFee := row.DecimalB("seller treasury fee")
    84  		sellerHighVolumeMakerFee, hasSellerHighVolumeMakerFee := row.DecimalB("seller high volume maker fee")
    85  
    86  		data := broker.GetTrades()
    87  		var found bool
    88  		for _, v := range data {
    89  			if v.Buyer == buyer &&
    90  				v.Seller == seller &&
    91  				stringToU64(v.Price) == price &&
    92  				v.Size == size &&
    93  				(aggressorRaw == "" || aggressor == v.GetAggressor()) &&
    94  				(!hasBuyerFee || buyerFee == feeToU64(v.BuyerFee)) &&
    95  				(!hasBuyerInfraFee || buyerInfraFee == stringToU64(v.BuyerFee.InfrastructureFee)) &&
    96  				(!hasBuyerMakerFee || buyerMakerFee == stringToU64(v.BuyerFee.MakerFee)) &&
    97  				(!hasBuyerLiqFee || buyerLiqFee == stringToU64(v.BuyerFee.LiquidityFee)) &&
    98  				(!hasBuyerInfraFeeVolumeDiscount || buyerInfraFeeVolumeDiscount.Equal(num.MustDecimalFromString(v.BuyerFee.InfrastructureFeeVolumeDiscount))) &&
    99  				(!hasBuyerMakerFeeVolumeDiscount || buyerMakerFeeVolumeDiscount.Equal(num.MustDecimalFromString(v.BuyerFee.MakerFeeVolumeDiscount))) &&
   100  				(!hasBuyerLiqFeeVolumeDiscount || buyerLiqFeeVolumeDiscount.Equal(num.MustDecimalFromString(v.BuyerFee.LiquidityFeeVolumeDiscount))) &&
   101  				(!hasBuyerInfraFeeReferrerDiscount || buyerInfraFeeReferrerDiscount.Equal(num.MustDecimalFromString(v.BuyerFee.InfrastructureFeeReferrerDiscount))) &&
   102  				(!hasBuyerMakerFeeReferrerDiscount || buyerMakerFeeReferrerDiscount.Equal(num.MustDecimalFromString(v.BuyerFee.MakerFeeReferrerDiscount))) &&
   103  				(!hasBuyerLiqFeeReferrerDiscount || buyerLiqFeeReferrerDiscount.Equal(num.MustDecimalFromString(v.BuyerFee.LiquidityFeeReferrerDiscount))) &&
   104  				(!hasBuyerTreasuryFee || buyerTreasuryFee.Equal(num.MustDecimalFromString(v.BuyerFee.TreasuryFee))) &&
   105  				(!hasBuyerBuyBackFee || buyerBuyBackFee.Equal(num.MustDecimalFromString(v.BuyerFee.BuyBackFee))) &&
   106  				(!hasBuyerHighVolumeMakerFee || buyerHighVolumeMakerFee.Equal(num.MustDecimalFromString(v.BuyerFee.HighVolumeMakerFee))) &&
   107  				(!hasSellerFee || sellerFee == feeToU64(v.SellerFee)) &&
   108  				(!hasSellerInfraFee || sellerInfraFee == stringToU64(v.SellerFee.InfrastructureFee)) &&
   109  				(!hasSellerMakerFee || sellerMakerFee == stringToU64(v.SellerFee.MakerFee)) &&
   110  				(!hasSellerLiqFee || sellerLiqFee == stringToU64(v.SellerFee.LiquidityFee)) &&
   111  				(!hasSellerInfraFeeVolumeDiscount || sellerInfraFeeVolumeDiscount.Equal(num.MustDecimalFromString(v.SellerFee.InfrastructureFeeVolumeDiscount))) &&
   112  				(!hasSellerMakerFeeVolumeDiscount || sellerMakerFeeVolumeDiscount.Equal(num.MustDecimalFromString(v.SellerFee.MakerFeeVolumeDiscount))) &&
   113  				(!hasSellerLiqFeeVolumeDiscount || sellerLiqFeeVolumeDiscount.Equal(num.MustDecimalFromString(v.SellerFee.LiquidityFeeVolumeDiscount))) &&
   114  				(!hasSellerInfraFeeReferrerDiscount || sellerInfraFeeReferrerDiscount.Equal(num.MustDecimalFromString(v.SellerFee.InfrastructureFeeReferrerDiscount))) &&
   115  				(!hasSellerMakerFeeReferrerDiscount || sellerMakerFeeReferrerDiscount.Equal(num.MustDecimalFromString(v.SellerFee.MakerFeeReferrerDiscount))) &&
   116  				(!hasSellerLiqFeeReferrerDiscount || sellerLiqFeeReferrerDiscount.Equal(num.MustDecimalFromString(v.SellerFee.LiquidityFeeReferrerDiscount))) &&
   117  				(!hasSellerTreasuryFee || sellerTreasuryFee.Equal(num.MustDecimalFromString(v.SellerFee.TreasuryFee))) &&
   118  				(!hasSellerBuyBackFee || sellerBuyBackFee.Equal(num.MustDecimalFromString(v.SellerFee.BuyBackFee))) &&
   119  				(!hasSellerHighVolumeMakerFee || sellerHighVolumeMakerFee.Equal(num.MustDecimalFromString(v.SellerFee.HighVolumeMakerFee))) {
   120  				found = true
   121  			}
   122  		}
   123  		if !found {
   124  			return errMissingTrade(buyerIn, sellerIn, price, size)
   125  		}
   126  	}
   127  	return err
   128  }
   129  
   130  func feeToU64(fee *vega.Fee) uint64 {
   131  	if fee == nil {
   132  		return uint64(0)
   133  	}
   134  	return stringToU64(fee.InfrastructureFee) + stringToU64(fee.LiquidityFee) + stringToU64(fee.MakerFee) + stringToU64(fee.BuyBackFee) + stringToU64(fee.TreasuryFee)
   135  }
   136  
   137  func parseExecutedTradesTable(table *godog.Table) []RowWrapper {
   138  	return StrictParseTable(table, []string{
   139  		"buyer",
   140  		"seller",
   141  		"price",
   142  		"size",
   143  	}, []string{
   144  		"aggressor side",
   145  
   146  		"buyer fee",
   147  		"buyer infrastructure fee",
   148  		"buyer liquidity fee",
   149  		"buyer maker fee",
   150  		"buyer infrastructure fee volume discount",
   151  		"buyer liquidity fee volume discount",
   152  		"buyer maker fee volume discount",
   153  		"buyer infrastructure fee referrer discount",
   154  		"buyer liquidity fee referrer discount",
   155  		"buyer maker fee referrer discount",
   156  		"buyer treasury fee",
   157  		"buyer buyback fee",
   158  		"buyer high volume maker fee",
   159  
   160  		"seller fee",
   161  		"seller infrastructure fee",
   162  		"seller liquidity fee",
   163  		"seller maker fee",
   164  		"seller infrastructure fee volume discount",
   165  		"seller liquidity fee volume discount",
   166  		"seller maker fee volume discount",
   167  		"seller infrastructure fee referrer discount",
   168  		"seller liquidity fee referrer discount",
   169  		"seller maker fee referrer discount",
   170  		"seller treasury fee",
   171  		"seller buyback fee",
   172  		"seller high volume maker fee",
   173  		"is amm",
   174  	})
   175  }
   176  
   177  // TheAuctionTradedVolumeAndPriceShouldBe pass in time at which the trades should happen in case there are previous trades in the broker stub.
   178  func TheAuctionTradedVolumeAndPriceShouldBe(broker *stubs.BrokerStub, volume, price string, now time.Time) error {
   179  	v, err := U64(volume)
   180  	if err != nil {
   181  		return err
   182  	}
   183  	p, err := U64(price)
   184  	if err != nil {
   185  		return err
   186  	}
   187  	// get all trades from stub
   188  	trades := broker.GetTrades()
   189  	sawV := uint64(0)
   190  	for _, t := range trades {
   191  		// no trades after the given time
   192  		if t.Timestamp > now.UnixNano() {
   193  			continue
   194  		}
   195  		if stringToU64(t.Price) != p {
   196  			return fmt.Errorf(
   197  				"expected trades to happen at price %d, instead saw a trade of size %d at price %s (%#v)",
   198  				p, t.Size, t.Price, t,
   199  			)
   200  		}
   201  		sawV += t.Size
   202  	}
   203  	if sawV != v {
   204  		return fmt.Errorf(
   205  			"expected a total traded volume of %d, instead saw a traded volume of %d len(%d): (%#v)",
   206  			v, sawV, len(trades), trades,
   207  		)
   208  	}
   209  	return nil
   210  }
   211  
   212  func errMissingTrade(buyer string, seller string, price uint64, volume uint64) error {
   213  	return fmt.Errorf(
   214  		"expecting trade was missing: buyer(%v), seller(%v), price(%v), volume(%v)",
   215  		buyer, seller, price, volume,
   216  	)
   217  }