Elnaril / uniswap-universal-router-decoder

Uniswap Universal Router Decoder and Encoder
https://www.buymeacoffee.com/elnaril
MIT License
187 stars 40 forks source link

I don't know what is wrong #22

Closed kthenurseone closed 1 year ago

kthenurseone commented 1 year ago
from uniswap_universal_router_decoder import FunctionRecipient, RouterCodec
from web3 import Account, Web3

private_key = "x"

chain_id = 56
rpc_endpoint = "https://binance.llamarpc.com"
w3 = Web3(Web3.HTTPProvider(rpc_endpoint))
account = Account.from_key(private_key)

amount_in = 1 * 10**27
min_amount_out = 1 * 10**18

token1 = Web3.to_checksum_address('0x55d398326f99059ff775485246999027b3197955')
token2 = Web3.to_checksum_address('0x643D89FBe699068353D24acf55Eb33366d57F533')

path = [token1, token2]

ur_address = Web3.to_checksum_address("0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad")
ur_abi = open("universalRouter.ABI").read()

codec = RouterCodec()

data, signable_message = codec.create_permit2_signable_message(
    token1,
    2**100,  # max = 2**160 - 1
    codec.get_default_deadline(),
    w3.eth.get_transaction_count("0x000000000022D473030F116dDEE9F6B43aC78BA3"),  # Permit2 nonce
    ur_address,  # The UR checksum address
    codec.get_default_deadline(),
    chain_id  # chain id
)

signed_message = Account.sign_message(signable_message, private_key=private_key)

encoded_input = (
        codec.encode.chain().permit2_permit(data, signed_message).v3_swap_exact_in(
        FunctionRecipient.SENDER,
        amount_in,  # in Wei
        w3.to_wei(0, 'gwei'),  # in Wei
        [
            token1,
            1,
            token2,
        ],
    )
        .build(codec.get_default_deadline())
)

trx_params = {
        "from": account.address,
        "to": ur_address,
        "gas": 300000,
        "maxPriorityFeePerGas": w3.eth.max_priority_fee,
        'maxFeePerGas': w3.to_wei(3, 'gwei'),
        # "maxFeePerGas": 100 * 10**9,
        "type": '0x2',
        "chainId": chain_id,
        "value": 0,
        "nonce": w3.eth.get_transaction_count(account.address),
        "data": encoded_input
}

decoded_trx_input = codec.decode.function_input(encoded_input)

print(decoded_trx_input)

raw_transaction = w3.eth.account.sign_transaction(trx_params, account.key).rawTransaction
trx_hash = w3.eth.send_raw_transaction(raw_transaction)
print(trx_hash.hex())

I bought the token manually and I got the data from tx and decode it. It looks like this: # (<Function execute(bytes,bytes[],uint256)>, {'commands': b'\n\x00', 'inputs': [(<Function PERMIT2_PERMIT(((address,uint256,uint256,uint256),address,uint256),bytes)>, {'struct': {'details': {'token': '0x55d398326f99059fF775485246999027B3197955', 'amount': 1461501637330902918203684832716283019655932542975, 'expiration': 1697657024, 'nonce': 0}, 'spender': '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD', 'sigDeadline': 1695066824}, 'data': b"\x920\xd6\xf4J\xf8a90\xda\xc1u\\\xcc'y\xcf\xa4\x13\x08\xdaR}\x9c\xf2\x00b\xbd\x19\xfb\x1c\xdbY(\x874\xb5\x8c\xf7\xc4\x0cC\xb1g\x03L\x1c\x08\xe0\r\x80\xa9\x8b\xc3i$E\xde\xa0-q\xc2}\x93\x1c"}), (<Function V3_SWAP_EXACT_IN(address,uint256,uint256,bytes,bool)>, {'recipient': '0x0000000000000000000000000000000000000001', 'amountIn': 1000000000000000000, 'amountOutMin': 1359931813892587514595, 'path': b"U\xd3\x982o\x99\x05\x9f\xf7uHRF\x99\x90'\xb3\x19yU\x00\x01\xf4d=\x89\xfb\xe6\x99\x06\x83S\xd2J\xcfU\xeb36mW\xf53", 'payerIsSender': True})], 'deadline': 1695066812})

I tried to encode the things on my side too and got the almost same input for my code: (<Function execute(bytes,bytes[],uint256)>, {'commands': b'\n\x00', 'inputs': [(<Function PERMIT2_PERMIT(((address,uint256,uint256,uint256),address,uint256),bytes)>, {'struct': {'details': {'token': '0x55d398326f99059fF775485246999027B3197955', 'amount': 1267650600228229401496703205376, 'expiration': 1695372715, 'nonce': 1}, 'spender': '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD', 'sigDeadline': 1695372715}, 'data': b'\x07\xb0\xd5F\x8f\x031a\x9d\xc5\x17\x05D\xfc\xfd\xeaO?\x15p\x95}*H3\xe1=\xc89\xb9E\x0eX\x7f\xefnG\xdc\xc7\x83\xd5\xc6)\xfe\x0f\x03\xe8r\xdd\xd6\xe3i\x94\xd8\x0cL-\x0c\x96?\xe3\xfa\xd8<\x1c'}), (<Function V3_SWAP_EXACT_IN(address,uint256,uint256,bytes,bool)>, {'recipient': '0x0000000000000000000000000000000000000001', 'amountIn': 1000000000000000000000000000, 'amountOutMin': 0, 'path': b"U\xd3\x982o\x99\x05\x9f\xf7uHRF\x99\x90'\xb3\x19yU\x00\x00\x01d=\x89\xfb\xe6\x99\x06\x83S\xd2J\xcfU\xeb36mW\xf53", 'payerIsSender': True})], 'deadline': 1695372715})

but it fails again and again.. I hope you guys know what should I do..

Here my successful tx(manual on uniswap): https://bscscan.com/tx/0x8fa2f34489edce758386692092efb9d9d00a317ac9c72631708540b487051749 Here my failed tx: https://bscscan.com/tx/0xfb62cbcc9f5fad8c5be485129e3105f485018941e2ad78f1dcbf889eba9a70c9

Elnaril commented 1 year ago

Hello @kthenurseone ! It looks like you're trying to buy for $1 billion! :)


<Function V3_SWAP_EXACT_IN(address,uint256,uint256,bytes,bool)>,
{
    'recipient': '0x0000000000000000000000000000000000000001',
    'amountIn': 1000000000000000000000000000,  # <--- That's a lot of B-USDT! ;)
    'amountOutMin': 0, 'path': b"U\xd3\x982o\x99\x05\x9f\xf7uHRF\x99\x90'\xb3\x19yU\x00\x00\x01d=\x89\xfb\xe6\x99\x06\x83S\xd2J\xcfU\xeb36mW\xf53",
    'payerIsSender': True
}

Let me know if it works after fixing that.

kthenurseone commented 1 year ago

Hello @kthenurseone ! It looks like you're trying to buy for $1 billion! :)

<Function V3_SWAP_EXACT_IN(address,uint256,uint256,bytes,bool)>,
{
    'recipient': '0x0000000000000000000000000000000000000001',
    'amountIn': 1000000000000000000000000000,  # <--- That's a lot of B-USDT! ;)
    'amountOutMin': 0, 'path': b"U\xd3\x982o\x99\x05\x9f\xf7uHRF\x99\x90'\xb3\x19yU\x00\x00\x01d=\x89\xfb\xe6\x99\x06\x83S\xd2J\xcfU\xeb36mW\xf53",
    'payerIsSender': True
}

Let me know if it works after fixing that.

Thank you for your response. I decreased the amount of busd to amount_in = 1 * 10**18 Now I have

(<Function execute(bytes,bytes[],uint256)>, {'commands': b'\n\x00', 'inputs': [(<Function PERMIT2_PERMIT(((address,uint256,uint256,uint256),address,uint256),bytes)>, {'struct': {'details': {'token': '0x55d398326f99059fF775485246999027B3197955', 'amount': 1267650600228229401496703205376, 'expiration': 1695388253, 'nonce': 1}, 'spender': '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD', 'sigDeadline': 1695388254}, 'data': b'D\'1\x81\xe6\x8e\x0eo\nj\xba\xba~@\x941\xa3\x0e\xfc\xc8\x82}\xed7Z\x17\xcc\xa6M\x0f\xf2\xd3\x19\xab\x89\'\xedB#\xf0\xc7^U\xbc\x15\x19\x93\x81"\xd0\xef\x18\x12\x1a+\x18\xf2,gy\x97\xeb\xbd\xc8\x1b'}), (<Function V3_SWAP_EXACT_IN(address,uint256,uint256,bytes,bool)>, {'recipient': '0x0000000000000000000000000000000000000001', 'amountIn': 1000000000000000000, 'amountOutMin': 0, 'path': b"U\xd3\x982o\x99\x05\x9f\xf7uHRF\x99\x90'\xb3\x19yU\x00\x00\x01d=\x89\xfb\xe6\x99\x06\x83S\xd2J\xcfU\xeb36mW\xf53", 'payerIsSender': True})], 'deadline': 1695388254})

