Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wire InGivenOut APIs to /custom-direct-quote #607

Draft
wants to merge 17 commits into
base: v28.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions domain/candidate_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,15 @@ var (

// CandidateRouteSearcher is the interface for finding candidate routes.
type CandidateRouteSearcher interface {
// FindCandidateRoutes finds candidate routes for a given tokenIn and tokenOutDenom
// FindCandidateRoutesOutGivenIn finds candidate routes for a given tokenIn and tokenOutDenom
// using the given options.
// Returns the candidate routes and an error if any.
FindCandidateRoutes(tokenIn sdk.Coin, tokenOutDenom string, options CandidateRouteSearchOptions) (ingesttypes.CandidateRoutes, error)
FindCandidateRoutesOutGivenIn(tokenIn sdk.Coin, tokenOutDenom string, options CandidateRouteSearchOptions) (ingesttypes.CandidateRoutes, error)

// FindCandidateRoutesOutGivenIn finds candidate routes for a given tokenOut and tokenInDenom
// using the given options.
// Returns the candidate routes and an error if any.
FindCandidateRoutesInGivenOut(tokenOut sdk.Coin, tokenInDenom string, options CandidateRouteSearchOptions) (ingesttypes.CandidateRoutes, error)
}

// CandidateRouteDenomData represents the data for a candidate route for a given denom.
Expand Down
9 changes: 7 additions & 2 deletions domain/mocks/candidate_route_finder_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ type CandidateRouteFinderMock struct {

var _ domain.CandidateRouteSearcher = CandidateRouteFinderMock{}

// FindCandidateRoutes implements domain.CandidateRouteSearcher.
func (c CandidateRouteFinderMock) FindCandidateRoutes(tokenIn types.Coin, tokenOutDenom string, options domain.CandidateRouteSearchOptions) (ingesttypes.CandidateRoutes, error) {
// FindCandidateRoutesOutGivenIn implements domain.CandidateRouteSearcher.
func (c CandidateRouteFinderMock) FindCandidateRoutesOutGivenIn(tokenIn types.Coin, tokenOutDenom string, options domain.CandidateRouteSearchOptions) (ingesttypes.CandidateRoutes, error) {
return c.Routes, c.Error
}

// FindCandidateRoutesInGivenOut implements domain.CandidateRouteSearcher.
func (c CandidateRouteFinderMock) FindCandidateRoutesInGivenOut(tokenOut types.Coin, tokenInDenom string, options domain.CandidateRouteSearchOptions) (ingesttypes.CandidateRoutes, error) {
return c.Routes, c.Error
}
4 changes: 2 additions & 2 deletions domain/mocks/quote_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

type MockQuote struct {
GetAmountInFunc func() types.Coin
GetAmountOutFunc func() math.Int
GetAmountOutFunc func() types.Coin
GetRouteFunc func() []domain.SplitRoute
}

Expand All @@ -25,7 +25,7 @@ func (m *MockQuote) GetAmountIn() types.Coin {
}

// GetAmountOut implements domain.Quote.
func (m *MockQuote) GetAmountOut() math.Int {
func (m *MockQuote) GetAmountOut() types.Coin {
if m.GetAmountOutFunc != nil {
return m.GetAmountOutFunc()
}
Expand Down
2 changes: 1 addition & 1 deletion domain/mocks/quote_simulator_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type QuoteSimulatorMock struct {
}

// SimulateQuote implements domain.QuoteSimulator.
func (q *QuoteSimulatorMock) SimulateQuote(ctx context.Context, quote domain.Quote, slippageToleranceMultiplier math.LegacyDec, simulatorAddress string) domain.TxFeeInfo {
func (q *QuoteSimulatorMock) SimulateQuoteOutGivenIn(ctx context.Context, quote domain.Quote, slippageToleranceMultiplier math.LegacyDec, simulatorAddress string) domain.TxFeeInfo {
if q.SimulateQuoteFn != nil {
return q.SimulateQuoteFn(ctx, quote, slippageToleranceMultiplier, simulatorAddress)
}
Expand Down
40 changes: 29 additions & 11 deletions domain/mocks/route_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import (
)

type RouteMock struct {
CalculateTokenOutByTokenInFunc func(ctx context.Context, tokenIn types.Coin) (types.Coin, error)
ContainsGeneralizedCosmWasmPoolFunc func() bool
GetPoolsFunc func() []domain.RoutablePool
GetTokenOutDenomFunc func() string
GetTokenInDenomFunc func() string
PrepareResultPoolsFunc func(ctx context.Context, tokenIn types.Coin, logger log.Logger) ([]domain.RoutablePool, math.LegacyDec, math.LegacyDec, error)
StringFunc func() string
CalculateTokenOutByTokenInFunc func(ctx context.Context, tokenIn types.Coin) (types.Coin, error)
CalculateTokenInByTokenOutFunc func(ctx context.Context, tokenOut types.Coin) (types.Coin, error)
ContainsGeneralizedCosmWasmPoolFunc func() bool
GetPoolsFunc func() []domain.RoutablePool
GetTokenOutDenomFunc func() string
GetTokenInDenomFunc func() string
PrepareResultPoolsExactAmountInFunc func(ctx context.Context, tokenIn types.Coin, logger log.Logger) ([]domain.RoutablePool, math.LegacyDec, math.LegacyDec, error)
PrepareResultPoolsExactAmountOutFunc func(ctx context.Context, tokenOut types.Coin, logger log.Logger) ([]domain.RoutablePool, math.LegacyDec, math.LegacyDec, error)
StringFunc func() string

GetAmountInFunc func() math.Int
GetAmountOutFunc func() math.Int
Expand All @@ -31,6 +33,15 @@ func (r *RouteMock) CalculateTokenOutByTokenIn(ctx context.Context, tokenIn type
panic("unimplemented")
}

// CalculateTokenOutByTokenIn implements domain.Route.
func (r *RouteMock) CalculateTokenInByTokenOut(ctx context.Context, tokenOut types.Coin) (types.Coin, error) {
if r.CalculateTokenInByTokenOutFunc != nil {
return r.CalculateTokenInByTokenOutFunc(ctx, tokenOut)
}

panic("unimplemented")
}

// ContainsGeneralizedCosmWasmPool implements domain.Route.
func (r *RouteMock) ContainsGeneralizedCosmWasmPool() bool {
if r.ContainsGeneralizedCosmWasmPoolFunc != nil {
Expand Down Expand Up @@ -67,10 +78,17 @@ func (r *RouteMock) GetTokenInDenom() string {
panic("unimplemented")
}

// PrepareResultPools implements domain.Route.
func (r *RouteMock) PrepareResultPools(ctx context.Context, tokenIn types.Coin, logger log.Logger) ([]domain.RoutablePool, math.LegacyDec, math.LegacyDec, error) {
if r.PrepareResultPoolsFunc != nil {
return r.PrepareResultPoolsFunc(ctx, tokenIn, logger)
// PrepareResultPoolsExactAmountIn implements domain.Route.
func (r *RouteMock) PrepareResultPoolsExactAmountIn(ctx context.Context, tokenIn types.Coin, logger log.Logger) ([]domain.RoutablePool, math.LegacyDec, math.LegacyDec, error) {
if r.PrepareResultPoolsExactAmountInFunc != nil {
return r.PrepareResultPoolsExactAmountInFunc(ctx, tokenIn, logger)
}

panic("unimplemented")
}
func (r *RouteMock) PrepareResultPoolsExactAmountOut(ctx context.Context, tokenIn types.Coin, logger log.Logger) ([]domain.RoutablePool, math.LegacyDec, math.LegacyDec, error) {
if r.PrepareResultPoolsExactAmountOutFunc != nil {
return r.PrepareResultPoolsExactAmountOutFunc(ctx, tokenIn, logger)
}

panic("unimplemented")
Expand Down
20 changes: 14 additions & 6 deletions domain/mocks/router_usecase_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ type RouterUsecaseMock struct {
GetOptimalQuoteFunc func(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, opts ...domain.RouterOption) (domain.Quote, error)
GetOptimalQuoteInGivenOutFunc func(ctx context.Context, tokenOut sdk.Coin, tokenInDenom string, opts ...domain.RouterOption) (domain.Quote, error)
GetBestSingleRouteQuoteFunc func(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string) (domain.Quote, error)
GetCustomDirectQuoteFunc func(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, poolID uint64) (domain.Quote, error)
GetCustomDirectQuoteOutGivenInFunc func(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, poolID uint64) (domain.Quote, error)
GetCustomDirectQuoteInGivenOutFunc func(ctx context.Context, tokenOut sdk.Coin, tokenInDenom string, poolID uint64) (domain.Quote, error)
GetCustomDirectQuoteMultiPoolFunc func(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom []string, poolIDs []uint64) (domain.Quote, error)
GetCustomDirectQuoteMultiPoolInGivenOutFunc func(ctx context.Context, tokenOut sdk.Coin, tokenInDenom []string, poolIDs []uint64) (domain.Quote, error)
GetCandidateRoutesFunc func(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string) (ingesttypes.CandidateRoutes, error)
Expand Down Expand Up @@ -66,7 +67,7 @@ func (m *RouterUsecaseMock) GetPoolSpotPrice(ctx context.Context, poolID uint64,
return osmomath.BigDec{}, nil
}

func (m *RouterUsecaseMock) GetOptimalQuote(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, opts ...domain.RouterOption) (domain.Quote, error) {
func (m *RouterUsecaseMock) GetOptimalQuoteOutGivenIn(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, opts ...domain.RouterOption) (domain.Quote, error) {
if m.GetOptimalQuoteFunc != nil {
return m.GetOptimalQuoteFunc(ctx, tokenIn, tokenOutDenom, opts...)
}
Expand All @@ -87,14 +88,21 @@ func (m *RouterUsecaseMock) GetBestSingleRouteQuote(ctx context.Context, tokenIn
panic("unimplemented")
}

func (m *RouterUsecaseMock) GetCustomDirectQuote(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, poolID uint64) (domain.Quote, error) {
if m.GetCustomDirectQuoteFunc != nil {
return m.GetCustomDirectQuoteFunc(ctx, tokenIn, tokenOutDenom, poolID)
func (m *RouterUsecaseMock) GetCustomDirectQuoteOutGivenIn(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, poolID uint64) (domain.Quote, error) {
if m.GetCustomDirectQuoteOutGivenInFunc != nil {
return m.GetCustomDirectQuoteOutGivenInFunc(ctx, tokenIn, tokenOutDenom, poolID)
}
panic("unimplemented")
}

func (m *RouterUsecaseMock) GetCustomDirectQuoteMultiPool(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom []string, poolIDs []uint64) (domain.Quote, error) {
func (m *RouterUsecaseMock) GetCustomDirectQuoteInGivenOut(ctx context.Context, tokenOut sdk.Coin, tokenInDenom string, poolID uint64) (domain.Quote, error) {
if m.GetCustomDirectQuoteInGivenOutFunc != nil {
return m.GetCustomDirectQuoteInGivenOutFunc(ctx, tokenOut, tokenInDenom, poolID)
}
panic("unimplemented")
}

func (m *RouterUsecaseMock) GetCustomDirectQuoteMultiPoolOutGivenIn(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom []string, poolIDs []uint64) (domain.Quote, error) {
if m.GetCustomDirectQuoteMultiPoolFunc != nil {
return m.GetCustomDirectQuoteMultiPoolFunc(ctx, tokenIn, tokenOutDenom, poolIDs)
}
Expand Down
18 changes: 12 additions & 6 deletions domain/mvc/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,25 @@ type SimpleRouterUsecase interface {
type RouterUsecase interface {
SimpleRouterUsecase

// GetOptimalQuote returns the optimal quote for the given tokenIn and tokenOutDenom.
GetOptimalQuote(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, opts ...domain.RouterOption) (domain.Quote, error)
// GetOptimalQuoteOutGivenIn returns the optimal quote for the given tokenIn and tokenOutDenom.
GetOptimalQuoteOutGivenIn(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, opts ...domain.RouterOption) (domain.Quote, error)

// GetOptimalQuoteInGivenOut returns the optimal quote for the given token swap method exact amount out.
GetOptimalQuoteInGivenOut(ctx context.Context, tokenOut sdk.Coin, tokenInDenom string, opts ...domain.RouterOption) (domain.Quote, error)

// GetCustomDirectQuote returns the custom direct quote for the given tokenIn, tokenOutDenom and poolID.
// GetCustomDirectQuoteOutGivenIn returns the custom direct quote for the given tokenIn, tokenOutDenom and poolID.
// It does not search for the route. It directly computes the quote for the given poolID.
// This allows to bypass a min liquidity requirement in the router when attempting to swap over a specific pool.
GetCustomDirectQuote(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, poolID uint64) (domain.Quote, error)
// GetCustomDirectQuoteMultiPool calculates direct custom quote for given tokenIn and tokenOutDenom over given poolID route.
GetCustomDirectQuoteOutGivenIn(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom string, poolID uint64) (domain.Quote, error)

// GetCustomDirectQuoteInGivenOut returns the custom direct quote for the given tokenOut, tokenInDenom and poolID.
// It does not search for the route. It directly computes the quote for the given poolID.
// This allows to bypass a min liquidity requirement in the router when attempting to swap over a specific pool.
GetCustomDirectQuoteInGivenOut(ctx context.Context, tokenOut sdk.Coin, tokenInDenom string, poolID uint64) (domain.Quote, error)

// GetCustomDirectQuoteMultiPoolOutGivenIn calculates direct custom quote for given tokenIn and tokenOutDenom over given poolID route.
// Underlying implementation uses GetCustomDirectQuote.
GetCustomDirectQuoteMultiPool(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom []string, poolIDs []uint64) (domain.Quote, error)
GetCustomDirectQuoteMultiPoolOutGivenIn(ctx context.Context, tokenIn sdk.Coin, tokenOutDenom []string, poolIDs []uint64) (domain.Quote, error)
// GetCustomDirectQuoteMultiPool calculates direct custom quote for given tokenOut and tokenInDenom over given poolID route.
// Underlying implementation uses GetCustomDirectQuote.
GetCustomDirectQuoteMultiPoolInGivenOut(ctx context.Context, tokenOut sdk.Coin, tokenInDenom []string, poolIDs []uint64) (domain.Quote, error)
Expand Down
2 changes: 1 addition & 1 deletion domain/quote_simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ type QuoteSimulator interface {
// - Only direct (non-split) quotes are supported.
// Retursn error if:
// - Simulator address does not have enough funds to pay for the quote.
SimulateQuote(ctx context.Context, quote Quote, slippageToleranceMultiplier osmomath.Dec, simulatorAddress string) TxFeeInfo
SimulateQuoteOutGivenIn(ctx context.Context, quote Quote, slippageToleranceMultiplier osmomath.Dec, simulatorAddress string) TxFeeInfo
}
2 changes: 1 addition & 1 deletion domain/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (s *RouterTestSuite) TestPrepareResultPools() {
s.Run(name, func() {

// Note: token in is chosen arbitrarily since it is irrelevant for this test
actualPools, _, _, err := tc.route.PrepareResultPools(context.TODO(), sdk.NewCoin(DenomTwo, DefaultAmt0), &log.NoOpLogger{})
actualPools, _, _, err := tc.route.PrepareResultPoolsExactAmountIn(context.TODO(), sdk.NewCoin(DenomTwo, DefaultAmt0), &log.NoOpLogger{})
s.Require().NoError(err)

s.ValidateRoutePools(tc.expectedPools, actualPools)
Expand Down
12 changes: 9 additions & 3 deletions domain/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ type Route interface {
// Returns error if the calculation fails.
CalculateTokenOutByTokenIn(ctx context.Context, tokenIn sdk.Coin) (sdk.Coin, error)

// CalculateTokenInByTokenOut calculates the token out amount given the token in amount.
// Returns error if the calculation fails.
CalculateTokenInByTokenOut(ctx context.Context, tokenOut sdk.Coin) (sdk.Coin, error)

// Returns token out denom of the last pool in the route.
// If route is empty, returns empty string.
GetTokenOutDenom() string
Expand All @@ -38,15 +42,17 @@ type Route interface {
// If route is empty, returns empty string.
GetTokenInDenom() string

// PrepareResultPools strips away unnecessary fields
// PrepareResultPoolsExactAmountIn strips away unnecessary fields
// from each pool in the route,
// leaving only the data needed by client
// Runs the quote logic one final time to compute the effective spot price.
// Note that it mutates the route.
// Computes the spot price of the route.
// Returns the spot price before swap and effective spot price.
// The token in is the base token and the token out is the quote token.
PrepareResultPools(ctx context.Context, tokenIn sdk.Coin, logger log.Logger) ([]RoutablePool, osmomath.Dec, osmomath.Dec, error)
PrepareResultPoolsExactAmountIn(ctx context.Context, tokenIn sdk.Coin, logger log.Logger) ([]RoutablePool, osmomath.Dec, osmomath.Dec, error)

PrepareResultPoolsExactAmountOut(ctx context.Context, tokenOut sdk.Coin, logger log.Logger) ([]RoutablePool, osmomath.Dec, osmomath.Dec, error)

String() string
}
Expand All @@ -59,7 +65,7 @@ type SplitRoute interface {

type Quote interface {
GetAmountIn() sdk.Coin
GetAmountOut() osmomath.Int
GetAmountOut() sdk.Coin
GetRoute() []SplitRoute
GetEffectiveFee() osmomath.Dec
GetPriceImpact() osmomath.Dec
Expand Down
6 changes: 3 additions & 3 deletions ingest/usecase/plugins/orderbook/fillbot/cyclic_arb.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ func (o *orderbookFillerIngestPlugin) estimateCyclicArb(ctx blockctx.BlockCtxI,

goCtx := ctx.AsGoCtx()

baseInOrderbookQuote, err := o.routerUseCase.GetCustomDirectQuote(goCtx, coinIn, denomOut, canonicalOrderbookPoolId)
baseInOrderbookQuote, err := o.routerUseCase.GetCustomDirectQuoteOutGivenIn(goCtx, coinIn, denomOut, canonicalOrderbookPoolId)
if err != nil {
return osmomath.Int{}, nil, err
}

// Make it $10 in USDC terms for quoteDenom
quoteInCoin := sdk.NewCoin(denomOut, baseInOrderbookQuote.GetAmountOut())
quoteInCoin := sdk.NewCoin(denomOut, baseInOrderbookQuote.GetAmountOut().Amount)
cyclicArbQuote, err := o.routerUseCase.GetSimpleQuote(goCtx, quoteInCoin, coinIn.Denom, domain.WithDisableSplitRoutes())
if err != nil {
return osmomath.Int{}, nil, err
Expand All @@ -45,7 +45,7 @@ func (o *orderbookFillerIngestPlugin) estimateCyclicArb(ctx blockctx.BlockCtxI,

fullCyclicArbRoute := append(routeThere[0].GetPools(), routeBack[0].GetPools()...)

return inverseAmountIn, fullCyclicArbRoute, nil
return inverseAmountIn.Amount, fullCyclicArbRoute, nil
}

// validateArb validates the arb opportunity by constructing a route from SQS router and then simulating it against chain.
Expand Down
4 changes: 2 additions & 2 deletions pools/usecase/pools_usecase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,9 @@ func (s *PoolsUsecaseTestSuite) TestGetRoutesFromCandidates() {
// helper method for validation.
// Note token in is chosen arbitrarily since it is irrelevant for this test
tokenIn := sdk.NewCoin(tc.tokenInDenom, osmomath.NewInt(100))
actualPools, _, _, err := actualRoute.PrepareResultPools(context.TODO(), tokenIn, logger)
actualPools, _, _, err := actualRoute.PrepareResultPoolsExactAmountIn(context.TODO(), tokenIn, logger)
s.Require().NoError(err)
expectedPools, _, _, err := expectedRoute.PrepareResultPools(context.TODO(), tokenIn, logger)
expectedPools, _, _, err := expectedRoute.PrepareResultPoolsExactAmountIn(context.TODO(), tokenIn, logger)
s.Require().NoError(err)

// Validates:
Expand Down
4 changes: 2 additions & 2 deletions quotesimulator/quote_simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func NewQuoteSimulator(msgSimulator tx.MsgSimulator, encodingConfig params.Encod
}

// SimulateQuote implements domain.QuoteSimulator
func (q *quoteSimulator) SimulateQuote(ctx context.Context, quote domain.Quote, slippageToleranceMultiplier osmomath.Dec, simulatorAddress string) domain.TxFeeInfo {
func (q *quoteSimulator) SimulateQuoteOutGivenIn(ctx context.Context, quote domain.Quote, slippageToleranceMultiplier osmomath.Dec, simulatorAddress string) domain.TxFeeInfo {
route := quote.GetRoute()
if len(route) != 1 {
return domain.TxFeeInfo{Err: fmt.Sprintf("route length must be 1, got %d", len(route))}
Expand All @@ -50,7 +50,7 @@ func (q *quoteSimulator) SimulateQuote(ctx context.Context, quote domain.Quote,

// Slippage bound from the token in and provided slippage tolerance multiplier
tokenOutAmt := quote.GetAmountOut()
slippageBound := tokenOutAmt.ToLegacyDec().Mul(slippageToleranceMultiplier).TruncateInt()
slippageBound := tokenOutAmt.Amount.ToLegacyDec().Mul(slippageToleranceMultiplier).TruncateInt()

// Create the swap message
swapMsg := &poolmanagertypes.MsgSwapExactAmountIn{
Expand Down
6 changes: 3 additions & 3 deletions quotesimulator/quote_simulator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func TestSimulateQuote(t *testing.T) {
return uosmoCoinIn
},

GetAmountOutFunc: func() math.Int {
return osmomath.NewInt(200000)
GetAmountOutFunc: func() sdk.Coin {
return sdk.Coin{Amount: osmomath.NewInt(200000)}
},

GetRouteFunc: func() []domain.SplitRoute {
Expand Down Expand Up @@ -112,7 +112,7 @@ func TestSimulateQuote(t *testing.T) {
)

// System under test
priceInfo := simulator.SimulateQuote(
priceInfo := simulator.SimulateQuoteOutGivenIn(
context.Background(),
mockQuote,
tt.slippageToleranceMultiplier,
Expand Down
Loading
Loading