Deciphering SushiSwap’s RouteProcessor4: Encoding the Route Parameter
Deciphering SushiSwap’s RouteProcessor4: Encoding the Route Parameter
It’s safe to say that we live in an era of the UniversalRouter. Uniswap’s solution to aggregating trades across their V2 and V3 protocols. Instead of sending transactions to either a V2 or a V3 router, transactions can be encoded into a hex string and sent to the UniversalRouter and it does the swap magic for you, providing a single entry point for trades across protocols.

Sushiswap being Uniswap’s copycat cousin came up with its own version of the UniversalRouter and called it the RouteProcessor, but forgot to provide documentation on how to use it(their docs section it the emptiest you’ll ever see).
So to find out how the RouteProcessor worked, as anyone would do, I swapped 0.5 Matic to USDT on polygon(Tx) and checked the Input Data and took a deep dive into the transaction.

The function processRoute is the entry point for all trades, as seen above, it has 6 params, 5 of them are pretty self-explanatory as seen below.

The 6th one, well, not so much.
route bytes 0x0301ffff020155ff76bffc3cdd9d5fdbbc2ece4528ecce45047e0d500b1d8e8ef31e21c99d1db9a6444d3adf1270040d500b1d8e8ef31e21c99d1db9a6444d3adf12700055ff76bffc3cdd9d5fdbbc2ece4528ecce45047e010f2e359de7769c155b08dc5342aea80eb3fc8c64000bb8
To understand this, I dived into the contract, traced the transaction back, and found out the breakdown of the route parameter. The bytes data is first converted into a stream and then read from. The first read is an unsigned 8 bit integer know as the command code.

Image: 1
For the code we see there are 6 command codes, and our transaction has the code 3 for processNative. Diving deeper into this function, we see that this function is for wrapping native tokens before performing a swap.
Continuing this traceback we find the make up of the route as follows:
0x03->01->ffff->02->01->
55ff76bffc3cdd9d5fdbbc2ece4528ecce45047e->
0d500b1d8e8ef31e21c99d1db9a6444d3adf1270->
04->0d500b1d8e8ef31e21c99d1db9a6444d3adf1270->
00->
55ff76bffc3cdd9d5fdbbc2ece4528ecce45047e->
01->0f2e359de7769c155b08dc5342aea80eb3fc8c64
->000bb8
The rest are as well ternary statements:
- 01 is for the number of pool, and ffff is the share % from each pool. ffff to decimal is 65535 which is the max value of a uint16.

- 02 is the pool type.

Image: 2
The next three reads are:
- 01 for the direction 0->1 as we going from Matic to WMatic.
- 0x55ff76bffc3cdd9d5fdbbc2ece4528ecce45047e (USDT->WMatic Pair)
- 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270 (Wrapped Matic)

Now we have successfully wrapped Matic. Moving on to the swap part.
- 04 is another command code, from the image above related to command code we can see this is for processOnePool(Image 1).
- 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270 (Wrapped Matic)

- 00 again we have the pool type of the swap, as this was a Uniswap V2 transaction(Image 2).
- 0x55ff76bffc3cdd9d5fdbbc2ece4528ecce45047e (USDT->WMatic Pair) again we have the pair address
- 01 again the swap direction.
- 0x0f2e359de7769c155b08dc5342aea80eb3fc8c64 (to)
Then finally 000bb8 which in decimal is 3000 which corresponds to the pool fee in bips.(For some reason this is only appended in the v2 transaction)

Now moving on to how to encode this route is Javascript using Viem.
function encodeRoute(pair, warpMatic, to) {
var params = {
wrap: {
command: 3,
pools: 1,
share: 65535, //largest uint16?
poolType: 2, // for uniswap wrap native (got from contract)
direction: 1, // ->
pair: pair,
wrapMatic: warpMatic,
},
route: {
command: 4,
wrapMatic: warpMatic,
poolType: 0, // for uniswap v2
pair: pair,
direction: 1, // ->
},
};
var paramsArr = [
...Object.values(params.wrap).map((val) => {
if (!isAddress(val)) {
return toHex(val);
} else return val;
}),
...Object.values(params.route).map((val) => {
if (!isAddress(val)) {
return toHex(val);
} else return val;
}),
...[to, toHex(3000)],
];
var route = encodePacked(
[
//WRAPPING PARAMS
"uint8", // COMMAND CODE
"uint8", // NUMBER OF POOLS
"uint16", // SHARE IN POOL
"uint8", // POOL TYPE
"uint8", // DIRECTION
"address", // PAIR
"address", // WRAP MATIC
//ROUTE PARAMS
"uint8", //COMMAND
"address", // WRAP MATIC
"uint8", // POOL TYPE
"address", // PAIR
"uint8", // DIRECTION
"address", // TO:DESTINATION
"uint24", // FEE IN BIPS SETTING (0.3%)
],
paramsArr
);
return route;
}
And that’s it!!
메타데이터
- post_id
- 0434a52be5d2
- slug
- deciphering-sushiswaps-routeprocessor4-encoding-the-route-parameter-0434a52be5d2
- url
- https://medium.com/@umar.317/deciphering-sushiswaps-routeprocessor4-encoding-the-route-parameter-0434a52be5d2
- canonical_url
- https://medium.com/@umar.317/deciphering-sushiswaps-routeprocessor4-encoding-the-route-parameter-0434a52be5d2
- author_url
- https://medium.com/@umar.317
- status
- ok
- fetched_at
- 2026-07-24 05:27:41