Skip to content

Decodes Uniswap Universal execute function in accordance with the Uniswap tehchnical reference in which translate binary into array.

License

Notifications You must be signed in to change notification settings

HiroyukiNaito/uniswap-universal-decoder

 
 

Repository files navigation

Ethereum JavaScript License: MIT

Uniswap universal execute decoder

Decodes Uniswap Universal execute function in accordance with the Uniswap tehchnical reference in which translate binary into array.

Used libraries

  • chai
  • ethers
  • mocha
  • fs
  • path
  • util

Decoded functions


command value Decode Tested
0x(Empty) Use hasUniswapCommands function for avoiding Exception
0x00 V3_SWAP_EXACT_IN
0x01 V3_SWAP_EXACT_OUT
0x02 PERMIT2_TRANSFER_FROM
0x03 PERMIT2_PERMIT_BATCH
0x04 SWEEP
0x05 TRANSFER
0x06 PAY_PORTION
0x07 N/A N/A N/A
0x08 V2_SWAP_EXACT_IN
0x09 V2_SWAP_EXACT_OUT
0x0a PERMIT2_PERMIT
0x0b WRAP_ETH
0x0c UNWRAP_WETH
0x0d PERMIT2_TRANSFER_FROM_BATCH
0x0e N/A N/A N/A
0x0f N/A N/A N/A
0x10 SEAPORT
0x11 LOOKS_RARE_721
0x12 NFTX
0x13 CRYPTOPUNKS
0x14 LOOKS_RARE_1155
0x15 OWNER_CHECK_721
0x16 OWNER_CHECK_1155
0x17 SWEEP_ERC721
0x18 X2Y2_721
0x19 SUDOSWAP
0x1a NFT20
0x1b X2Y2_1155
0x1c FOUNDATION
0x1d N/A N/A N/A
0x1e N/A N/A N/A
0x1f N/A N/A N/A

NOTE: Uniswap Universal Router uses address constants internally, for example

    /// @dev Used as a flag for identifying the transfer of ETH instead of a token
    address internal constant ETH = address(0);

    /// @dev Used as a flag for identifying that msg.sender should be used, saves gas by sending more 0 bytes
    address internal constant MSG_SENDER = address(1);

    /// @dev Used as a flag for identifying address(this) should be used, saves gas by sending more 0 bytes
    address internal constant ADDRESS_THIS = address(2);
  • '0x0000000000000000000000000000000000000001' represents msg.sender (EOA) address itself
  • '0x0000000000000000000000000000000000000002' represents Universal Router Contract address itself

Usage

Importing module

const {
  hasUniswapCommands,
  uniswapCommands,
  uniswapCommandArray,
  uniswapInputArray,
  uniswapDecodedInputArray,
  uniswapV3DecodedInputArray,
  uniswapDeadline,
  uniswapFullDecodedInput,
} = require("./universalDecoder");

hasUniswapCommands function

Check whether it has Uiversal Router Commands

  • Call function
console.log(hasUniswapCommands(txnData));
  • Expected Result Example
true

Obtain Uniswap Uiversal Router Commands as an String

  • Call function
console.log(uniswapCommands(txnData));
  • Expected Result Example
"0x0b08"

uniswapCommandArray function

Obtain Uniswap Uiversal Router Commands as an Array

  • Call function
console.log(uniswapCommandArray(txnData));
  • Expected Result Example
["0b", "08"]

uniswapInputArray function

Obtain Uniswap Uiversal Router Input Array as an Binary

  • Call function
console.log(uniswapInputArray(txnData));
  • Expected Result Example
[
"0x0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000001aa535d3d0c000",
"0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000001aa535d3d0c00000000000000000000000000000000000000000000030b3ead9ce807fab959dd700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000002e7f808990638e9e67e1f00313037ede2362361",
]

uniswapDecodedInputArray function

Obtain Uniswap Uiversal Router Input Decoded Array

  • Call function
console.log(uniswapDecodedInputArray(txnData));
  • Expected Result Example
 [
  '0x0000000000000000000000000000000000000001',
  7500000000000000n,
  58878075174672152174894551n,
  [
    '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
    '0x02e7f808990638e9e67e1f00313037ede2362361'
  ],
  false
]

uniswapV3DecodedInputArray function

Obtain Uniswap Uiversal Router Input Decoded Array and Decoded Uniswap V3 Path

  • Call function
