GithubHelp home page GithubHelp logo

Comments (11)

daqingsu19 avatar daqingsu19 commented on July 20, 2024

figured out...format issue. this works:
_referralCode=bytes.fromhex('0000000000000000000000000000000000000000000000000000000000000000'),
_callbackTarget='0x0000000000000000000000000000000000000000'

from gmx-contracts.

daqingsu19 avatar daqingsu19 commented on July 20, 2024

txn was mined but still got error:
https://arbiscan.io/tx/0x9fde90302e8e46705781e295ead6fe9d41ce3316fd93c9968eeccf6bde78d8b3
this is how i call the function:
createIncreasePosition(
_path=[gmx.usdc, gmx.weth],
_indexToken=gmx.weth,
_amountIn= 10000000,
_minOut= 0,
_sizeDelta= 10000000000000000000000000000000,
_isLong= True,
_acceptablePrice= 1698660740000000000000000000000000,
_executionFee= 100000000000000,
_referralCode= '0x0000000000000000000000000000000000000000000000000000000000000000',
_callbackTarget= '0x0000000000000000000000000000000000000000').buildTransaction({ "gas": 10000000,
"maxFeePerGas": "0x3b9aca00",
"maxPriorityFeePerGas": "0x12a05f200",
"nonce": gmx.web3.eth.getTransactionCount(gmx.account.address),
'from': gmx.account.address})

to use 10 usdc to open long eth position

from gmx-contracts.

daqingsu19 avatar daqingsu19 commented on July 20, 2024

@vianiGa can you take a look?

from gmx-contracts.

RoscoeTheDog avatar RoscoeTheDog commented on July 20, 2024

bump did you figure this out? Trying to essentially do the same on web3 python. I'm running into web3.exceptions.ContractLogicError: execution reverted: val when at estimated_gas = tx.estimate_gas({ 'from': MY_ADDRESS })

def increase_position(base_address, quote_address, direction, amount, slippage=0.5):
    # normalize direction param
    direction = str.lower(direction)

    create_increase_position_abi = abi.arb.gmx.positionRouter.abi  # ABI for the `createIncreasePosition` function
    position_router_contract = w3.eth.contract(address=abi.arb.gmx.positionRouter.address, abi=create_increase_position_abi)

    acceptable_price = 0
    try:
        for s in fetch_tickers([base_address, quote_address]):
            if s.get('tokenAddress') == base_address:
                acceptable_price = int(float(s.get('maxPrice')) * (1 + slippage/100))
    except Exception as e:
        print('failed to fetch tickers, aborting', print(e))
        return None

    params = {
        '_path': [quote_address],  # Make sure this is a list.
        '_indexToken': base_address,
        '_amountIn': w3.to_wei(amount, 'mwei'),
        '_minOut': 0,
        '_sizeDelta': int(amount * (10 ** 30)),
        '_isLong': True if direction == 'long' else False,  # Convert this directly to a bool here
        '_acceptablePrice': acceptable_price,
        '_executionFee': position_router_contract.functions.minExecutionFee().call(),
        '_referralCode': w3.to_bytes(text='0').rjust(32, b'\0'),
        '_callbackTarget': '0x0000000000000000000000000000000000000000'
    }

    tx = position_router_contract.functions.createIncreasePosition(
        params['_path'],
        params['_indexToken'],
        params['_amountIn'],
        params['_minOut'],
        params['_sizeDelta'],
        params['_isLong'],
        params['_acceptablePrice'],
        params['_executionFee'],
        params['_referralCode'],
        params['_callbackTarget']
    )
    estimated_gas = tx.estimate_gas({
        'from': MY_ADDRESS
    })
    buffered_gas = int(estimated_gas * 1.20)
    tx.build_transaction({
        'chainId': 42161,
        'gas': buffered_gas,
        'gasPrice': w3.eth.gas_price,
        'nonce': w3.eth.get_transaction_count(MY_ADDRESS),
    })

    signed_tx = w3.eth.account.sign_transaction(tx, MY_PRIVATE_KEY)
    return w3.eth.send_raw_transaction(signed_tx.rawTransaction).hex()
    
   if __name__ == '__main__':
    receipt = increase_position(base_address=token_contracts.arbitrum.ARB,      # token_contracts.arbitrum.ARB,
                                quote_address=token_contracts.arbitrum.USDC,     # token_contracts.arbitrum.USDC,
                                direction='long',
                                amount=5)

