update contracts and approval logs

This commit is contained in:
2025-08-27 05:08:13 +07:00
parent 9d808cfe1a
commit 5d7f73a794
4 changed files with 214 additions and 90 deletions

View File

@@ -51,12 +51,12 @@ export const CONTRACTS = {
DataStore: "0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8", DataStore: "0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8",
EventEmitter: "0xC8ee91A54287DB53897056e12D9819156D3822Fb", EventEmitter: "0xC8ee91A54287DB53897056e12D9819156D3822Fb",
SubaccountRouter: "0xa329221a77BE08485f59310b873b14815c82E10D", SubaccountRouter: "0xa329221a77BE08485f59310b873b14815c82E10D",
ExchangeRouter: "0x5ac4e27341e4cccb3e5fd62f9e62db2adf43dd57", ExchangeRouter: "0x602b805EedddBbD9ddff44A7dcBD46cb07849685",
DepositVault: "0xF89e77e8Dc11691C9e8757e84aaFbCD8A67d7A55", DepositVault: "0xF89e77e8Dc11691C9e8757e84aaFbCD8A67d7A55",
WithdrawalVault: "0x0628D46b5D145f183AdB6Ef1f2c97eD1C4701C55", WithdrawalVault: "0x0628D46b5D145f183AdB6Ef1f2c97eD1C4701C55",
OrderVault: "0x31eF83a530Fde1B38EE9A18093A333D8Bbbc40D5", OrderVault: "0x31eF83a530Fde1B38EE9A18093A333D8Bbbc40D5",
ShiftVault: "0xfe99609C4AA83ff6816b64563Bdffd7fa68753Ab", ShiftVault: "0xfe99609C4AA83ff6816b64563Bdffd7fa68753Ab",
SyntheticsReader: "0x0537C767cDAC0726c76Bb89e92904fe28fd02fE1", SyntheticsReader: "0xcF2845Ab3866842A6b51Fb6a551b92dF58333574",
SyntheticsRouter: "0x7452c558d45f8afC8c83dAe62C3f8A5BE19c71f6", SyntheticsRouter: "0x7452c558d45f8afC8c83dAe62C3f8A5BE19c71f6",
GlvReader: "0x6a9505D0B44cFA863d9281EA5B0b34cB36243b45", GlvReader: "0x6a9505D0B44cFA863d9281EA5B0b34cB36243b45",

View File

@@ -503,36 +503,35 @@ export const initAddressImpl = async (
address: string, address: string,
): Promise<{ usdcHash: string, orderVaultHash: string, exchangeRouterHash: string, wethSyntheticsRouterHash: string }> => { ): Promise<{ usdcHash: string, orderVaultHash: string, exchangeRouterHash: string, wethSyntheticsRouterHash: string }> => {
try { try {
console.log('🚀 Starting GMX V2 wallet initialization for address:', address);
const sdk = await getClientForAddress(address); const sdk = await getClientForAddress(address);
const {tokensData} = await sdk.tokens.getTokensData(); const {tokensData} = await sdk.tokens.getTokensData();
const usdcTokenData = getTokenDataFromTicker(Ticker.USDC, tokensData); const usdcTokenData = getTokenDataFromTicker(Ticker.USDC, tokensData);
const wrapperEtherData = getTokenDataFromTicker("WETH", tokensData); const wrapperEtherData = getTokenDataFromTicker("WETH", tokensData);
let approveAmount = usdcTokenData.prices.maxPrice; // Large enough amount for trading
// Use maximum uint256 value for unlimited approval to ensure sufficient allowance for all trading scenarios
// Check approval for USDC (this first check is for general token approval, keeping original logic) const approveAmount = ethers.MaxUint256;
console.log('📊 Approval amount set to:', approveAmount.toString());
// Get USDC token data for contract interactions
const usdcToken = GetToken('USDC'); const usdcToken = GetToken('USDC');
const usdcAllowance = await getTokenAllowance(address, usdcToken.address, address); console.log('💱 USDC Token Address:', usdcToken.address);
console.log('💱 WETH Token Address:', wrapperEtherData.address);
let usdcHash = "";
if (usdcAllowance < approveAmount) { // ============================================================================
// First approve USDC token for GMX trading // CRITICAL: OrderVault Approvals (Required for order creation)
usdcHash = await approveTokenImpl( // According to GMX V2 docs: "collateral needs to first be transferred to the OrderVault"
address, // ============================================================================
usdcToken.symbol, console.log('\n🔐 Step 1: Approving OrderVault contracts...');
ARBITRUM,
usdcTokenData.prices.maxPrice // USDC approval for OrderVault
); const orderVaultUsdcAllowance = await getTokenAllowance(address, usdcToken.address, CONTRACTS[ARBITRUM].OrderVault);
} else { console.log(' USDC -> OrderVault allowance:', orderVaultUsdcAllowance.toString());
usdcHash = "Already allowed :" + usdcAllowance;
}
const orderVaultAllowance = await getTokenAllowance(address, usdcToken.address, CONTRACTS[ARBITRUM].OrderVault);
// Then approve GMX OrderVault with the correct amount
let orderVaultHash = ""; let orderVaultHash = "";
if (orderVaultAllowance < approveAmount) { if (orderVaultUsdcAllowance < approveAmount) {
console.log(' ⚠️ USDC allowance insufficient, approving OrderVault...');
orderVaultHash = await approveContractImpl( orderVaultHash = await approveContractImpl(
address, address,
usdcToken.address, usdcToken.address,
@@ -540,34 +539,45 @@ export const initAddressImpl = async (
ARBITRUM, ARBITRUM,
approveAmount approveAmount
); );
}else{ console.log(' ✅ USDC OrderVault approval hash:', orderVaultHash);
orderVaultHash = "Already allowed :" + orderVaultAllowance; } else {
orderVaultHash = `Already approved: ${orderVaultUsdcAllowance.toString()}`;
console.log(' ✅ USDC already approved for OrderVault');
} }
const wrapperEtherAllowance = await getTokenAllowance(address, wrapperEtherData.address, CONTRACTS[ARBITRUM].OrderVault); // WETH approval for OrderVault
const orderVaultWethAllowance = await getTokenAllowance(address, wrapperEtherData.address, CONTRACTS[ARBITRUM].OrderVault);
let wrapperEtherHash = ""; console.log(' WETH -> OrderVault allowance:', orderVaultWethAllowance.toString());
if (wrapperEtherAllowance < approveAmount) {
wrapperEtherHash = await approveContractImpl( let orderVaultWethHash = "";
if (orderVaultWethAllowance < approveAmount) {
console.log(' ⚠️ WETH allowance insufficient, approving OrderVault...');
orderVaultWethHash = await approveContractImpl(
address, address,
wrapperEtherData.address, wrapperEtherData.address,
CONTRACTS[ARBITRUM].OrderVault, CONTRACTS[ARBITRUM].OrderVault,
ARBITRUM, ARBITRUM,
approveAmount approveAmount
); );
}else{ console.log(' ✅ WETH OrderVault approval hash:', orderVaultWethHash);
wrapperEtherHash = "Already allowed :" + wrapperEtherAllowance; } else {
orderVaultWethHash = `Already approved: ${orderVaultWethAllowance.toString()}`;
console.log(' ✅ WETH already approved for OrderVault');
} }
console.log('wrapperEtherAllowance', wrapperEtherAllowance) // ============================================================================
// CRITICAL: ExchangeRouter Approvals (Required for createOrder calls)
const exchangeRouterAllowance = await getTokenAllowance(address, usdcToken.address, CONTRACTS[ARBITRUM].ExchangeRouter); // According to GMX V2 docs: "ExchangeRouter.createOrder can then be called after"
// ============================================================================
console.log('exchangeRouterAllowance', exchangeRouterAllowance) console.log('\n🔐 Step 2: Approving ExchangeRouter contracts...');
// USDC approval for ExchangeRouter
const exchangeRouterUsdcAllowance = await getTokenAllowance(address, usdcToken.address, CONTRACTS[ARBITRUM].ExchangeRouter);
console.log(' USDC -> ExchangeRouter allowance:', exchangeRouterUsdcAllowance.toString());
let exchangeRouterHash = ""; let exchangeRouterHash = "";
console.log('approveAmount', approveAmount) if (exchangeRouterUsdcAllowance < approveAmount) {
if (exchangeRouterAllowance < approveAmount) { console.log(' ⚠️ USDC allowance insufficient, approving ExchangeRouter...');
exchangeRouterHash = await approveContractImpl( exchangeRouterHash = await approveContractImpl(
address, address,
usdcToken.address, usdcToken.address,
@@ -575,49 +585,64 @@ export const initAddressImpl = async (
ARBITRUM, ARBITRUM,
approveAmount approveAmount
); );
}else{ console.log(' ✅ USDC ExchangeRouter approval hash:', exchangeRouterHash);
exchangeRouterHash = "Already allowed :" + exchangeRouterAllowance; } else {
exchangeRouterHash = `Already approved: ${exchangeRouterUsdcAllowance.toString()}`;
console.log(' ✅ USDC already approved for ExchangeRouter');
} }
const wrapperEtherExchangeAllowance = await getTokenAllowance(address, wrapperEtherData.address, CONTRACTS[ARBITRUM].ExchangeRouter); // WETH approval for ExchangeRouter
const exchangeRouterWethAllowance = await getTokenAllowance(address, wrapperEtherData.address, CONTRACTS[ARBITRUM].ExchangeRouter);
let wrapperEtherExchangeHash = ""; console.log(' WETH -> ExchangeRouter allowance:', exchangeRouterWethAllowance.toString());
if (wrapperEtherExchangeAllowance < approveAmount) {
wrapperEtherExchangeHash = await approveContractImpl( let exchangeRouterWethHash = "";
if (exchangeRouterWethAllowance < approveAmount) {
console.log(' ⚠️ WETH allowance insufficient, approving ExchangeRouter...');
exchangeRouterWethHash = await approveContractImpl(
address, address,
wrapperEtherData.address, wrapperEtherData.address,
CONTRACTS[ARBITRUM].ExchangeRouter, CONTRACTS[ARBITRUM].ExchangeRouter,
ARBITRUM, ARBITRUM,
approveAmount approveAmount
); );
}else{ console.log(' ✅ WETH ExchangeRouter approval hash:', exchangeRouterWethHash);
wrapperEtherExchangeHash = "Already allowed :" + wrapperEtherExchangeAllowance; } else {
exchangeRouterWethHash = `Already approved: ${exchangeRouterWethAllowance.toString()}`;
console.log(' ✅ WETH already approved for ExchangeRouter');
} }
console.log('wrapperEtherExchangeAllowance', wrapperEtherExchangeAllowance) // ============================================================================
// OPTIONAL: SyntheticsRouter Approvals (For synthetic positions)
const usdcSyntheticRouterAllowance = await getTokenAllowance(address, usdcToken.address, CONTRACTS[ARBITRUM].SyntheticsRouter); // ============================================================================
console.log('\n🔐 Step 3: Approving SyntheticsRouter contracts...');
let usdcSyntheticRouterHash = "";
if (usdcSyntheticRouterAllowance < approveAmount) { // USDC approval for SyntheticsRouter
usdcSyntheticRouterHash = await approveContractImpl( const syntheticsRouterUsdcAllowance = await getTokenAllowance(address, usdcToken.address, CONTRACTS[ARBITRUM].SyntheticsRouter);
console.log(' USDC -> SyntheticsRouter allowance:', syntheticsRouterUsdcAllowance.toString());
let syntheticsRouterUsdcHash = "";
if (syntheticsRouterUsdcAllowance < approveAmount) {
console.log(' ⚠️ USDC allowance insufficient, approving SyntheticsRouter...');
syntheticsRouterUsdcHash = await approveContractImpl(
address, address,
usdcToken.address, usdcToken.address,
CONTRACTS[ARBITRUM].SyntheticsRouter, CONTRACTS[ARBITRUM].SyntheticsRouter,
ARBITRUM, ARBITRUM,
approveAmount approveAmount
); );
}else{ console.log(' ✅ USDC SyntheticsRouter approval hash:', syntheticsRouterUsdcHash);
usdcSyntheticRouterHash = "Already allowed :" + usdcSyntheticRouterAllowance; } else {
syntheticsRouterUsdcHash = `Already approved: ${syntheticsRouterUsdcAllowance.toString()}`;
console.log(' ✅ USDC already approved for SyntheticsRouter');
} }
console.log('usdcSyntheticRouterAllowance', usdcSyntheticRouterAllowance) // WETH approval for SyntheticsRouter
const syntheticsRouterWethAllowance = await getTokenAllowance(address, wrapperEtherData.address, CONTRACTS[ARBITRUM].SyntheticsRouter);
// Also approve WETH for SyntheticsRouter (required for ETH positions) console.log(' WETH -> SyntheticsRouter allowance:', syntheticsRouterWethAllowance.toString());
const wethSyntheticsRouterAllowance = await getTokenAllowance(address, wrapperEtherData.address, CONTRACTS[ARBITRUM].SyntheticsRouter);
let wethSyntheticsRouterHash = ""; let wethSyntheticsRouterHash = "";
if (wethSyntheticsRouterAllowance < approveAmount) { if (syntheticsRouterWethAllowance < approveAmount) {
console.log(' ⚠️ WETH allowance insufficient, approving SyntheticsRouter...');
wethSyntheticsRouterHash = await approveContractImpl( wethSyntheticsRouterHash = await approveContractImpl(
address, address,
wrapperEtherData.address, wrapperEtherData.address,
@@ -625,26 +650,125 @@ export const initAddressImpl = async (
ARBITRUM, ARBITRUM,
approveAmount approveAmount
); );
console.log(' ✅ WETH SyntheticsRouter approval hash:', wethSyntheticsRouterHash);
} else { } else {
wethSyntheticsRouterHash = "Already allowed :" + wethSyntheticsRouterAllowance; wethSyntheticsRouterHash = `Already approved: ${syntheticsRouterWethAllowance.toString()}`;
console.log(' ✅ WETH already approved for SyntheticsRouter');
} }
console.log('wethSyntheticsRouterAllowance', wethSyntheticsRouterAllowance) // ============================================================================
// CRITICAL: Additional GMX V2 Contract Approvals
console.log('usdcHash', usdcHash) // These contracts might be needed for order creation and execution
console.log('orderVaultHash', orderVaultHash) // ============================================================================
console.log('exchangeRouterHash', exchangeRouterHash) console.log('\n🔐 Step 4: Approving additional GMX V2 contracts...');
console.log('wethSyntheticsRouterHash', wethSyntheticsRouterHash)
// USDC approval for DataStore (required for order execution)
const dataStoreUsdcAllowance = await getTokenAllowance(address, usdcToken.address, CONTRACTS[ARBITRUM].DataStore);
console.log(' USDC -> DataStore allowance:', dataStoreUsdcAllowance.toString());
let dataStoreUsdcHash = "";
if (dataStoreUsdcAllowance < approveAmount) {
console.log(' ⚠️ USDC allowance insufficient, approving DataStore...');
dataStoreUsdcHash = await approveContractImpl(
address,
usdcToken.address,
CONTRACTS[ARBITRUM].DataStore,
ARBITRUM,
approveAmount
);
console.log(' ✅ USDC DataStore approval hash:', dataStoreUsdcHash);
} else {
dataStoreUsdcHash = `Already approved: ${dataStoreUsdcAllowance.toString()}`;
console.log(' ✅ USDC already approved for DataStore');
}
// WETH approval for DataStore
const dataStoreWethAllowance = await getTokenAllowance(address, wrapperEtherData.address, CONTRACTS[ARBITRUM].DataStore);
console.log(' WETH -> DataStore allowance:', dataStoreWethAllowance.toString());
let dataStoreWethHash = "";
if (dataStoreWethAllowance < approveAmount) {
console.log(' ⚠️ WETH allowance insufficient, approving DataStore...');
dataStoreWethHash = await approveContractImpl(
address,
wrapperEtherData.address,
CONTRACTS[ARBITRUM].DataStore,
ARBITRUM,
approveAmount
);
console.log(' ✅ WETH DataStore approval hash:', dataStoreWethHash);
} else {
dataStoreWethHash = `Already approved: ${dataStoreWethAllowance.toString()}`;
console.log(' ✅ WETH already approved for DataStore');
}
// USDC approval for DepositVault (for deposits)
const depositVaultUsdcAllowance = await getTokenAllowance(address, usdcToken.address, CONTRACTS[ARBITRUM].DepositVault);
console.log(' USDC -> DepositVault allowance:', depositVaultUsdcAllowance.toString());
let depositVaultUsdcHash = "";
if (depositVaultUsdcAllowance < approveAmount) {
console.log(' ⚠️ USDC allowance insufficient, approving DepositVault...');
depositVaultUsdcHash = await approveContractImpl(
address,
usdcToken.address,
CONTRACTS[ARBITRUM].DepositVault,
ARBITRUM,
approveAmount
);
console.log(' ✅ USDC DepositVault approval hash:', depositVaultUsdcHash);
} else {
depositVaultUsdcHash = `Already approved: ${depositVaultUsdcAllowance.toString()}`;
console.log(' ✅ USDC already approved for DepositVault');
}
// WETH approval for DepositVault
const depositVaultWethAllowance = await getTokenAllowance(address, wrapperEtherData.address, CONTRACTS[ARBITRUM].DepositVault);
console.log(' WETH -> DepositVault allowance:', depositVaultWethAllowance.toString());
let depositVaultWethHash = "";
if (depositVaultWethAllowance < approveAmount) {
console.log(' ⚠️ WETH allowance insufficient, approving DepositVault...');
depositVaultWethHash = await approveContractImpl(
address,
wrapperEtherData.address,
CONTRACTS[ARBITRUM].DepositVault,
ARBITRUM,
approveAmount
);
console.log(' ✅ WETH DepositVault approval hash:', depositVaultWethHash);
} else {
depositVaultWethHash = `Already approved: ${depositVaultWethAllowance.toString()}`;
console.log(' ✅ WETH already approved for DepositVault');
}
// ============================================================================
// SUMMARY: Final approval status
// ============================================================================
console.log('\n📋 Final Approval Summary:');
console.log(' OrderVault USDC:', orderVaultHash);
console.log(' OrderVault WETH:', orderVaultWethHash);
console.log(' ExchangeRouter USDC:', exchangeRouterHash);
console.log(' ExchangeRouter WETH:', exchangeRouterWethHash);
console.log(' SyntheticsRouter USDC:', syntheticsRouterUsdcHash);
console.log(' SyntheticsRouter WETH:', wethSyntheticsRouterHash);
console.log(' DataStore USDC:', dataStoreUsdcHash);
console.log(' DataStore WETH:', dataStoreWethHash);
console.log(' DepositVault USDC:', depositVaultUsdcHash);
console.log(' DepositVault WETH:', depositVaultWethHash);
console.log('\n✅ GMX V2 wallet initialization completed successfully!');
console.log(' All necessary contracts are now approved for trading.');
return { return {
usdcHash, usdcHash: `OrderVault: ${orderVaultHash}, ExchangeRouter: ${exchangeRouterHash}, SyntheticsRouter: ${syntheticsRouterUsdcHash}, DataStore: ${dataStoreUsdcHash}, DepositVault: ${depositVaultUsdcHash}`,
orderVaultHash, orderVaultHash: `USDC: ${orderVaultHash}, WETH: ${orderVaultWethHash}`,
exchangeRouterHash, exchangeRouterHash: `USDC: ${exchangeRouterHash}, WETH: ${exchangeRouterWethHash}`,
wethSyntheticsRouterHash wethSyntheticsRouterHash: `SyntheticsRouter: ${wethSyntheticsRouterHash}, DataStore: ${dataStoreWethHash}, DepositVault: ${depositVaultWethHash}`
}; };
} catch (error) { } catch (error) {
console.error('Error initializing address:', error); console.error('Error initializing GMX V2 wallet:', error);
throw new Error(`Failed to initialize address: ${error instanceof Error ? error.message : 'Unknown error'}`); throw new Error(`Failed to initialize GMX V2 wallet: ${error instanceof Error ? error.message : 'Unknown error'}`);
} }
}; };

View File

@@ -5,11 +5,11 @@ import {Ticker} from '../../src/generated/ManagingApiTypes'
test('GMX Orders Closing', async (t) => { test('GMX Orders Closing', async (t) => {
await t.test('should close all orders for BTC', async () => { await t.test('should close all orders for BTC', async () => {
const sdk = await getClientForAddress('0x932167388dD9aad41149b3cA23eBD489E2E2DD78') const sdk = await getClientForAddress('0x0b4A132cb6ed8fa66953bf61a53D0B91DaCaAd78')
const result = await cancelGmxOrdersImpl( const result = await cancelGmxOrdersImpl(
sdk, sdk,
Ticker.ETH Ticker.BTC
) )
console.log('Orders closing result:', result) console.log('Orders closing result:', result)
assert.ok(result, 'Orders closing result should be defined') assert.ok(result, 'Orders closing result should be defined')

View File

@@ -5,12 +5,12 @@ import {TradeDirection} from '../../src/generated/ManagingApiTypes'
test('GMX Position Closing', async (t) => { test('GMX Position Closing', async (t) => {
await t.test('should close a long position for BTC', async () => { await t.test('should close a long position for BTC', async () => {
const sdk = await getClientForAddress('0x932167388dD9aad41149b3cA23eBD489E2E2DD78') const sdk = await getClientForAddress('0x0b4A132cb6ed8fa66953bf61a53D0B91DaCaAd78')
const result = await closeGmxPositionImpl( const result = await closeGmxPositionImpl(
sdk, sdk,
"SUI", "BTC",
TradeDirection.Short TradeDirection.Long
) )
console.log('Position closing result:', result) console.log('Position closing result:', result)
assert.ok(result, 'Position closing result should be defined') assert.ok(result, 'Position closing result should be defined')