Skip to content

Conversation

@legion2002
Copy link
Contributor

@legion2002 legion2002 commented Sep 3, 2025

Description

The PR adds a new calldata optimized execution mode to ERC7821 which allows you to batch calls to the same target address, without sending the redundant "to" variable in each call.
It also removes the value field, and assumes it will be 0 for all the calls. This is usually true for most DeFi batches, because everything uses WETH.

Even if the address(0) optimization is used in calldata, for each call there is still a 4 gas overhead.
With this PR, you can compress the calldata down to the theoretical optimal, this is specially useful when you want to do highly optimized self calls.

Note: The address(0) replacement is still available with the common to field passed.

Checklist

Ensure you completed all of the steps below before submitting your pull request:

  • Ran forge fmt?
  • Ran forge test?

Pull requests with an incomplete checklist will be thrown out.

@atarpara
Copy link
Collaborator

atarpara commented Sep 4, 2025

@legion2002 bounds checks for CallSansTo[] is missing.

@Vectorized
Copy link
Owner

i’ll work on this after i wake up. brb sleep now.

@legion2002
Copy link
Contributor Author

Thanks @atarpara, I maybe missing something, but doesn't solady intentionally skip these bounds checks, as mentioned here?

I was following the same pattern as how we treat the standard Call struct, do we do bounds check for that somewhere?

@Vectorized
Copy link
Owner

Vectorized commented Sep 5, 2025

@howydev @legion2002 @atarpara

Upon further thinking, this is actually more non-trivial than expected.

First, ERC7821 does not make any bounds checks. This is intentional (Solady tries to cater to max performance under expert use, freedom to bear footguns).

We expect that users who require checks use LibERC7579.decodeBatchAndOpData and LibERC7579.decodeBatch.

The reason why ERC7821 does not have the checks is because we expect that the executionData will be checked once via LibERC7579 somewhere else, when it matters. For Ithaca's case, that check is in the the _computeDigest functions, since in cases with both validation AND execution, the offsets of executionData can be different.

If we want to put this on ERC7821, we will need LibERC7579.isCompactBatch and LibERC7579.decodeCompactBatch.

Maybe can do this just on the Orchestrator, if all the intents will be done via the Orchestrator. I'm currently thinking if this is actually worth the effort. There is some overhead in detecting a compact representation, and re-encoding it. I'm thinking of simply abi.encode(address to, bytes[] calldatas). Also, the updated re-encoding function will need all the hardcore checks.

@legion2002 legion2002 changed the title feat: add new commonTo execution mode, for calldata optimization feat: add new calldata optimal execution mode Sep 30, 2025
@legion2002
Copy link
Contributor Author

@Vectorized @atarpara I have now updated the PR to remove the CallSansTo struct, and replace it with an array of data values.
So this should be the theoretical optimal calldata mode for most common DeFi interactions.

We could also do RLE encoding, but I think it won't have that big of a gas improvement, because 0 bytes are already priced 1/4th the value of non zero bytes.
We could think of adding this down the line, but for now I think this level of optimization should be good enough.

@Vectorized
Copy link
Owner

Vectorized commented Oct 1, 2025

@legion2002 I think i'll make a vendor subdirectory for ithaca for to unblock, without needing to change ERC7821. Else other vendors will need to update their ERC7821 related stuff.

Note: ERC7821 allows address(0) as an alias for address(this) in to, which makes it pretty good for RLE.

I'll go make a writeup on how EIP8022 could be made into a precompile. Ideally, we can braindead RLE everything.

@Vectorized Vectorized changed the title feat: add new calldata optimal execution mode ✨Add new calldata optimal execution mode for ERC7821 Oct 6, 2025
@Vectorized Vectorized changed the title ✨Add new calldata optimal execution mode for ERC7821 ✨ Add new calldata optimal execution mode for ERC7821 Oct 6, 2025
@Vectorized Vectorized changed the base branch from main to opt-7821-call-mode October 6, 2025 04:49
@Vectorized Vectorized merged commit 25af3d1 into Vectorized:opt-7821-call-mode Oct 6, 2025
9 of 11 checks passed
Vectorized pushed a commit that referenced this pull request Oct 28, 2025
* feat: add new commonTo execution mode, for calldata optimization

* feat: add address(0) replacement to new execution mode

* chore: use memory-safe-assembly tag

* chore: natspec

* fix: clean to address, before checking if it is 0

* feat: replace commonTo mode with calldata optimal mode

* chore: replace datas with dataArr
Vectorized added a commit that referenced this pull request Oct 28, 2025
* ✨ Add new calldata optimal execution mode for ERC7821 (#1485)

* feat: add new commonTo execution mode, for calldata optimization

* feat: add address(0) replacement to new execution mode

* chore: use memory-safe-assembly tag

* chore: natspec

* fix: clean to address, before checking if it is 0

* feat: replace commonTo mode with calldata optimal mode

* chore: replace datas with dataArr

* Refactor, fix ci

* Fix ci

* Fix _get

* Remove debug emits

* Update foundry.toml

* Add corrupted calldata test

---------

Co-authored-by: Tanishk Goyal <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants