Refactor user settings management to remove IsGmxEnabled and DefaultExchange from updatable fields, introducing GmxSlippage instead. Update UserController, UserService, and related DTOs to reflect these changes, ensuring proper handling of user settings. Adjust database schema and migrations to accommodate the new GmxSlippage property, enhancing user customization options for trading configurations.
This commit is contained in:
@@ -157,6 +157,7 @@ public class UserController : BaseController
|
||||
{
|
||||
var user = await GetUser();
|
||||
// Map API request to DTO
|
||||
// Note: IsGmxEnabled and DefaultExchange are not updatable via settings endpoint
|
||||
var settingsDto = new Managing.Application.Abstractions.Models.UserSettingsDto
|
||||
{
|
||||
LowEthAmountAlert = settings.LowEthAmountAlert,
|
||||
@@ -164,12 +165,11 @@ public class UserController : BaseController
|
||||
AutoswapAmount = settings.AutoswapAmount,
|
||||
MaxWaitingTimeForPositionToGetFilledSeconds = settings.MaxWaitingTimeForPositionToGetFilledSeconds,
|
||||
MaxTxnGasFeePerPosition = settings.MaxTxnGasFeePerPosition,
|
||||
IsGmxEnabled = settings.IsGmxEnabled,
|
||||
GmxSlippage = settings.GmxSlippage,
|
||||
MinimumConfidence = settings.MinimumConfidence,
|
||||
TrendStrongAgreementThreshold = settings.TrendStrongAgreementThreshold,
|
||||
SignalAgreementThreshold = settings.SignalAgreementThreshold,
|
||||
AllowSignalTrendOverride = settings.AllowSignalTrendOverride,
|
||||
DefaultExchange = settings.DefaultExchange
|
||||
AllowSignalTrendOverride = settings.AllowSignalTrendOverride
|
||||
};
|
||||
var updatedUser = await _userService.UpdateUserSettings(user, settingsDto);
|
||||
return Ok(updatedUser);
|
||||
|
||||
@@ -11,13 +11,14 @@ public class UpdateUserSettingsRequest
|
||||
public decimal? AutoswapAmount { get; set; }
|
||||
public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; }
|
||||
public decimal? MaxTxnGasFeePerPosition { get; set; }
|
||||
public bool? IsGmxEnabled { get; set; }
|
||||
// Note: IsGmxEnabled is not updatable via settings endpoint
|
||||
public decimal? GmxSlippage { get; set; }
|
||||
|
||||
// Indicator Combo Configuration
|
||||
public Confidence? MinimumConfidence { get; set; }
|
||||
public decimal? TrendStrongAgreementThreshold { get; set; }
|
||||
public decimal? SignalAgreementThreshold { get; set; }
|
||||
public bool? AllowSignalTrendOverride { get; set; }
|
||||
public TradingExchanges? DefaultExchange { get; set; }
|
||||
// Note: DefaultExchange is not updatable via settings endpoint
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@ public class UserSettingsDto
|
||||
public decimal? AutoswapAmount { get; set; }
|
||||
public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; }
|
||||
public decimal? MaxTxnGasFeePerPosition { get; set; }
|
||||
public bool? IsGmxEnabled { get; set; }
|
||||
// Note: IsGmxEnabled is not updatable via settings endpoint
|
||||
public decimal? GmxSlippage { get; set; }
|
||||
|
||||
// Indicator Combo Configuration
|
||||
public Confidence? MinimumConfidence { get; set; }
|
||||
public decimal? TrendStrongAgreementThreshold { get; set; }
|
||||
public decimal? SignalAgreementThreshold { get; set; }
|
||||
public bool? AllowSignalTrendOverride { get; set; }
|
||||
public TradingExchanges? DefaultExchange { get; set; }
|
||||
// Note: DefaultExchange is not updatable via settings endpoint
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ public interface IEvmManager
|
||||
Task<Trade> IncreasePosition(Account account, Ticker ticker, TradeDirection direction, decimal price,
|
||||
decimal quantity, decimal? leverage = 1,
|
||||
decimal? stopLossPrice = null,
|
||||
decimal? takeProfitPrice = null);
|
||||
decimal? takeProfitPrice = null,
|
||||
decimal? allowedSlippage = null);
|
||||
|
||||
Task<Trade> GetTrade(Account account, string chainName, Ticker ticker);
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ public interface IExchangeService
|
||||
DateTime? currentDate = null,
|
||||
bool ioc = true,
|
||||
decimal? stopLossPrice = null,
|
||||
decimal? takeProfitPrice = null);
|
||||
decimal? takeProfitPrice = null,
|
||||
decimal? allowedSlippage = null);
|
||||
|
||||
Task<decimal> GetBalance(Account account, bool isForPaperTrading = false);
|
||||
Task<Balance?> GetBalance(Account account, Ticker ticker);
|
||||
|
||||
@@ -58,7 +58,7 @@ public interface ITradingService
|
||||
Task<Scenario?> GetScenarioByNameUserAsync(string scenarioName, User user);
|
||||
Task<IEnumerable<Position>> GetPositionByUserIdAsync(int userId);
|
||||
Task<SwapInfos> SwapGmxTokensAsync(User user, string accountName, Ticker fromTicker, Ticker toTicker,
|
||||
double amount, string orderType = "market", double? triggerRatio = null, double allowedSlippage = 0.5);
|
||||
double amount, string orderType = "market", double? triggerRatio = null, double? allowedSlippage = null);
|
||||
|
||||
/// <summary>
|
||||
/// Calculates indicator values and generates signals for a given ticker, timeframe, and date range with selected indicators.
|
||||
|
||||
@@ -73,6 +73,10 @@ namespace Managing.Application.Trading.Handlers
|
||||
var stopLossPrice = RiskHelpers.GetStopLossPrice(request.Direction, openPrice, request.MoneyManagement);
|
||||
var takeProfitPrice = RiskHelpers.GetTakeProfitPrice(request.Direction, openPrice, request.MoneyManagement);
|
||||
|
||||
// Get user's slippage setting from IndicatorComboConfig
|
||||
var config = TradingBox.CreateConfigFromUserSettings(request.User);
|
||||
var allowedSlippage = request.User.GmxSlippage ?? config.GmxSlippage;
|
||||
|
||||
var trade = await exchangeService.OpenTrade(
|
||||
account,
|
||||
request.Ticker,
|
||||
@@ -84,7 +88,8 @@ namespace Managing.Application.Trading.Handlers
|
||||
isForPaperTrading: request.IsForPaperTrading,
|
||||
currentDate: request.Date,
|
||||
stopLossPrice: stopLossPrice,
|
||||
takeProfitPrice: takeProfitPrice);
|
||||
takeProfitPrice: takeProfitPrice,
|
||||
allowedSlippage: allowedSlippage);
|
||||
|
||||
position.Open = trade;
|
||||
|
||||
|
||||
@@ -455,7 +455,7 @@ public class TradingService : ITradingService
|
||||
}
|
||||
|
||||
public async Task<SwapInfos> SwapGmxTokensAsync(User user, string accountName, Ticker fromTicker, Ticker toTicker,
|
||||
double amount, string orderType = "market", double? triggerRatio = null, double allowedSlippage = 0.5)
|
||||
double amount, string orderType = "market", double? triggerRatio = null, double? allowedSlippage = null)
|
||||
{
|
||||
// Get the account for the user
|
||||
var account = await _accountService.GetAccountByUser(user, accountName, true, false);
|
||||
@@ -473,6 +473,14 @@ public class TradingService : ITradingService
|
||||
|
||||
try
|
||||
{
|
||||
// Get user's config to access default slippage value
|
||||
var config = TradingBox.CreateConfigFromUserSettings(user);
|
||||
|
||||
// Use provided allowedSlippage if specified, otherwise use user's GmxSlippage setting, or default from IndicatorComboConfig
|
||||
var slippageToUse = (double)(allowedSlippage.HasValue
|
||||
? (decimal)allowedSlippage.Value
|
||||
: (user.GmxSlippage ?? config.GmxSlippage));
|
||||
|
||||
// Call the Web3ProxyService to swap GMX tokens
|
||||
var swapInfos = await _web3ProxyService.SwapGmxTokensAsync(
|
||||
account.Key,
|
||||
@@ -481,7 +489,7 @@ public class TradingService : ITradingService
|
||||
amount,
|
||||
orderType,
|
||||
triggerRatio,
|
||||
allowedSlippage
|
||||
slippageToUse
|
||||
);
|
||||
|
||||
return swapInfos;
|
||||
|
||||
@@ -359,8 +359,10 @@ public class UserService : IUserService
|
||||
if (settings.MaxTxnGasFeePerPosition.HasValue)
|
||||
user.MaxTxnGasFeePerPosition = settings.MaxTxnGasFeePerPosition.Value;
|
||||
|
||||
if (settings.IsGmxEnabled.HasValue)
|
||||
user.IsGmxEnabled = settings.IsGmxEnabled.Value;
|
||||
// Note: IsGmxEnabled is not updatable via settings endpoint - managed internally
|
||||
|
||||
if (settings.GmxSlippage.HasValue)
|
||||
user.GmxSlippage = settings.GmxSlippage.Value;
|
||||
|
||||
if (settings.MinimumConfidence.HasValue)
|
||||
user.MinimumConfidence = settings.MinimumConfidence.Value;
|
||||
@@ -374,8 +376,7 @@ public class UserService : IUserService
|
||||
if (settings.AllowSignalTrendOverride.HasValue)
|
||||
user.AllowSignalTrendOverride = settings.AllowSignalTrendOverride.Value;
|
||||
|
||||
if (settings.DefaultExchange.HasValue)
|
||||
user.DefaultExchange = settings.DefaultExchange.Value;
|
||||
// Note: DefaultExchange is not updatable via settings endpoint - managed internally
|
||||
|
||||
await _userRepository.SaveOrUpdateUserAsync(user);
|
||||
return user;
|
||||
|
||||
@@ -58,6 +58,12 @@ public class IndicatorComboConfig
|
||||
/// </summary>
|
||||
[Id(5)]
|
||||
public TradingExchanges DefaultExchange { get; set; } = TradingExchanges.GmxV2;
|
||||
|
||||
/// <summary>
|
||||
/// GMX slippage tolerance percentage for trades (default: 0.5%)
|
||||
/// </summary>
|
||||
[Id(6)]
|
||||
public decimal GmxSlippage { get; set; } = 0.5m;
|
||||
}
|
||||
|
||||
public static class TradingBox
|
||||
@@ -80,6 +86,8 @@ public static class TradingBox
|
||||
config.AllowSignalTrendOverride = user.AllowSignalTrendOverride ?? true;
|
||||
// DefaultExchange defaults to GMX if not set
|
||||
config.DefaultExchange = user.DefaultExchange ?? TradingExchanges.GmxV2;
|
||||
// GmxSlippage defaults to 0.5% if not set
|
||||
config.GmxSlippage = user.GmxSlippage ?? 0.5m;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ public class User
|
||||
[Id(12)] public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; }
|
||||
[Id(13)] public decimal? MaxTxnGasFeePerPosition { get; set; }
|
||||
[Id(14)] public bool IsGmxEnabled { get; set; } = false;
|
||||
[Id(20)] public decimal? GmxSlippage { get; set; }
|
||||
|
||||
// User Settings - Indicator Combo Configuration
|
||||
[Id(15)] public Confidence? MinimumConfidence { get; set; }
|
||||
|
||||
1788
src/Managing.Infrastructure.Database/Migrations/20251230000830_AddGmxSlippageSetting.Designer.cs
generated
Normal file
1788
src/Managing.Infrastructure.Database/Migrations/20251230000830_AddGmxSlippageSetting.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Managing.Infrastructure.Databases.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddGmxSlippageSetting : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Add column with default value
|
||||
migrationBuilder.AddColumn<decimal>(
|
||||
name: "GmxSlippage",
|
||||
table: "Users",
|
||||
type: "numeric(5,2)",
|
||||
nullable: true,
|
||||
defaultValue: 0.5m);
|
||||
|
||||
// Update existing NULL values to default
|
||||
migrationBuilder.Sql(@"
|
||||
UPDATE ""Users""
|
||||
SET ""GmxSlippage"" = 0.5
|
||||
WHERE ""GmxSlippage"" IS NULL;
|
||||
");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "GmxSlippage",
|
||||
table: "Users");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1441,6 +1441,9 @@ namespace Managing.Infrastructure.Databases.Migrations
|
||||
b.Property<bool>("EnableAutoswap")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal?>("GmxSlippage")
|
||||
.HasColumnType("decimal(5,2)");
|
||||
|
||||
b.Property<bool>("IsAdmin")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ public class UserEntity
|
||||
public int? MaxWaitingTimeForPositionToGetFilledSeconds { get; set; } = 600; // Default: 10 minutes (600 seconds)
|
||||
[Column(TypeName = "decimal(18,8)")] public decimal? MaxTxnGasFeePerPosition { get; set; } = 1.5m; // Default: MaximumGasFeeUsd
|
||||
public bool IsGmxEnabled { get; set; } = false;
|
||||
[Column(TypeName = "decimal(5,2)")] public decimal? GmxSlippage { get; set; } = 0.5m; // Default: 0.5% slippage for GMX trades
|
||||
|
||||
// User Settings - Indicator Combo Configuration
|
||||
public Confidence? MinimumConfidence { get; set; } = Confidence.Medium; // Default: Medium confidence for context indicators
|
||||
|
||||
@@ -140,6 +140,7 @@ public static class PostgreSqlMappers
|
||||
MaxWaitingTimeForPositionToGetFilledSeconds = entity.MaxWaitingTimeForPositionToGetFilledSeconds,
|
||||
MaxTxnGasFeePerPosition = entity.MaxTxnGasFeePerPosition,
|
||||
IsGmxEnabled = entity.IsGmxEnabled,
|
||||
GmxSlippage = entity.GmxSlippage,
|
||||
MinimumConfidence = entity.MinimumConfidence,
|
||||
TrendStrongAgreementThreshold = entity.TrendStrongAgreementThreshold,
|
||||
SignalAgreementThreshold = entity.SignalAgreementThreshold,
|
||||
@@ -187,6 +188,7 @@ public static class PostgreSqlMappers
|
||||
MaxWaitingTimeForPositionToGetFilledSeconds = user.MaxWaitingTimeForPositionToGetFilledSeconds,
|
||||
MaxTxnGasFeePerPosition = user.MaxTxnGasFeePerPosition,
|
||||
IsGmxEnabled = user.IsGmxEnabled,
|
||||
GmxSlippage = user.GmxSlippage,
|
||||
MinimumConfidence = user.MinimumConfidence,
|
||||
TrendStrongAgreementThreshold = user.TrendStrongAgreementThreshold,
|
||||
SignalAgreementThreshold = user.SignalAgreementThreshold,
|
||||
|
||||
@@ -263,6 +263,7 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
|
||||
existingUser.MaxWaitingTimeForPositionToGetFilledSeconds = user.MaxWaitingTimeForPositionToGetFilledSeconds;
|
||||
existingUser.MaxTxnGasFeePerPosition = user.MaxTxnGasFeePerPosition;
|
||||
existingUser.IsGmxEnabled = user.IsGmxEnabled;
|
||||
existingUser.GmxSlippage = user.GmxSlippage;
|
||||
existingUser.MinimumConfidence = user.MinimumConfidence;
|
||||
existingUser.TrendStrongAgreementThreshold = user.TrendStrongAgreementThreshold;
|
||||
existingUser.SignalAgreementThreshold = user.SignalAgreementThreshold;
|
||||
|
||||
@@ -23,7 +23,8 @@ public interface IExchangeProcessor
|
||||
DateTime? currentDate = null,
|
||||
bool ioc = true,
|
||||
decimal? stopLossPrice = null,
|
||||
decimal? takeProfitPrice = null);
|
||||
decimal? takeProfitPrice = null,
|
||||
decimal? allowedSlippage = null);
|
||||
Task<decimal> GetBalance(Account account, bool isForPaperTrading = false);
|
||||
Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false);
|
||||
Task<decimal> GetPrice(Account account, Ticker ticker, DateTime date);
|
||||
|
||||
@@ -46,10 +46,11 @@ namespace Managing.Infrastructure.Exchanges
|
||||
DateTime? currentDate = null,
|
||||
bool ioc = true,
|
||||
decimal? stopLossPrice = null,
|
||||
decimal? takeProfitPrice = null)
|
||||
decimal? takeProfitPrice = null,
|
||||
decimal? allowedSlippage = null)
|
||||
{
|
||||
_logger.LogDebug(
|
||||
$"OpenMarketTrade - {ticker} - Type: {tradeType} - {direction} - Price: {price} - Quantity: {quantity} - Leverage: {leverage} - SL: {stopLossPrice} - TP: {takeProfitPrice}");
|
||||
$"OpenMarketTrade - {ticker} - Type: {tradeType} - {direction} - Price: {price} - Quantity: {quantity} - Leverage: {leverage} - SL: {stopLossPrice} - TP: {takeProfitPrice} - Slippage: {allowedSlippage}");
|
||||
|
||||
if (isForPaperTrading)
|
||||
{
|
||||
@@ -60,7 +61,7 @@ namespace Managing.Infrastructure.Exchanges
|
||||
|
||||
var processor = GetProcessor(account);
|
||||
return await processor.OpenTrade(account, ticker, direction, price, quantity, leverage, tradeType,
|
||||
reduceOnly, isForPaperTrading, currentDate, ioc, stopLossPrice, takeProfitPrice);
|
||||
reduceOnly, isForPaperTrading, currentDate, ioc, stopLossPrice, takeProfitPrice, allowedSlippage);
|
||||
}
|
||||
|
||||
private IExchangeProcessor GetProcessor(Account account)
|
||||
|
||||
@@ -35,7 +35,8 @@ namespace Managing.Infrastructure.Exchanges.Exchanges
|
||||
DateTime? currentDate = null,
|
||||
bool ioc = true,
|
||||
decimal? stopLossPrice = null,
|
||||
decimal? takeProfitPrice = null);
|
||||
decimal? takeProfitPrice = null,
|
||||
decimal? allowedSlippage = null);
|
||||
public abstract Orderbook GetOrderbook(Account account, Ticker ticker);
|
||||
public abstract Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false);
|
||||
public abstract Task<List<Trade>> GetOrders(Account account, Ticker ticker);
|
||||
|
||||
@@ -174,7 +174,8 @@ public class EvmProcessor : BaseProcessor
|
||||
DateTime? currentDate = null,
|
||||
bool ioc = true,
|
||||
decimal? stopLossPrice = null,
|
||||
decimal? takeProfitPrice = null)
|
||||
decimal? takeProfitPrice = null,
|
||||
decimal? allowedSlippage = null)
|
||||
{
|
||||
Trade trade;
|
||||
if (reduceOnly)
|
||||
@@ -197,7 +198,7 @@ public class EvmProcessor : BaseProcessor
|
||||
else
|
||||
{
|
||||
trade = await _evmManager.IncreasePosition(account, ticker, direction, price, quantity, leverage,
|
||||
stopLossPrice, takeProfitPrice);
|
||||
stopLossPrice, takeProfitPrice, allowedSlippage);
|
||||
}
|
||||
|
||||
return trade;
|
||||
|
||||
@@ -641,7 +641,8 @@ public class EvmManager : IEvmManager
|
||||
decimal quantity,
|
||||
decimal? leverage,
|
||||
decimal? stopLossPrice = null,
|
||||
decimal? takeProfitPrice = null)
|
||||
decimal? takeProfitPrice = null,
|
||||
decimal? allowedSlippage = null)
|
||||
{
|
||||
Trade trade = null;
|
||||
|
||||
@@ -664,7 +665,8 @@ public class EvmManager : IEvmManager
|
||||
quantity,
|
||||
leverage = leverage ?? 1.0m,
|
||||
stopLossPrice = stopLossPrice,
|
||||
takeProfitPrice = takeProfitPrice
|
||||
takeProfitPrice = takeProfitPrice,
|
||||
allowedSlippage = allowedSlippage.HasValue ? (double)allowedSlippage.Value : (double?)null
|
||||
});
|
||||
|
||||
// Create a trade object using the returned hash
|
||||
|
||||
@@ -643,7 +643,8 @@ const openPositionSchema = z.object({
|
||||
direction: z.enum(Object.keys(TradeDirection) as [string, ...string[]]),
|
||||
price: z.number().positive().optional(),
|
||||
quantity: z.number().positive(),
|
||||
leverage: z.number().positive()
|
||||
leverage: z.number().positive(),
|
||||
allowedSlippage: z.number().min(0).max(100).optional()
|
||||
});
|
||||
|
||||
// Schema for cancel-orders request
|
||||
@@ -774,7 +775,8 @@ export const openGmxPositionImpl = async (
|
||||
leverage: number,
|
||||
price?: number,
|
||||
stopLossPrice?: number,
|
||||
takeProfitPrice?: number
|
||||
takeProfitPrice?: number,
|
||||
allowedSlippage?: number
|
||||
): Promise<string> => {
|
||||
return executeWithFallback(
|
||||
async (sdk, retryCount) => {
|
||||
@@ -852,12 +854,18 @@ export const openGmxPositionImpl = async (
|
||||
const leverageBps = BigInt((leverage || 1) * 10000);
|
||||
const limitPrice = price ? numberToBigint(price, 30) : undefined;
|
||||
|
||||
// Use provided slippage or default to 0.5% (50 basis points)
|
||||
// Convert percentage to basis points (e.g., 0.5% = 50 bps)
|
||||
const slippageBps = allowedSlippage != null
|
||||
? Math.floor(allowedSlippage * 100) // Convert percentage to basis points
|
||||
: 50; // Default 0.5% = 50 basis points
|
||||
|
||||
const params: PositionIncreaseParams = {
|
||||
payAmount: collateralAmount,
|
||||
marketAddress: marketInfo.marketTokenAddress,
|
||||
payTokenAddress: collateralToken.address,
|
||||
collateralTokenAddress: collateralToken.address,
|
||||
allowedSlippageBps: 55, // 0.55% slippage
|
||||
allowedSlippageBps: slippageBps,
|
||||
leverage: leverageBps,
|
||||
skipSimulation: true,
|
||||
referralCodeForTxn: encodeReferralCode("kaigen_ai"),
|
||||
@@ -971,7 +979,8 @@ export async function openGmxPosition(
|
||||
quantity?: number,
|
||||
leverage?: number,
|
||||
stopLossPrice?: number,
|
||||
takeProfitPrice?: number
|
||||
takeProfitPrice?: number,
|
||||
allowedSlippage?: number
|
||||
) {
|
||||
try {
|
||||
// Validate the request parameters
|
||||
@@ -984,7 +993,8 @@ export async function openGmxPosition(
|
||||
quantity,
|
||||
leverage,
|
||||
stopLossPrice,
|
||||
takeProfitPrice
|
||||
takeProfitPrice,
|
||||
allowedSlippage
|
||||
});
|
||||
|
||||
// Get client for the address
|
||||
@@ -999,7 +1009,8 @@ export async function openGmxPosition(
|
||||
leverage,
|
||||
price,
|
||||
stopLossPrice,
|
||||
takeProfitPrice
|
||||
takeProfitPrice,
|
||||
allowedSlippage
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user