-
-
Notifications
You must be signed in to change notification settings - Fork 41
feat: Add eip_7702_bytecode.zig #1754
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
WalkthroughA new module for handling EIP-7702 bytecode is introduced. It defines a structure encapsulating an Ethereum address, a magic byte sequence, and provides functions to create instances from an address or raw bytes, as well as to output the raw byte representation (currently unimplemented). Changes
Sequence Diagram(s)sequenceDiagram
participant Caller
participant EIP7702Bytecode
Caller->>EIP7702Bytecode: new(address)
EIP7702Bytecode-->>Caller: Instance with address
Caller->>EIP7702Bytecode: newRaw(bytes)
EIP7702Bytecode->>EIP7702Bytecode: Check length, copy address
EIP7702Bytecode-->>Caller: Instance with parsed address
Caller->>EIP7702Bytecode: raw(self)
EIP7702Bytecode-->>Caller: Empty byte slice (unimplemented)
Poem
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
3971f08
to
5050454
Compare
1039a50
to
2cf7744
Compare
2cf7744
to
2422867
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/evm/eip_7702_bytecode.zig
(1 hunks)
🔇 Additional comments (3)
src/evm/eip_7702_bytecode.zig (3)
1-1
: LGTM for the Address import.The import statement follows Zig conventions correctly.
5-7
: LGTM for the struct definition.The struct definition follows Zig conventions and appropriately represents EIP-7702 bytecode with an embedded address.
9-11
: LGTM for the address constructor.The constructor correctly creates a new instance from an address parameter.
@@ -0,0 +1,24 @@ | |||
const Address = @import("Address"); | |||
|
|||
pub const EIP7702_MAGIC_BYTES = [2]u8{ 0xE7, 0x02 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify the EIP-7702 magic bytes are correct.
Please confirm that 0xE7, 0x02
are the correct magic bytes according to the EIP-7702 specification.
🌐 Web query:
What are the correct magic bytes for EIP-7702 bytecode according to the official EIP-7702 specification?
💡 Result:
In the EIP-7702 specification, the "magic bytes" used to designate an Externally Owned Account (EOA) as a smart contract are 0xef0100
. This sequence is employed to set the code of an EOA to point to another address, effectively delegating its code execution. (eips.ethereum.org)
Specifically, the code of the EOA is set to 0xef0100 || address
, where address
is the target address to which the EOA's code is delegated. This delegation mechanism allows the EOA to execute code from the specified address, enabling functionalities typically associated with smart contracts. (eips.ethereum.org)
It's important to note that the 0xef
prefix is reserved for special purposes, as defined in EIP-3541, and is not used for general contract code. The 0x01
and 0x00
following it serve to identify the delegation and its version, respectively. (eips.ethereum.org)
Citations:
- 1: https://eips.ethereum.org/EIPS/eip-7702?utm_source=openai
- 2: https://eips.ethereum.org/EIPS/eip-7702?utm_source=openai
- 3: https://eips.ethereum.org/EIPS/eip-7702?utm_source=openai
Fix EIP-7702 magic bytes
The current declaration uses 0xE7, 0x02
, but the EIP-7702 spec defines a 3-byte magic sequence: 0xEF, 0x01, 0x00
. Please update in src/evm/eip_7702_bytecode.zig
:
- pub const EIP7702_MAGIC_BYTES = [2]u8{ 0xE7, 0x02 };
+ pub const EIP7702_MAGIC_BYTES = [3]u8{ 0xEF, 0x01, 0x00 };
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
pub const EIP7702_MAGIC_BYTES = [2]u8{ 0xE7, 0x02 }; | |
pub const EIP7702_MAGIC_BYTES = [3]u8{ 0xEF, 0x01, 0x00 }; |
🤖 Prompt for AI Agents
In src/evm/eip_7702_bytecode.zig at line 3, the magic bytes for EIP-7702 are
incorrectly set to 0xE7, 0x02. According to the EIP-7702 specification, the
correct magic bytes are a 3-byte sequence: 0xEF, 0x01, 0x00. Update the constant
EIP7702_MAGIC_BYTES to be a 3-element array with these values to accurately
reflect the specification.
pub fn raw(self: *const Self) []const u8 { | ||
_ = self; | ||
return &[_]u8{}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Implement the raw function to return proper EIP-7702 bytecode.
The function should return the complete EIP-7702 bytecode format: magic bytes followed by the address.
Apply this diff to implement the function:
pub fn raw(self: *const Self) []const u8 {
- _ = self;
- return &[_]u8{};
+ // TODO: This should return a properly allocated byte array
+ // For now, this is a placeholder that needs proper memory management
+ var result: [22]u8 = undefined;
+ result[0] = EIP7702_MAGIC_BYTES[0];
+ result[1] = EIP7702_MAGIC_BYTES[1];
+ @memcpy(result[2..22], &self.address);
+ return &result;
}
Note: This implementation has a memory management issue as it returns a reference to a local array. Consider using an allocator or requiring the caller to provide a buffer.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
pub fn raw(self: *const Self) []const u8 { | |
_ = self; | |
return &[_]u8{}; | |
} | |
pub fn raw(self: *const Self) []const u8 { | |
// TODO: This should return a properly allocated byte array | |
// For now, this is a placeholder that needs proper memory management | |
var result: [22]u8 = undefined; | |
result[0] = EIP7702_MAGIC_BYTES[0]; | |
result[1] = EIP7702_MAGIC_BYTES[1]; | |
@memcpy(result[2..22], &self.address); | |
return &result; | |
} |
🤖 Prompt for AI Agents
In src/evm/eip_7702_bytecode.zig at lines 21 to 24, the raw function currently
returns an empty byte slice and does not provide the required EIP-7702 bytecode.
To fix this, implement the function to return the full bytecode consisting of
the magic bytes followed by the address bytes. Since returning a reference to a
local array causes memory issues, modify the function to either accept an
allocator to allocate the bytecode buffer dynamically or require the caller to
provide a buffer for the bytecode, then fill and return the slice referencing
that buffer.
pub fn newRaw(bytes: []const u8) !Self { | ||
var address: Address.Address = undefined; | ||
if (bytes.len > 20) { | ||
@memcpy(&address, bytes[2..22]); | ||
} | ||
return Self.new(address); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix critical issues in newRaw function.
The function has several serious issues that need to be addressed:
- Undefined behavior: If
bytes.len <= 20
, the address remains uninitialized but is still used - Missing validation: No check that the first 2 bytes match
EIP7702_MAGIC_BYTES
- Potential out-of-bounds:
bytes[2..22]
could access beyond array bounds ifbytes.len < 22
- Unused error return: Function signature indicates it can fail but never returns an error
Apply this diff to fix the issues:
pub fn newRaw(bytes: []const u8) !Self {
- var address: Address.Address = undefined;
- if (bytes.len > 20) {
- @memcpy(&address, bytes[2..22]);
- }
- return Self.new(address);
+ // Validate minimum length for magic bytes + address
+ if (bytes.len < 22) {
+ return error.InvalidLength;
+ }
+
+ // Validate magic bytes
+ if (bytes[0] != EIP7702_MAGIC_BYTES[0] or bytes[1] != EIP7702_MAGIC_BYTES[1]) {
+ return error.InvalidMagicBytes;
+ }
+
+ // Extract address
+ var address: Address.Address = undefined;
+ @memcpy(&address, bytes[2..22]);
+ return Self.new(address);
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
pub fn newRaw(bytes: []const u8) !Self { | |
var address: Address.Address = undefined; | |
if (bytes.len > 20) { | |
@memcpy(&address, bytes[2..22]); | |
} | |
return Self.new(address); | |
} | |
pub fn newRaw(bytes: []const u8) !Self { | |
// Validate minimum length for magic bytes + address | |
if (bytes.len < 22) { | |
return error.InvalidLength; | |
} | |
// Validate magic bytes | |
if (bytes[0] != EIP7702_MAGIC_BYTES[0] or bytes[1] != EIP7702_MAGIC_BYTES[1]) { | |
return error.InvalidMagicBytes; | |
} | |
// Extract address | |
var address: Address.Address = undefined; | |
@memcpy(&address, bytes[2..22]); | |
return Self.new(address); | |
} |
🤖 Prompt for AI Agents
In src/evm/eip_7702_bytecode.zig around lines 13 to 19, the newRaw function has
multiple issues: it uses an uninitialized address if bytes.len is 20 or less,
lacks validation that the first two bytes match EIP7702_MAGIC_BYTES, risks
out-of-bounds access when slicing bytes[2..22] if bytes.len is less than 22, and
never returns an error despite the signature allowing it. Fix this by first
checking that bytes.len is at least 22, then validating the first two bytes
against EIP7702_MAGIC_BYTES, returning an error if validation fails. Only after
these checks, safely copy bytes[2..22] into address and return the new instance.
Ensure to return appropriate errors for invalid input or insufficient length.
Description
Added support for EIP-7702 bytecode handling with a new module that defines the magic bytes and provides functionality for creating and manipulating EIP-7702 bytecode. The implementation includes methods for creating new instances from an address or raw bytes, with proper memory handling.
Testing
The code has been reviewed for proper memory management and adherence to the EIP-7702 specification. The implementation correctly handles the magic bytes (0xE7, 0x02) and address extraction from raw bytecode.
Additional Information
Your ENS/address:
Summary by CodeRabbit