Reducing gas costs for L2 users by optimising calldata.
Transaction fees on L2s like Optimism and Arbitrum involve paying the calldata gas costs for the batch submission on L1. And it accounts for good amount of gas fees.
For example, breakup of $4.19 Uniswap Trade on Arbitrum (explorer):
- L1 Fixed Cost: $1.77
- L1 Calldata Cost: $2.30
- L2 Computation: $0.12
You can see that, the calldata cost is over 50%.
On L1, calldata is not compact because decoding costs would be more. But on L2, where calldata is costly while computation is cheaper, calldata can be encoded in a compact way, without much worring about decoding costs. Now there are a lot of ways to do that, which might cause security as well as compatibility issues. This document proposes a way to do that.
- Function compact selectors are 1 byte.
- Parameters are closedly packed.
- Normal solidity functions (according to ABI spec) should still be exposted to allow other contracts to CALL.
- It is only intended an EOA to use such route to interact with contract using a compact calldata.
TODO: think about compact dynamic length stuff
It is possible that a compact calldata might collide with the normal calldata. It should be ensured that the compact selector should not collide with any function selector's first byte.
If the selector byte is
BURN_SELECTOR
wouldn't it be better for the calling EOA to encode the calldata packed? That is, wouldn't it make more sense for line 45 to beCalldata.getUint96(1)
instead ofCalldata.getUint96(21)
?