Skip to content

[Flow EVM] Add strict hex-prefix check when parsing EVM addresses from String#8437

Merged
m-Peter merged 5 commits intomasterfrom
mpeter/evm-address-parsing-add-hex-prefix-check
Feb 22, 2026
Merged

[Flow EVM] Add strict hex-prefix check when parsing EVM addresses from String#8437
m-Peter merged 5 commits intomasterfrom
mpeter/evm-address-parsing-add-hex-prefix-check

Conversation

@m-Peter
Copy link
Collaborator

@m-Peter m-Peter commented Feb 20, 2026

Closes: #8436

Summary by CodeRabbit

  • Improvements

    • Stricter EVM address parsing: enforces 0x-prefix for 42-char inputs and normalizes decoding for more consistent handling.
  • Tests

    • Updated genesis state commitment expectations to new values.
    • Added expanded EVM address parsing tests covering valid and invalid inputs and error conditions.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 20, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Tightens EVM address parsing to require a true 0x prefix for 42-char inputs, updates related genesis/state commitment hex constants used in bootstrap tests, and adds tests for EVM.addressFromString (the test block is duplicated in-file).

Changes

Cohort / File(s) Summary
EVM stdlib
fvm/evm/stdlib/contract.cdc
Enforce both '0' and 'x' for 0x prefix on 42-character inputs; remove prior heuristic prefix handling and decode the resulting string with an explicit assertion for invalid 0x-prefixed inputs.
EVM tests
fvm/evm/evm_test.go
Add TestEVMaddressFromString covering valid/invalid EVM address forms and error messages; test block is duplicated (two identical declarations).
Bootstrap tests
engine/execution/state/bootstrap/bootstrap_test.go
Update expected state commitment byte values in two tests to match new genesis/state commitments.
Unittest genesis constants
utils/unittest/execution_state.go
Replace hardcoded GenesisStateCommitmentHex and genesisCommitHexByChainID return values with new hex strings used by tests.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

Bugfix

Suggested reviewers

  • janezpodhostnik
  • zhangchiqing
  • peterargue

Poem

🐰 I nibbled at hex and chased a sly prefix,
I now check both characters — no more tricks.
Commitments refreshed, tests hop in line,
Addresses trimmed tidy — all bytes align. 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Changes include state commitment updates and test duplicates unrelated to the hex-prefix fix objective, introducing unnecessary modifications beyond the primary issue scope. Remove duplicate TestEVMaddressFromString test and revert unrelated state commitment constant updates in bootstrap_test.go and execution_state.go to keep the PR focused on the hex-prefix check implementation.
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly matches the main code change: strict hex-prefix check when parsing EVM addresses, which is implemented in contract.cdc by checking both characters (asHex[0] == "0" && asHex[1] == "x").
Linked Issues check ✅ Passed The PR implements the exact fix proposed in #8436: changing prefix detection from asHex[1] == "x" to asHex[0] == "0" && asHex[1] == "x" in contract.cdc, preventing unintended character stripping and improving error handling.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mpeter/evm-address-parsing-add-hex-prefix-check

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter
Copy link

codecov-commenter commented Feb 20, 2026

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
utils/unittest/execution_state.go 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
fvm/evm/evm_test.go (1)

5011-5016: Dead Cadence assert in error-path test cases.

In all three error-path sub-tests (non-hex prefix, insufficient length, superfluous length), the Cadence script calls EVM.addressFromString(…) which panics before returning, so the subsequent assert(address.toString() == …) is unreachable dead code. The Go-side assertions (require.Error / require.ErrorContains) are the real validation and are correct. Consider removing the dead assert to avoid misleading readers.

♻️ Example: clean up the unreachable assert (shown for lines 5011–5016)
 access(all)
 fun main(): Bool {
     let address = EVM.addressFromString("2xE62340807933BCFC3b89FE121dDC0ae5DA9599a0")
-    assert(
-        address.toString() == "e62340807933bcfc3b89fe121ddc0ae5da9599a0",
-        message: "unexpected EVM address"
-    )
     return true
 }

Apply the same pattern to the other two error-path Cadence scripts.