from gmx-contracts.

salparadi avatar salparadi commented on July 20, 2024

According to the contract, you need to send the _executionFee amount as the transaction value. So if _executionFee is 180000000000000, you'd need to send that amount of ETH. You can check the contract here. Look in PositionRouter.sol on line 306. I think you would just add 'value': 180000000000000 to your estimate_gas dict.

from gmx-contracts.

RoscoeTheDog avatar RoscoeTheDog commented on July 20, 2024

According to the contract, you need to send the _executionFee amount as the transaction value. So if _executionFee is 180000000000000, you'd need to send that amount of ETH. You can check the contract here. Look in PositionRouter.sol on line 306. I think you would just add 'value': 180000000000000 to your estimate_gas dict.

Thanks. Putting that in the dictionary did get me passed that error. But now its also erroring web3.exceptions.ContractLogicError: execution reverted: ERC20: transfer amount exceeds allowance. This is confusing. Does it mean the allowance for the symbol is not permitted yet or does it mean I not have enough etherium? I'm testing on the arbitrum network and have roughly $15 of ether to play with, I should be able to open a position with ~$2.00 worth when using the front-end UI.

    estimated_gas = tx.estimate_gas({
        'from': MY_ADDRESS,
        'value': position_router_contract.functions.minExecutionFee().call()
    })

from gmx-contracts.

RoscoeTheDog avatar RoscoeTheDog commented on July 20, 2024

Here's me trying to approve a token to the maxuint256, getting web3.exceptions.ContractLogicError: execution reverted: Governable: forbidden.

# 3. Approve the Router contract for the token and amount
def approve_router(token_address):
    # Assume a standard ERC20 approve function
    approve_abi = abi.arb.gmx.positionRouter.abi  # ABI for the `approve` function of an ERC20 token
    token_contract = w3.eth.contract(address=abi.arb.gmx.positionRouter.address, abi=approve_abi)
    tx = token_contract.functions.approve(token_address, MY_ADDRESS, 2**256 - 1)
    estimated_gas = tx.estimate_gas({'from': MY_ADDRESS})
    buffered_gas = int(estimated_gas * 1.20)
    tx = tx.build_transaction({
        'chainId': 42161,
        'gas': buffered_gas,
        'gasPrice': w3.eth.gas_price,
        'nonce': w3.eth.get_transaction_count(MY_ADDRESS),
    })

    signed_tx = w3.eth.account.sign_transaction(tx, MY_PRIVATE_KEY)
    return w3.eth.send_raw_transaction(signed_tx.rawTransaction).hex()

receipt = approve_router(token_contracts.arbitrum.ETH)

from gmx-contracts.

salparadi avatar salparadi commented on July 20, 2024

I think you're doing it backwards? Your token_contract is being set to the position router, when it should be the address of whatever token. Then you should be approving the position router as a spender for the token. I'm not sure if your approve abi is correct either, not sure how you have that defined but it appears to be the abi of the position router?

from gmx-contracts.

RoscoeTheDog avatar RoscoeTheDog commented on July 20, 2024

Ah yea that was a chicken scratch mistake-- with labeling things incorrectly. I've fixed it but now you got me a bit confused.. Is it my wallet address or the position router contract's address passed for approve functions second argument? I am using the approve function from the positionRouter contract. You can see the function signature on arbiscan and says the "spender" is the second argument.

The positionRouter.abi is equivalent to the "abi" section of the contract 0xb87a436B93fFE9D75c5cFA7bAcFff96430b09868 found on arbiscan. Using web3, we serialize that data back into an object, then call the approve method and pass down the arguments as needed. Still confused if the second argument is my wallet or the contracts.. I've tried both and still get that execution reverted: Governable: forbidden error.

