Skip to content

EVM: Add support for dynamic call intents#52

Merged
alavarello merged 22 commits into
evm/refactor-intents-with-operationsfrom
evm/dynamic_call_intents
Apr 30, 2026
Merged

EVM: Add support for dynamic call intents#52
alavarello merged 22 commits into
evm/refactor-intents-with-operationsfrom
evm/dynamic_call_intents

Conversation

@facuspagnuolo
Copy link
Copy Markdown
Member

@facuspagnuolo facuspagnuolo commented Jan 19, 2026

This PR introduces support for dynamic call intents, enabling calldata to be built on-chain from structured arguments instead of precomputed calldata.

Dynamic calls support:

  • Literal ABI-encoded arguments
  • Variable references resolved from previous intent results
  • Nested static calls whose return values can be used as arguments

The encoder reconstructs ABI calldata at execution time following the Aggregatable ABI Encoding approach proposed by OpenZeppelin, allowing intents to be composed, parameterized, and chained without relying on off-chain calldata generation. This unlocks more flexible and expressive intent definitions while preserving standard ABI semantics.

@facuspagnuolo facuspagnuolo self-assigned this Jan 19, 2026
@lgalende lgalende changed the base branch from main to evm/refactor-intents-with-operations April 10, 2026 18:08
@lgalende lgalende requested a review from alavarello April 10, 2026 19:36
@lgalende lgalende self-assigned this Apr 10, 2026
*/
struct DynamicCallOperation {
uint256 chainId;
bytes[] calls;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: bytes[] instead of DynamicCall[] to avoid stack-too-deep error

_transferFrom(transfer.token, operation.user, transfer.recipient, transfer.amount, isSmartAccount);
}

outputs = new bytes[](0);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could include the balance diff instead (as we do in swaps). If we decide to do so, I'd do it in a separate PR.

@lgalende lgalende marked this pull request as ready for review April 17, 2026 18:34
@lgalende lgalende added the do not merge Do not merge label Apr 20, 2026
Comment thread packages/evm/contracts/dynamic-calls/DynamicCallEncoder.sol Outdated
Comment thread packages/evm/contracts/dynamic-calls/DynamicCallEncoder.sol Outdated
Comment thread packages/evm/contracts/utils/BytesHelpers.sol
Comment thread packages/evm/contracts/utils/BytesHelpers.sol Outdated
Comment thread packages/evm/contracts/utils/BytesHelpers.sol Outdated
* The encoder follows standard ABI encoding rules, reconstructing
* the calldata heads and tails dynamically based on argument types.
*/
contract DynamicCallEncoder is IDynamicCallEncoder {
Copy link
Copy Markdown
Member

@lgalende lgalende Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should DynamicCallEncoder be a library instead of a contract?

If we keep it as a contract, we can update its reference in the Settler and change its behavior without redeploying the Settler. However, any changes to DynamicCallEncoder will probably be related to changes to DynamicCallTypes, and that would require redeploying the Settler anyway. So in practice, we’d likely have to redeploy the Settler anyways.

Also, note that the Settler will be upgradeable from now on.

Let me know what you think.

lgalende and others added 2 commits April 28, 2026 12:09
Co-authored-by: Facu Spagnuolo <facuspagnuolo@users.noreply.github.com>
@lgalende lgalende requested a review from alavarello April 29, 2026 05:18
// Skip the ABI-encoded offset and length of the outer `bytes` to point at the inner payload
assembly {
result := add(result, 64)
}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to sth like

Suggested change
}
// Skip the ABI-encoded offset and length of the outer `bytes` to point at the inner payload
result = abi.decode(result, (bytes));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought they were equivalent. I changed it in evm: optimize SmartAccountsHandlerHelpers call because it consumes less gas.
Let me know if I should roll it back.

@alavarello alavarello merged commit 5fed564 into evm/refactor-intents-with-operations Apr 30, 2026
4 checks passed
@alavarello alavarello deleted the evm/dynamic_call_intents branch April 30, 2026 15:30
@lgalende lgalende removed the do not merge Do not merge label Apr 30, 2026
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