and my tx is here: https://bscscan.com/tx/0xee681635071cae21c5b2d83c7f4bbdd1b55ce3ca12f81e61315c5e7258fede37

I get still same error :(

kthenurseone commented 1 year ago

I approved the permit2permit contract also (as you mentioned in the library) here my tx link: https://bscscan.com/tx/0x928b9637427fc4c7fbc2a8063ce3349d9c16b68267169fa4c5603abd70d3e507

and I approved the usdt here too: https://bscscan.com/tx/0xa85d710afc178d542452e28872ccf2ced3523ad7c76c19f1a54e63be91dccf3d

Elnaril commented 1 year ago

I approved the permit2permit contract also (as you mentioned in the library) here my tx link: https://bscscan.com/tx/0x928b9637427fc4c7fbc2a8063ce3349d9c16b68267169fa4c5603abd70d3e507

and I approved the usdt here too: https://bscscan.com/tx/0xa85d710afc178d542452e28872ccf2ced3523ad7c76c19f1a54e63be91dccf3d

If you use the PERMIT2 like you intend to do here, you don't need to do that. You just need to call the approve function of the BUSD contract with the PERMIT2 as the spender (not your wallet and not the UR)

Having said that, I had a quick look into your allowances and they seem good to me.

But you have another issue in your transaction: the V3 path is not correct. More accurately, the fee is not correct because it should be in basis points like 500 or 3000, not 1:

>>>path=b"U\xd3\x982o\x99\x05\x9f\xf7uHRF\x99\x90'\xb3\x19yU\x00\x00\x01d=\x89\xfb\xe6\x99\x06\x83S\xd2J\xcfU\xeb36mW\xf53"  # The path in the failed transaction
>>>codec.decode.v3_path("V3_SWAP_EXACT_IN", path)
('0x55d398326f99059fF775485246999027B3197955', 1, '0x643D89FBe699068353D24acf55Eb33366d57F533')  # The fee should be in basis points, 1% = 10000 basis points
>>>original_path = b"U\xd3\x982o\x99\x05\x9f\xf7uHRF\x99\x90'\xb3\x19yU\x00\x01\xf4d=\x89\xfb\xe6\x99\x06\x83S\xd2J\xcfU\xeb36mW\xf53"  # path in the successful transaction
>>>codec.decode.v3_path("V3_SWAP_EXACT_IN", original_path)
('0x55d398326f99059fF775485246999027B3197955', 500, '0x643D89FBe699068353D24acf55Eb33366d57F533')  # fee = 0.5%
kthenurseone commented 1 year ago

Brooo you are genious <3 Thank you so much it works now ! I just changed my code to like this:

encoded_input = (
        codec.encode.chain().permit2_permit(data, signed_message).v3_swap_exact_in(
        FunctionRecipient.SENDER,
        amount_in,  # in Wei
        w3.to_wei(0, 'gwei'),  # in Wei
        [
            token1,
            500,
            token2,
        ],
    )
        .build(codec.get_default_deadline())
)
Elnaril commented 1 year ago

You're welcome! And thank you for your interest in this lib! :)

kthenurseone commented 1 year ago

You're welcome! And thank you for your interest in this lib! :)

Thanks buddy. Now I have same issues I don't know why šŸ˜† It's really weird. It sold 1 time now it does the same thing.. Here I sold: https://bscscan.com/tx/0x7003e97d30ad87093a9bafd2b90fa11d7b57088639b7f7efe028a2ae9ed72c98 Now it gives error again šŸ˜†

Elnaril commented 1 year ago

Your permit2 nonce is still 1 in your last trx. It should be 2 ... ;)

Elnaril commented 1 year ago

also you can give big enough allowance and expiration once and for all, and then you don't need to call the permit2 fct in your trx

kthenurseone commented 1 year ago

I though I gave the allowance like 9999999999 tokens :D And my expiration is 2030 , How can I get my txs count with permit2 contract? I get nonce of permit2 as you mentioned in your code:

w3.eth.get_transaction_count(Web3.to_checksum_address("0x000000000022D473030F116dDEE9F6B43aC78BA3")), # Permit2 nonce

Should I delete permit2_permit(data, signed_message) from my code ?

Elnaril commented 1 year ago

You just call the permit2 allowance function ;) When I have some spare time I'll write a tutorial on how to use the permit2 with the UR. I'll provide the link in the announcement section of this repo and Twitter.

I'm closing this ticket as the issues are not in the lib.