def approve_router(token_address):
    approve_abi = abi.arb.gmx.positionRouter.abi
    position_router_contract = w3.eth.contract(address=abi.arb.gmx.positionRouter.address, abi=approve_abi)
    tx = position_router_contract.functions.approve(token_address, abi.arb.gmx.positionRouter.address, 2**256 - 1)
    estimated_gas = tx.estimate_gas({'from': MY_ADDRESS})
    buffered_gas = int(estimated_gas * 1.20)
    tx = tx.build_transaction({
        'chainId': 42161,
        'gas': buffered_gas,
        'gasPrice': w3.eth.gas_price,
        'nonce': w3.eth.get_transaction_count(MY_ADDRESS),
    })
    signed_tx = w3.eth.account.sign_transaction(tx, MY_PRIVATE_KEY)
    return w3.eth.send_raw_transaction(signed_tx.rawTransaction).hex()
    
receipt = approve_router(token_contracts.arbitrum.ETH)

I was able to allow plugins successfully, targeting the position router contract as the target and the code below.

def approve_plugin():
    approve_plugin_abi = abi.arb.gmx.router.abi # ABI for the `approvePlugin` function
    position_router_contract = w3.eth.contract(address=abi.arb.gmx.router.address, abi=approve_plugin_abi)
    tx = position_router_contract.functions.approvePlugin(abi.arb.gmx.positionRouter.address)
    estimated_gas = tx.estimate_gas({'from': MY_ADDRESS})
    buffered_gas = int(estimated_gas * 1.20)
    tx = tx.build_transaction({
        'chainId': 42161,
        'gas': buffered_gas,
        'gasPrice': w3.eth.gas_price,
        'nonce': w3.eth.get_transaction_count(MY_ADDRESS),
    })

    signed_tx = w3.eth.account.sign_transaction(tx, MY_PRIVATE_KEY)
    return w3.eth.send_raw_transaction(signed_tx.rawTransaction).hex()

Not sure what I'm doing wrong to allow spending ** shrug **

from gmx-contracts.

salparadi avatar salparadi commented on July 20, 2024

It's the approve that's wrong, it's still backwards. Above, you are calling approve on the router contract. You need to do the opposite. You need to call approve on the token contract, and pass the router address in as the first argument, and the amount as the second.

Would look something like this:

def approve_router(token_address):
    token_abi = abi.arb.erc20.abi (or whatever)
    token_contract = w3.eth.contract(address=token_address, abi=token_abi)
    tx = token_contract.functions.approve(abi.arb.gmx.positionRouter.address, 2**256 - 1)
    ....

from gmx-contracts.

RoscoeTheDog avatar RoscoeTheDog commented on July 20, 2024

Thank you for the guidance. I apologize I'm still a little new to web3 / smart contracts with python. I didn't think the token_address would have an ABI since upon viewing the contracts on arbiscan I could see there were basically 0 read/write functions for that token itself. I was unaware of native abi methods from erc20 standard.

I'm still running into another issue while trying to open positions :( I found this position manager library from a community member from https://github.com/SentryApe/sentry-gmx-python/blob/main/gmx.py . The snippit below is from it.

def send_tx(pk, addy, tx):
    signed_tx = w3.eth.account.sign_transaction(tx, pk)
    tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
    print(w3.to_hex(tx_hash))

