1

i'm getting list of data from web3.eth.filter('pending'), here i'm listening uniswap ETH router.

If i print one result of the list :

AttributeDict({'blockHash': None, 'blockNumber': None, 'from': '0xxxxx0f7548e88708f7F212AfA58d27293fxxxx', 'gas': 180961, 'gasPrice': 165687947255, 'maxFeePerGas': 165687947255, 'maxPriorityFeePerGas': 94000000, 'hash': HexBytes('0xa79d8760dd7e6dba5a0c1567bba3f3d5cd976aa1bb0478c878d0ac5f634d6cbc'), 'input': '0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006457ef7700000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000066fe4797754b1ebfb5b5f3c600000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000471a202f69d6e975da55e363dab1bdb2e86e0c0f', 'nonce': 551, 'to': '0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B', 'transactionIndex': None, 'value': 1000000000000000000, 'type': 2, 'accessList': [], 'chainId': 1, 'v': 0, 'r': HexBytes('0xf00649dc54b04986577d93a1f89ac0f80002c366e42179f4e3872bb74e5b2486'), 's': HexBytes('0x69f5375cb00778357013f34130aa1681feb7e8c259222c5675339fc2b32d543e')})

As it's pending i understand there is no blockHash/blockNumber. But my question here is how can i know wich token this users is transfering ? For example how can i know this users is swapping 1ETH for 1000$ ?

My guess would be to request last transactions of "from" and check what this address did last time. But i would be surprise that we don't already got this info somewhere here ?

1 Answer 1

2

You need to decode input params. You can do this if you know ABI of the smart-contract address. In your case it is not hard.

  1. Smart contract address: 0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B
  2. ABI (go to etherscan) to https://etherscan.io/address/0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B#code. Scroll down to 'Contract ABI' and copy it
  3. a little portion of code
In [1]: from web3 import Web3

In [2]: w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/<i use infura token>'))

In [3]: router_contract = w3.eth.contract(address='0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B', abi='<paste here abi>')

In [4]: input_params = '0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000
   ...: 0000000000000000000000000000006457ef7700000000000000000000000000000000000000000000000000000000000000020b0800000000000000000000000000000000000000000000000000000000000000000000000000
   ...: 00000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000
   ...: 0000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000de0b6
   ...: b3a764000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000
   ...: 0000000de0b6b3a7640000000000000000000000000000000000000000000066fe4797754b1ebfb5b5f3c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000
   ...: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000
   ...: 000000471a202f69d6e975da55e363dab1bdb2e86e0c0f'
In [5]: router_contract.decode_function_input(input_params)
Out[5]: 
(<Function execute(bytes,bytes[],uint256)>,
 {'commands': b'\x0b\x08',
  'inputs': [b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xe0\xb6\xb3\xa7d\x00\x00',
   b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xe0\xb6\xb3\xa7d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\xfeG\x97uK\x1e\xbf\xb5\xb5\xf3\xc6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0*\xaa9\xb2#\xfe\x8d\n\x0e\\O'\xea\xd9\x08<ul\xc2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G\x1a /i\xd6\xe9u\xdaU\xe3c\xda\xb1\xbd\xb2\xe8n\x0c\x0f"],
  'deadline': 1683484535})

In [6]: next_params = router_contract.decode_function_input(input_params)[1]['inputs']

We are now understand that it is params to call an execute method from universal router (https://blog.uniswap.org/permit2-and-universal-router). Let's read more docs from github repo to understand what is command https://github.com/Uniswap/universal-router#how-the-command-byte-is-structured.

'commands': b'\x0b\x08' means V2_SWAP_EXACT_IN. Input params for each command covered in docs https://docs.uniswap.org/contracts/universal-router/technical-reference#command. V2_SWAP_EXACT_IN accepts address, uint256, uint256, address[], bool as input parameters.

Let's take a look on next_params content in hex.

In [7]: Web3.to_hex(next_params[0])
Out[7]: '0x00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000de0b6b3a7640000'

In [8]: Web3.to_hex(next_params[1])
Out[8]: '0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000066fe4797754b1ebfb5b5f3c600000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000471a202f69d6e975da55e363dab1bdb2e86e0c0f'

The second one looks prominent. Let's use eth_abi to decode.

In [9]: from eth_abi import decode

In [10]: decode(['address', 'uint256', 'uint256', 'address[]', 'bool'], next_params[1])
Out[10]: 
('0x0000000000000000000000000000000000000001',
 1000000000000000000,
 31874876241889834629682557894,
 ('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
  '0x471a202f69d6e975da55e363dab1bdb2e86e0c0f'),
 False)

Voilà!

This transaction is an swap ecxact input value of Uniswap V2 liq pool.

Tokens:

Amounts:

  • Input amount: 1000000000000000000/10 ** 18 = 1 (WETH)

  • Minimum output: 31874876241889834629682557894/10 ** 18 = 31 874 876 241.889835 (Geke tokens)

About second input. Honestly, I don't find docs but running this gives at least understanding about input params structure.

In [48]: decode(['address', 'uint256'], next_params[0])
Out[48]: ('0x0000000000000000000000000000000000000002', 1000000000000000000)

Based on all list of commands from a full list: https://docs.uniswap.org/contracts/universal-router/technical-reference#wrap_eth

I bet that first command is the WRAP_ETH.

Using WRAP_ETH + V2_SWAP_EXACT_IN looks very logically when you sell ETH to Geke.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.