Update slippage handling in GMX position management to ensure valid ranges and improve logging. Refactor slippage calculations in openGmxPositionImpl and swapGmxTokensImpl, introducing clamping for slippage percentages and detailed output for swap calculations. Adjust tests to reflect changes in expected parameters for position opening.
This commit is contained in:
BIN
.cursor/.DS_Store
vendored
Normal file
BIN
.cursor/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
assets/.DS_Store
vendored
Normal file
BIN
assets/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
scripts/.DS_Store
vendored
BIN
scripts/.DS_Store
vendored
Binary file not shown.
BIN
src/.DS_Store
vendored
BIN
src/.DS_Store
vendored
Binary file not shown.
BIN
src/Managing.Web3Proxy/.DS_Store
vendored
BIN
src/Managing.Web3Proxy/.DS_Store
vendored
Binary file not shown.
@@ -856,9 +856,11 @@ export const openGmxPositionImpl = async (
|
|||||||
|
|
||||||
// Use provided slippage or default to 0.5% (50 basis points)
|
// Use provided slippage or default to 0.5% (50 basis points)
|
||||||
// Convert percentage to basis points (e.g., 0.5% = 50 bps)
|
// Convert percentage to basis points (e.g., 0.5% = 50 bps)
|
||||||
const slippageBps = allowedSlippage != null
|
// Ensure slippage is within valid range (0-100%)
|
||||||
? Math.floor(allowedSlippage * 100) // Convert percentage to basis points
|
const slippagePercentage = allowedSlippage != null
|
||||||
: 50; // Default 0.5% = 50 basis points
|
? Math.max(0, Math.min(100, allowedSlippage)) // Clamp between 0-100%
|
||||||
|
: 0.5; // Default 0.5%
|
||||||
|
const slippageBps = Math.floor(slippagePercentage * 100); // Convert percentage to basis points
|
||||||
|
|
||||||
const params: PositionIncreaseParams = {
|
const params: PositionIncreaseParams = {
|
||||||
payAmount: collateralAmount,
|
payAmount: collateralAmount,
|
||||||
@@ -884,7 +886,9 @@ export const openGmxPositionImpl = async (
|
|||||||
payTokenAddress: collateralToken.address,
|
payTokenAddress: collateralToken.address,
|
||||||
collateralTokenAddress: collateralToken.address,
|
collateralTokenAddress: collateralToken.address,
|
||||||
leverage: leverageBps.toString(),
|
leverage: leverageBps.toString(),
|
||||||
direction: direction
|
direction: direction,
|
||||||
|
allowedSlippagePercentage: slippagePercentage,
|
||||||
|
allowedSlippageBps: slippageBps
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check and handle token allowance for GMX contracts
|
// Check and handle token allowance for GMX contracts
|
||||||
@@ -3098,9 +3102,16 @@ export const swapGmxTokensImpl = async (
|
|||||||
triggerPrice = BigInt(Math.floor(triggerRatio * Math.pow(10, 30)));
|
triggerPrice = BigInt(Math.floor(triggerRatio * Math.pow(10, 30)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert slippage percentage to basis points
|
// Ensure slippage is within valid range (0-100%) and convert to basis points
|
||||||
const allowedSlippageBps = Math.floor(allowedSlippage * 100); // Convert percentage to basis points
|
const slippagePercentage = Math.max(0, Math.min(100, allowedSlippage)); // Clamp between 0-100%
|
||||||
|
const allowedSlippageBps = Math.floor(slippagePercentage * 100); // Convert percentage to basis points
|
||||||
|
|
||||||
|
console.log('💱 Swap slippage settings:', {
|
||||||
|
slippagePercentage: slippagePercentage,
|
||||||
|
slippageBps: allowedSlippageBps,
|
||||||
|
fromTicker,
|
||||||
|
toTicker
|
||||||
|
});
|
||||||
|
|
||||||
// Try using the SDK's built-in swap method first
|
// Try using the SDK's built-in swap method first
|
||||||
try {
|
try {
|
||||||
@@ -3116,7 +3127,10 @@ export const swapGmxTokensImpl = async (
|
|||||||
swapParams.marketsInfoData = marketsInfoData;
|
swapParams.marketsInfoData = marketsInfoData;
|
||||||
swapParams.tokensData = tokensData;
|
swapParams.tokensData = tokensData;
|
||||||
|
|
||||||
console.log('🔄 Attempting SDK swap...');
|
console.log('🔄 Attempting SDK swap with slippage:', {
|
||||||
|
allowedSlippageBps: allowedSlippageBps,
|
||||||
|
slippagePercentage: slippagePercentage
|
||||||
|
});
|
||||||
await sdk.orders.swap(swapParams);
|
await sdk.orders.swap(swapParams);
|
||||||
console.log('✅ SDK swap successful!');
|
console.log('✅ SDK swap successful!');
|
||||||
} catch (sdkError) {
|
} catch (sdkError) {
|
||||||
@@ -3160,13 +3174,40 @@ export const swapGmxTokensImpl = async (
|
|||||||
|
|
||||||
console.log(`💰 Calculated execution fee: ${(Number(executionFee.feeTokenAmount) / 1e18).toFixed(6)} ETH`);
|
console.log(`💰 Calculated execution fee: ${(Number(executionFee.feeTokenAmount) / 1e18).toFixed(6)} ETH`);
|
||||||
|
|
||||||
|
// Calculate minOutputAmount based on current market price and slippage
|
||||||
|
// Get the current price ratio from token data
|
||||||
|
const fromTokenPrice = fromTokenData.prices?.minPrice
|
||||||
|
? Number(fromTokenData.prices.minPrice) / 1e30
|
||||||
|
: 1;
|
||||||
|
const toTokenPrice = toTokenData.prices?.minPrice
|
||||||
|
? Number(toTokenData.prices.minPrice) / 1e30
|
||||||
|
: 1;
|
||||||
|
|
||||||
|
// Calculate expected output amount (simplified - assumes 1:1 price ratio if prices unavailable)
|
||||||
|
const fromAmountInUsd = (Number(verifiedFromTokenAmount) / Math.pow(10, fromTokenData.decimals)) * fromTokenPrice;
|
||||||
|
const expectedOutputInUsd = fromAmountInUsd * (toTokenPrice / fromTokenPrice);
|
||||||
|
const expectedOutputInTokens = expectedOutputInUsd / toTokenPrice;
|
||||||
|
|
||||||
|
// Apply slippage tolerance to minimum output
|
||||||
|
const minOutputAmount = BigInt(Math.floor(
|
||||||
|
expectedOutputInTokens * Math.pow(10, toTokenData.decimals) * (1 - slippagePercentage / 100)
|
||||||
|
));
|
||||||
|
|
||||||
|
console.log('💱 Swap output calculation:', {
|
||||||
|
fromAmountUsd: fromAmountInUsd.toFixed(2),
|
||||||
|
expectedOutputUsd: expectedOutputInUsd.toFixed(2),
|
||||||
|
expectedOutputTokens: expectedOutputInTokens.toFixed(6),
|
||||||
|
minOutputAmount: minOutputAmount.toString(),
|
||||||
|
slippagePercentage: slippagePercentage
|
||||||
|
});
|
||||||
|
|
||||||
await createSwapOrderTxn(sdk, {
|
await createSwapOrderTxn(sdk, {
|
||||||
fromTokenAddress: fromTokenData.address,
|
fromTokenAddress: fromTokenData.address,
|
||||||
fromTokenAmount: verifiedFromTokenAmount,
|
fromTokenAmount: verifiedFromTokenAmount,
|
||||||
toTokenAddress: toTokenData.address,
|
toTokenAddress: toTokenData.address,
|
||||||
swapPath: swapPath,
|
swapPath: swapPath,
|
||||||
orderType: OrderType.MarketSwap,
|
orderType: OrderType.MarketSwap,
|
||||||
minOutputAmount: BigInt(Math.floor(amount * Math.pow(10, toTokenData.decimals) * (1 - allowedSlippage / 100))),
|
minOutputAmount: minOutputAmount,
|
||||||
referralCode: encodeReferralCode("kaigen_ai"),
|
referralCode: encodeReferralCode("kaigen_ai"),
|
||||||
executionFee: executionFee.feeTokenAmount,
|
executionFee: executionFee.feeTokenAmount,
|
||||||
allowedSlippage: allowedSlippageBps,
|
allowedSlippage: allowedSlippageBps,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ test('GMX Position Opening', async (t) => {
|
|||||||
TradeDirection.Long,
|
TradeDirection.Long,
|
||||||
0.00012, // ~5.3 USDC collateral with 2x leverage (fits available balance of 5.69 USDC)
|
0.00012, // ~5.3 USDC collateral with 2x leverage (fits available balance of 5.69 USDC)
|
||||||
2,
|
2,
|
||||||
87856,
|
87880,
|
||||||
75000,
|
75000,
|
||||||
100000
|
100000
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user