Also applies to: 5050-5055, 5088-5093

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fvm/evm/evm_test.go` around lines 5011 - 5016, The Cadence error-path
sub-tests call EVM.addressFromString(...) which panics, so the subsequent
assert(address.toString() == "...") lines are unreachable and should be removed;
update the three failing Cadence snippets (the ones that call
EVM.addressFromString with non-hex prefix, insufficient length, and superfluous
length) by deleting the assert(address.toString() == "...") and its message so
the script only invokes EVM.addressFromString and lets the Go-side require.Error
/ require.ErrorContains validate the panic, leaving the rest of the test logic
intact.
fvm/evm/stdlib/contract.cdc (1)

243-244: Optional: align panic message format with existing pre-condition messages.

The existing pre-condition message (line 241) includes the function name, actual value, and expected range. The new panic message is terser and provides no context about the actual prefix characters.

💬 Suggested more informative message
-        if asHex.length == 42 && !(asHex[0] == "0" && asHex[1] == "x") {
-            panic("Invalid string with non-hex prefix")
+        if asHex.length == 42 && !(asHex[0] == "0" && asHex[1] == "x") {
+            panic("EVM.addressFromString(): Invalid string with non-hex prefix. Expected \"0x\", got \"".concat(asHex.slice(from: 0, upTo: 2)).concat("\""))
         }

Note: if you adopt this, the corresponding require.ErrorContains substring in evm_test.go would need to be updated.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fvm/evm/stdlib/contract.cdc` around lines 243 - 244, The panic message in the
conditional that checks asHex length/prefix is too terse; update the panic in
the block that checks `if asHex.length == 42 && !(asHex[0] == "0" && asHex[1] ==
"x")` to mirror the existing precondition style (include the function/operation
name, the actual `asHex` value or prefix, and the expected prefix "0x"), e.g. a
descriptive message like "<function/operation> invalid prefix: got '<actual
prefix>' for value '<asHex>'; expected '0x'"; also update the corresponding
`require.ErrorContains` expectation in `evm_test.go` to match the new substring.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@fvm/evm/evm_test.go`:
- Around line 5011-5016: The Cadence error-path sub-tests call
EVM.addressFromString(...) which panics, so the subsequent
assert(address.toString() == "...") lines are unreachable and should be removed;
update the three failing Cadence snippets (the ones that call
EVM.addressFromString with non-hex prefix, insufficient length, and superfluous
length) by deleting the assert(address.toString() == "...") and its message so
the script only invokes EVM.addressFromString and lets the Go-side require.Error
/ require.ErrorContains validate the panic, leaving the rest of the test logic
intact.

In `@fvm/evm/stdlib/contract.cdc`:
- Around line 243-244: The panic message in the conditional that checks asHex
length/prefix is too terse; update the panic in the block that checks `if
asHex.length == 42 && !(asHex[0] == "0" && asHex[1] == "x")` to mirror the
existing precondition style (include the function/operation name, the actual
`asHex` value or prefix, and the expected prefix "0x"), e.g. a descriptive
message like "<function/operation> invalid prefix: got '<actual prefix>' for
value '<asHex>'; expected '0x'"; also update the corresponding
`require.ErrorContains` expectation in `evm_test.go` to match the new substring.

@m-Peter m-Peter changed the title Add strict hex-prefix check when parsing EVM addresses from String [Flow EVM] Add strict hex-prefix check when parsing EVM addresses from String Feb 20, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@fvm/evm/stdlib/contract.cdc`:
- Around line 246-249: The assert for checking the string prefix (the asHex[0]
== "0" && asHex[1] == "x" check) uses the vague message "Invalid string with
non-hex prefix"; update it to follow the file-wide convention by prefixing the
message with the fully-qualified function name (e.g., "EVM.addressFromString():
") and include the expected prefix ("0x") and actual value context so callers
can identify the failure; locate the assertion in contract.cdc near the
addressFromString function and replace the message accordingly.

@m-Peter m-Peter force-pushed the mpeter/evm-address-parsing-add-hex-prefix-check branch from 80a177d to 3abd6ea Compare February 20, 2026 17:52
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
fvm/evm/evm_test.go (1)

4922-5112: Add a test case for valid-length strings containing non-hex characters.

The current suite covers length errors and prefix errors, but there is no test for a 40- or 42-character string that satisfies the length and prefix checks yet contains non-hex characters (e.g., "0xGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG"). Such input would pass the new asHex[0] == "0" && asHex[1] == "x" guard and the length precondition, but fail inside decodeHex() with a generic runtime error rather than a descriptive addressFromString message. A test case for this path documents the current behaviour and would catch any future regression.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fvm/evm/evm_test.go` around lines 4922 - 5112, Add a new subtest inside
TestEVMaddressFromString that supplies a 40- or 42-character input containing
non-hex characters (e.g., "0xGGGG...") to exercise EVM.addressFromString's path
where length/prefix checks pass but decodeHex fails; in that subtest call vm.Run
like the others, require output.Err is an error, and use require.ErrorContains
to check the error message includes a hex-related substring (e.g., "hex" or
"invalid") to document the current decodeHex failure behavior and catch
regressions; reference TestEVMaddressFromString, EVM.addressFromString and
decodeHex when locating where to add this case.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@fvm/evm/stdlib/contract.cdc`:
- Around line 246-249: Update the assert message in EVM.addressFromString() to
follow the file-wide convention: include the fully-qualified function name and a
clear expected value. Replace the current message "Invalid string with non-hex
prefix" with something like "EVM.addressFromString(): Invalid hex string prefix
— expected '0x'". Ensure this change is made for the assert that checks asHex[0]
== "0" && asHex[1] == "x" inside the addressFromString function.

---

Nitpick comments:
In `@fvm/evm/evm_test.go`:
- Around line 4922-5112: Add a new subtest inside TestEVMaddressFromString that
supplies a 40- or 42-character input containing non-hex characters (e.g.,
"0xGGGG...") to exercise EVM.addressFromString's path where length/prefix checks
pass but decodeHex fails; in that subtest call vm.Run like the others, require
output.Err is an error, and use require.ErrorContains to check the error message
includes a hex-related substring (e.g., "hex" or "invalid") to document the
current decodeHex failure behavior and catch regressions; reference
TestEVMaddressFromString, EVM.addressFromString and decodeHex when locating
where to add this case.

Copy link
Member

@turbolent turbolent left a comment

Choose a reason for hiding this comment

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

👌

@m-Peter m-Peter force-pushed the mpeter/evm-address-parsing-add-hex-prefix-check branch from 3abd6ea to 2f73b54 Compare February 22, 2026 12:00
@m-Peter m-Peter added this pull request to the merge queue Feb 22, 2026
Merged via the queue into master with commit 4f88a2a Feb 22, 2026
61 checks passed
@m-Peter m-Peter deleted the mpeter/evm-address-parsing-add-hex-prefix-check branch February 22, 2026 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FLO-2] Loose hex prefix check in EVM.addressFromString

7 participants