console.log(uniswapV3DecodedInputArray(txnData));
  • Expected Result Example
 [
  [ '0x0000000000000000000000000000000000000002', 34564726617685178n ],
  [
    '0x0000000000000000000000000000000000000001',
    10000000000000000000n,
    34564726617685178n,
    [
      '0x4d224452801aced8b2f0aebe155379bb5d594381', <-- Path Address
      3000n,                                        <-- Pool Fee
      '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'  <-- Path Address
    ],
    false
  ],
  [ '0x0000000000000000000000000000000000000001', 0n ]
]

uniswapDeadline function

Obtain Uniswap Uiversal Router Deadline

  • Call function
console.log(uniswapDeadline(txnData));
  • Expected Result Example
1674344111n

uniswapFullDecodedInput function

Obtain Uniswap Uiversal Router Fullout with above functions as a Dictionary

  • Call function
console.log(
util.inspect(uniswapFullDecodedInput(txnData), false, null, true)
);
  • Expected Result Example

Please see the reference of each array meanings

{
  contents: [
    {
      command: '0a',
      value: 'PERMIT2_PERMIT',
      inputType: [
        'tuple((address,uint160,uint48,uint48),address,uint256)',
        'bytes'
      ],
      decodedInput: [
        [
          [
            '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
            1461501637330902918203684832716283019655932542975n,
            1703502841n,
            0n
          ],
          '0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad',
          1700912641n
        ],
        '0x5f0511ba3fa712da37ec36ee9a253b62a633045c94307f1199fbbfbe5208e64e631a4964e505db3f74227bab7d03166084939b2e38ec7a312983cccee3a06fdf1c'
      ]
    },
    {
      command: '01',
      value: 'V3_SWAP_EXACT_OUT',
      inputType: [ 'address', 'uint256', 'uint256', 'bytes', 'bool' ],
      decodedInput: [
        '0x0000000000000000000000000000000000000002',
        2003000000000000000n,
        4185711450n,
        [
          '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
          500n,
          '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
        ],
        true
      ]
    },
    {
      command: '05',
      value: 'TRANSFER',
      inputType: [ 'address', 'address', 'uint256' ],
      decodedInput: [
        '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
        '0x37a8f295612602f2774d331e562be9e61b83a327',
        3000000000000000n
      ]
    },
    {
      command: '0c',
      value: 'UNWRAP_WETH',
      inputType: [ 'address', 'uint256' ],
      decodedInput: [
        '0x0000000000000000000000000000000000000001',
        2000000000000000000n
      ]
    }
  ],
  deadline: 1700911439n
}

Example program

  1. Change YOUR_NODE_RPC_WEBSOCKET_URL in example.js to your WSS PRC endpoint (Ex. ws://localhost:8546 )
const ethers = require("ethers");
const util = require("util");
const {
  hasUniswapCommands,
  uniswapCommands,
  uniswapCommandArray,
  uniswapInputArray,
  uniswapDecodedInputArray,
  uniswapV3DecodedInputArray,
  uniswapDeadline,
  uniswapFullDecodedInput,
} = require("./universalDecoder");

const wssUrl = "YOUR_RPC_WEBSOCKET_URL";
// const wssUrl = "ws://localhost:8546";

//Universal Router Contract Address
const router = "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD";
const compose = (...fns) => arg => fns.reduce((composed, f) => f(composed),arg);

const main = async () => {
    const provider = new ethers.WebSocketProvider(wssUrl);
    provider.on('pending', async (tx) => {
        const txnData = await provider.getTransaction(tx);
        txnData 
          ? (txnData.to == router && hasUniswapCommands(txnData['data'])) 
                ? compose(
                     console.log("uniswapCommands: ", util.inspect(uniswapCommands(txnData['data']), false, null, true )),
                     console.log("uniswapCommandArray: ", util.inspect(uniswapCommandArray(txnData['data']), false, null, true )),
                     console.log("uniswapInputArray: ", util.inspect(uniswapInputArray(txnData['data']), false, null, true)),
                     console.log("uniswapDecodedInputArray: ", util.inspect(uniswapDecodedInputArray(txnData['data']), false, null, true )),
                     console.log("uniswapV3DecodedInputArray: ", util.inspect(uniswapV3DecodedInputArray(txnData['data']), false, null, true )),
                     console.log("uniswapDeadline: ", util.inspect(uniswapDeadline(txnData['data']), false, null, true )),
                     console.log("uniswapFullDecodedInput: ", util.inspect(uniswapFullDecodedInput(txnData['data']), false, null, true))
                   )
                : null 
          : null ;
        }
    )
}
main();
  1. Run the program
$ node example.js

About

Decodes Uniswap Universal execute function in accordance with the Uniswap tehchnical reference in which translate binary into array.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%