def marketLong(coin, collateral, leverage, amount_in, price, slippage):
    print("Longboi")
    nonce = w3.eth.get_transaction_count(MY_ADDRESS)
    path = long_collateral_path(coin, collateral)
    execution_price = Web3.to_wei(str(price * (1.0 + slippage / 100.0)), "tether")
    is_long = True
    executionFee = Web3.to_wei( 300000, "gwei")
    referral = "0x0000000000000000000000000000000000000000000000000000000000000000"
    create_increase_position_abi = abi.arb.gmx.positionRouter.abi  # ABI for the `createIncreasePosition` function
    position_router_contract = w3.eth.contract(address=abi.arb.gmx.positionRouter.address, abi=create_increase_position_abi)
    if (coin == "eth" and collateral == "weth"):
        index_token = Web3.to_checksum_address(token_contracts.arbitrum.WETH.lower())
        min_out = 0
        amountIn = Web3.to_wei(amount_in, 'ether')
        size_delta = Web3.to_wei(str(leverage * amount_in * price *  (1.0 + slippage / 100.0)), 'tether')
        print(path, ", ",index_token, ", ",   ",", min_out, ", ", size_delta, ", ", is_long, ", ", execution_price, ", ", )
        longboi = position_router_contract.functions.createIncreasePosition(path, index_token, amountIn,  min_out,  size_delta,  is_long, execution_price, executionFee, referral, token_contracts.arbitrum.ADDRESS_ZERO).build_transaction({'chainId': 42161, 'nonce': nonce, 'value' : executionFee,'gasPrice': Web3.to_wei('1', 'gwei')})
        send_tx(MY_PRIVATE_KEY, position_router_contract, longboi)
    elif (coin == "eth" and (collateral == "usdt" or collateral == "usdc")):
        index_token = Web3.to_checksum_address(token_contracts.arbitrum.WETH.lower())
        min_out = Web3.to_wei(amount_in / (price * (1.0 + slippage / 100.0)) , 'ether')
        amountIn = Web3.to_wei(amount_in , 'mwei')
        size_delta = Web3.to_wei(str(leverage * amount_in  *  (1.0 + slippage / 100.0)), 'tether')
        print(path, ", ",index_token, ", ",   ",", min_out, ", ", size_delta, ", ", is_long, ", ", execution_price, ", ", )
        longboi = position_router_contract.functions.createIncreasePosition(path, index_token, amountIn,  min_out,  size_delta,  is_long, execution_price, executionFee, referral, token_contracts.arbitrum.ADDRESS_ZERO).build_transaction({'chainId': 42161, 'nonce': nonce, 'value' : executionFee,'gasPrice': Web3.to_wei('1', 'gwei')})
        send_tx(MY_PRIVATE_KEY, position_router_contract, longboi)
    elif (coin == "btc" and collateral == "btc"):
        index_token = Web3.to_checksum_address(token_contracts.arbitrum.BTC.lower())
        min_out = 0
        amountIn = Web3.to_wei(amount_in * 100, 'mwei')
        size_delta = Web3.to_wei(str(leverage * amount_in * price *  (1.0 + slippage / 100.0)), 'tether')
        print(path, ", ",index_token, ", ",   ",", min_out, ", ", size_delta, ", ", is_long, ", ", execution_price, ", ", )
        longboi = position_router_contract.functions.createIncreasePosition(path, index_token, amountIn,  min_out,  size_delta,  is_long, execution_price, executionFee, referral, token_contracts.arbitrum.ADDRESS_ZERO).build_transaction({'chainId': 42161, 'nonce': nonce, 'value' : executionFee,'gasPrice': Web3.to_wei('1', 'gwei')})
        send_tx(MY_PRIVATE_KEY, position_router_contract, longboi)
    elif (coin == "btc" and (collateral == "usdt" or collateral == "usdc")):
        index_token = Web3.to_checksum_address(token_contracts.arbitrum.BTC.lower())
        min_out = Web3.to_wei(amount_in / (price * (1.0 + slippage / 100.0)) * 100, 'mwei')
        amountIn = Web3.to_wei(amount_in , 'mwei')
        size_delta = Web3.to_wei(str(leverage * amount_in  *  (1.0 + slippage / 100.0)), 'tether')
        print(path, ", ",index_token, ", ",   ",", min_out, ", ", size_delta, ", ", is_long, ", ", execution_price, ", ", )
        longboi = position_router_contract.functions.createIncreasePosition(path, index_token, amountIn,  min_out,  size_delta,  is_long, execution_price, executionFee, referral, token_contracts.arbitrum.ADDRESS_ZERO).build_transaction({'chainId': 42161, 'nonce': nonce, 'value' : executionFee,'gasPrice': Web3.to_wei('1', 'gwei')})
        send_tx(MY_PRIVATE_KEY, position_router_contract, longboi)

When running script with receipt = marketLong('btc', 'usdc', 2.0, 5.50, 30000, 0.5), I get execution reverted: Router: plugin not approved

I've already called approvePluggin() on the router contract, passing in the positionRouter contract address as its argument. It should be approved unless I missed something else?

from gmx-contracts.

Related Issues (9)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.