Skip to content

fix(transaction-controller): reject transactions that would deploy an empty contract#8744

Merged
matthewwalsh0 merged 1 commit intomainfrom
fix/prevent-empty-to-contract-deployment
May 8, 2026
Merged

fix(transaction-controller): reject transactions that would deploy an empty contract#8744
matthewwalsh0 merged 1 commit intomainfrom
fix/prevent-empty-to-contract-deployment

Conversation

@matthewwalsh0
Copy link
Copy Markdown
Member

@matthewwalsh0 matthewwalsh0 commented May 8, 2026

Explanation

TransactionController would silently classify a transaction with no recipient and no real bytecode as a contract deployment and broadcast it, creating an empty contract on-chain with any value permanently locked inside.

The root cause is that '0x' is a non-empty string, so if (data) truthiness checks in validateParamRecipient and determineTransactionType treated it as real deployment bytecode. validateParamRecipient also didn't recognize to === '' as missing.

Validation now treats to === '' as missing alongside '0x' / undefined, and both the validator and the type classifier require data.length > 2 before accepting a missing recipient as a legitimate deployment.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Tightens core transaction validation/type inference around contract deployments; could cause some previously-accepted malformed transactions to be rejected or reclassified, but the change is narrowly scoped and well-covered by tests.

Overview
Prevents accidental empty contract deployments by treating missing recipients (to of '', '0x', or undefined) as invalid unless data contains real deployment bytecode (more than just '0x').

Updates both validateTxParams/validateParamRecipient and determineTransactionType to require non-empty bytecode before allowing a missing to, adds targeted unit tests for the new edge cases, and records the fix in the transaction-controller changelog.

Reviewed by Cursor Bugbot for commit 7154b2f. Bugbot is set up for automated code reviews on this repo. Configure here.

@matthewwalsh0 matthewwalsh0 force-pushed the fix/prevent-empty-to-contract-deployment branch from 41d7192 to bf27407 Compare May 8, 2026 09:49
@matthewwalsh0 matthewwalsh0 force-pushed the fix/prevent-empty-to-contract-deployment branch from bf27407 to 0ac0c13 Compare May 8, 2026 09:53
When a transaction has no recipient (`to` is empty string, `'0x'`, or
`undefined`) and no real bytecode (`data` is empty or `'0x'`), the
TransactionController would silently classify it as a contract deployment
and broadcast it.

Two places contributed:
- `validateParamRecipient` treated `data === '0x'` as real bytecode
  because `'0x'` is a non-empty string and therefore truthy.
- `determineTransactionType` had the same `'0x'` truthiness bug.

Now:
- `validateParamRecipient` requires `data.length > 2` for the bytecode to
  count as real, treats `to === ''` as missing alongside `'0x'` and
  `undefined`, and rejects with a more descriptive error message.
- `determineTransactionType` only returns `deployContract` when there is
  real bytecode.
@matthewwalsh0 matthewwalsh0 force-pushed the fix/prevent-empty-to-contract-deployment branch from 0ac0c13 to 7154b2f Compare May 8, 2026 10:03
@matthewwalsh0 matthewwalsh0 marked this pull request as ready for review May 8, 2026 10:19
@matthewwalsh0 matthewwalsh0 requested review from a team as code owners May 8, 2026 10:19
@matthewwalsh0 matthewwalsh0 added this pull request to the merge queue May 8, 2026
Merged via the queue into main with commit 374c0ed May 8, 2026
366 checks passed
@matthewwalsh0 matthewwalsh0 deleted the fix/prevent-empty-to-contract-deployment branch May 8, 2026 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants