Decodes Uniswap Universal execute function in accordance with the Uniswap tehchnical reference in which translate binary into array.
- chai
- ethers
- mocha
- fs
- path
- util
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
const {
hasUniswapCommands,
uniswapCommands,
uniswapCommandArray,
uniswapInputArray,
uniswapDecodedInputArray,
uniswapV3DecodedInputArray,
uniswapDeadline,
uniswapFullDecodedInput,
} = require("./universalDecoder");
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"
Obtain Uniswap Uiversal Router Commands as an Array
- Call function
console.log(uniswapCommandArray(txnData));
- Expected Result Example
["0b", "08"]
Obtain Uniswap Uiversal Router Input Array as an Binary
- Call function
console.log(uniswapInputArray(txnData));
- Expected Result Example
[
"0x0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000001aa535d3d0c000",
"0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000001aa535d3d0c00000000000000000000000000000000000000000000030b3ead9ce807fab959dd700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000002e7f808990638e9e67e1f00313037ede2362361",
]
Obtain Uniswap Uiversal Router Input Decoded Array
- Call function
console.log(uniswapDecodedInputArray(txnData));
- Expected Result Example
[
'0x0000000000000000000000000000000000000001',
7500000000000000n,
58878075174672152174894551n,
[
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
'0x02e7f808990638e9e67e1f00313037ede2362361'
],
false
]
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 ]
]
Obtain Uniswap Uiversal Router Deadline
- Call function
console.log(uniswapDeadline(txnData));
- Expected Result Example
1674344111n
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
}
- 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();
- Run the program
$ node example.js