Skip to content

fix: replace sender to timelock address during error decoding#775

Merged
ecPablo merged 7 commits into
mainfrom
ecpablo/fix-error-decoding-callproxy-replace
Jun 5, 2026
Merged

fix: replace sender to timelock address during error decoding#775
ecPablo merged 7 commits into
mainfrom
ecpablo/fix-error-decoding-callproxy-replace

Conversation

@ecPablo

@ecPablo ecPablo commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Timelock execution failures through a CallProxy were decoded with the wrong underlying revert. CI reported OnlyCallableByOwner() on WorkflowRegistry, but the real failure was NodeDoesNotSupportCapability(...).

Root cause

When mcms.WithCallProxy is used, the EVM executor sends the tx to the CallProxy, not the RBACTimelock. On failure, BuildExecutionError replayed the inner timelock call with From set to that execution address (the proxy). That synthetic path is not what happens on chain: CallProxy forwards to the timelock, and the target sees msg.sender as the timelock. Replaying from the proxy made Ownable targets revert with OnlyCallableByOwner() even when the real execution had already passed ownership and failed for a different reason.

Fix

EVM-only change in sdk/evm/execution_error.go: before underlying-call replay, resolve the real sender. If the execution address is a generated CallProxy (runtime bytecode fingerprint from bindings.CallProxy), extract the embedded timelock target and use it as From for eth_call replay. Otherwise behavior is unchanged.

AI Summary

This pull request enhances the handling of execution errors for EVM timelock transactions, especially when transactions are routed through a CallProxy contract. The main improvement is the ability to correctly identify and replay the underlying call from the true sender (the embedded timelock) even when a proxy is involved, providing more accurate revert reasons. The changes also add robust testing for CallProxy bytecode fingerprinting and sender resolution logic.

Enhancements to CallProxy handling and error replay:

  • Added logic to detect when an address is a CallProxy contract by matching its runtime bytecode against known prefix/suffix fingerprints, and to extract the embedded target (timelock) address from the bytecode. This allows the system to replay the underlying transaction as the correct sender, improving error diagnosis. (sdk/evm/execution_error.go) [1] [2]
  • Introduced the resolveUnderlyingCallSender function, which determines the true sender for replaying failed calls, handling both proxy and non-proxy cases. (sdk/evm/execution_error.go)

Testing and validation improvements:

  • Added comprehensive unit tests for CallProxy bytecode detection, target extraction, and sender resolution, including edge cases for incorrect bytecode and error fallbacks. (sdk/evm/execution_error_test.go)
  • Added integration-style tests to ensure that when a timelock operation fails through a CallProxy, the error replay uses the correct sender and the underlying revert reason is surfaced accurately. (sdk/evm/timelock_executor_test.go) [1] [2] [3]

Other changes:

  • Updated imports to support new logic and tests. (sdk/evm/execution_error.go, sdk/evm/execution_error_test.go, sdk/evm/timelock_executor_test.go) [1] [2] [3]

These changes significantly improve the reliability and transparency of error handling for timelock operations, especially in the presence of proxy contracts.

Signed-off-by: Pablo <pablo.estrada@smartcontract.com>

This comment was marked as resolved.

ecPablo added 3 commits June 4, 2026 13:21
Signed-off-by: Pablo <pablo.estrada@smartcontract.com>
Signed-off-by: Pablo <pablo.estrada@smartcontract.com>
Signed-off-by: Pablo <pablo.estrada@smartcontract.com>
@ecPablo ecPablo marked this pull request as ready for review June 5, 2026 14:36
@ecPablo ecPablo requested a review from a team as a code owner June 5, 2026 14:36
Copilot AI review requested due to automatic review settings June 5, 2026 14:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread sdk/evm/execution_error_test.go
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 5, 2026 14:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

gustavogama-cll
gustavogama-cll previously approved these changes Jun 5, 2026
Signed-off-by: Pablo <pablo.estrada@smartcontract.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@cl-sonarqube-production

Copy link
Copy Markdown

@ecPablo ecPablo merged commit 7da8a8e into main Jun 5, 2026
22 checks passed
@ecPablo ecPablo deleted the ecpablo/fix-error-decoding-callproxy-replace branch June 5, 2026 15:22
ecPablo pushed a commit that referenced this pull request Jun 5, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.46.0](v0.45.1...v0.46.0)
(2026-06-05)


### Features

* **canton:** integrate Canton support
([#613](#613))
([d1e8d62](d1e8d62))


### Bug Fixes

* replace sender to timelock address during error decoding
([#775](#775))
([7da8a8e](7da8a8e))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: app-token-issuer-ops-platform[bot] <275822481+app-token-issuer-ops-platform[bot]@users.noreply.github.com>
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