Skip to content

isContract #1167

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

Closed
wants to merge 2 commits into from
Closed

isContract #1167

wants to merge 2 commits into from

Conversation

mirooon
Copy link
Contributor

@mirooon mirooon commented May 27, 2025

Which Jira task belongs to this PR?

Why did I implement it this way?

Checklist before requesting a review

Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)

  • I have checked that any arbitrary calls to external contracts are validated and or restricted
  • I have checked that any privileged calls (i.e. storage modifications) are validated and or restricted
  • I have ensured that any new contracts have had AT A MINIMUM 1 preliminary audit conducted on by <company/auditor>

Copy link
Contributor

coderabbitai bot commented May 27, 2025

Walkthrough

A new helper contract and interface are introduced to encapsulate the EXTCODECOPY operation for reading delegation info from contract bytecode. The core library is updated to use this helper via a new function. Test contracts are extended to validate correct and fallback behaviors when the helper fails or reverts.

Changes

Files / Grouped Files Change Summary
src/Helpers/ExtCodeHelper.sol Added new contract ExtcodeHelper with external view function getDelegationInfo to extract delegation prefix and delegate address from bytecode.
src/Interfaces/IExtcodeHelper.sol Added new interface IExtcodeHelper with getDelegationInfo(address) signature.
src/Libraries/LibAsset.sol Changed license to MIT, imported IExtcodeHelper, added isContractWithHelper using the helper contract, removed inline assembly delegation detection logic.
test/solidity/Libraries/LibAsset.t.sol Added RevertingHelper, updated LibAssetImplementer to use helper, introduced LibAssetImplementerWithRevHelper, and added LibAssetZkSyncFallbackTest for fallback and delegation tests.

Suggested labels

AuditNotRequired

Suggested reviewers

  • 0xDEnYO

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e7261fa and 11d24d7.

📒 Files selected for processing (1)
  • src/Libraries/LibAsset.sol (2 hunks)
🧰 Additional context used
🪛 GitHub Check: Olympix Integrated Security
src/Libraries/LibAsset.sol

[notice] 209-209:
Making an external call without a gas budget may consume all of the transaction's gas, causing it to revert. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/call-without-gas-budget


[failure] 209-209:
The contract uses low-level calls without properly verifying the input parameters, potentially leading to unexpected behavior or vulnerabilities. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/low-level-call-params-verified

🔇 Additional comments (2)
src/Libraries/LibAsset.sol (2)

1-1: LGTM! License change to MIT is appropriate.

The change from UNLICENSED to MIT license makes the code open source, which aligns with best practices for public repositories.


8-8: LGTM! Import is necessary for the new helper functionality.

The import of IExtcodeHelper interface is required for the new contract detection functionality and follows proper import conventions.


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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@lifi-action-bot lifi-action-bot marked this pull request as draft May 27, 2025 08:45
address helper
) internal view returns (bool) {
// exactly the same body you have now, but using `helper` instead of EXT_CODE_HELPER
(bool ok, bytes memory ret) = helper.staticcall(

Check notice

Code scanning / Olympix Integrated Security

Making an external call without a gas budget may consume all of the transaction's gas, causing it to revert. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/call-without-gas-budget Low

Making an external call without a gas budget may consume all of the transaction's gas, causing it to revert. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/call-without-gas-budget
address helper
) internal view returns (bool) {
// exactly the same body you have now, but using `helper` instead of EXT_CODE_HELPER
(bool ok, bytes memory ret) = helper.staticcall(

Check failure

Code scanning / Olympix Integrated Security

The contract uses low-level calls without properly verifying the input parameters, potentially leading to unexpected behavior or vulnerabilities. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/low-level-call-params-verified Critical

The contract uses low-level calls without properly verifying the input parameters, potentially leading to unexpected behavior or vulnerabilities. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/low-level-call-params-verified
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: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74b3346 and e7261fa.

📒 Files selected for processing (5)
  • src/Helpers/ExtCodeHelper.sol (1 hunks)
  • src/Interfaces/IExtcodeHelper.sol (1 hunks)
  • src/Libraries/LibAsset.sol (3 hunks)
  • src/Libraries/LibSwap.sol (2 hunks)
  • test/solidity/Libraries/LibAsset.t.sol (3 hunks)
🧰 Additional context used
🪛 GitHub Check: Olympix Integrated Security
src/Libraries/LibSwap.sol

[notice] 12-12:
Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast

src/Libraries/LibAsset.sol

[notice] 213-213:
Making an external call without a gas budget may consume all of the transaction's gas, causing it to revert. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/call-without-gas-budget


[failure] 213-213:
The contract uses low-level calls without properly verifying the input parameters, potentially leading to unexpected behavior or vulnerabilities. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/low-level-call-params-verified

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: run-unit-tests
🔇 Additional comments (10)
src/Interfaces/IExtcodeHelper.sol (1)

1-10: LGTM! Clean interface design.

The interface is well-documented and follows Solidity conventions. The function signature correctly defines the expected return values for delegation info extraction.

src/Libraries/LibSwap.sol (1)

35-36: Good integration of enhanced contract detection.

The migration from isContract to isContractWithHelper properly leverages the new EIP-7702 aware validation.

src/Libraries/LibAsset.sol (3)

1-1: License update acknowledged.

Changed from UNLICENSED to MIT license.


208-237: Well-implemented contract detection with EIP-7702 support.

The function correctly:

  • Uses staticcall for gas efficiency and safety
  • Validates return data length before decoding
  • Falls back to standard extcodesize check on failure
  • Handles delegated contracts via the DELEGATION_DESIGNATOR prefix

The static analysis warnings are false positives:

  • Gas budget warning: Not applicable to view functions
  • Parameter verification: Parameters are properly encoded with abi.encodeWithSelector
🧰 Tools
🪛 GitHub Check: Olympix Integrated Security

[notice] 213-213:
Making an external call without a gas budget may consume all of the transaction's gas, causing it to revert. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/call-without-gas-budget


[failure] 213-213:
The contract uses low-level calls without properly verifying the input parameters, potentially leading to unexpected behavior or vulnerabilities. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/low-level-call-params-verified


239-245: Good practice: Preserving original function for backward compatibility.

Keeping the original isContract function ensures existing code continues to work while new code can adopt the enhanced isContractWithHelper functionality.

test/solidity/Libraries/LibAsset.t.sol (5)

11-19: Good test helper implementation for simulating failure scenarios.

The RevertingHelper contract effectively simulates the behavior when EXTCODECOPY is not supported, allowing thorough testing of the fallback mechanism.


22-26: Well-structured dependency injection for the helper contract.

The modifications properly implement dependency injection for the ExtcodeHelper, making the contract more testable and flexible.

Also applies to: 61-63


68-72: Correct test setup with proper deployment order.

The ExtcodeHelper is correctly deployed and injected into the LibAssetImplementer.


198-208: Good test contract design for flexible helper testing.

The generic helper address allows testing with different IExtcodeHelper implementations, particularly the RevertingHelper.


210-252: Comprehensive fallback mechanism testing.

Excellent test coverage for the fallback behavior when the ExtcodeHelper fails. The tests effectively verify that:

  1. Contract detection falls back to extcodesize for regular contracts
  2. EOAs are correctly identified when the helper reverts
  3. The delegation code path is bypassed when the helper fails

The test names and assertions clearly communicate the expected behavior.

Comment on lines +14 to +19
assembly {
// buf layout at buf+0x20: [ prefix:3 | delegate:20 ]
let ptr := add(buf, 0x20)
prefix := mload(ptr) // loads first 32 bytes, high-order 3 bytes are our prefix
delegate := shr(96, mload(add(ptr, 3))) // loads next 32 bytes, shift right 96 bits to drop padding
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix unsafe memory access when extracting delegate address.

The current implementation reads past the buffer boundary. When mload(add(ptr, 3)) is called, it reads 32 bytes starting from offset 3, but the buffer only contains 23 bytes. This reads 12 bytes of potentially uninitialized memory.

Apply this safer alternative:

 assembly {
     // buf layout at buf+0x20: [ prefix:3 | delegate:20 ]
     let ptr := add(buf, 0x20)
-    prefix := mload(ptr) // loads first 32 bytes, high-order 3 bytes are our prefix
-    delegate := shr(96, mload(add(ptr, 3))) // loads next 32 bytes, shift right 96 bits to drop padding
+    let data := mload(ptr) // loads 32 bytes safely (23 bytes data + 9 bytes zero padding)
+    prefix := data // automatically takes first 3 bytes when casting to bytes3
+    // Extract delegate by removing 3-byte prefix and aligning to address
+    delegate := shr(96, shl(24, data))
 }

Alternatively, use masking to ensure clean extraction:

delegate := and(shr(24, data), 0xffffffffffffffffffffffffffffffffffffffff)
🤖 Prompt for AI Agents
In src/Helpers/ExtCodeHelper.sol between lines 14 and 19, the assembly code
reads 32 bytes starting at an offset that causes it to access memory beyond the
buffer boundary, leading to unsafe memory access. To fix this, avoid loading
memory starting at an unaligned offset; instead, load the 32 bytes starting at
the buffer pointer and then use bit shifting and masking to extract the delegate
address safely within the buffer limits. Replace the current mload and shr
operations with a single mload followed by a shift right by 24 bits and an and
mask with 0xffffffffffffffffffffffffffffffffffffffff to cleanly extract the
20-byte delegate address without reading out-of-bounds memory.

Comment on lines 11 to 12
address internal constant EXT_CODE_HELPER =
address(uint160(uint256(keccak256("EXT_CODE_HELPER"))));
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Helper address inconsistency between libraries.

This computes the helper address as keccak256("EXT_CODE_HELPER"), but LibAsset.sol uses a fixed address 0x7000000000000000000000000000000000000000. These will reference different contracts, causing the validation to fail.

Align with LibAsset's approach:

-address internal constant EXT_CODE_HELPER =
-    address(uint160(uint256(keccak256("EXT_CODE_HELPER"))));
+address internal constant EXT_CODE_HELPER =
+    0x7000000000000000000000000000000000000000;

Note: The static analysis warning about narrowing downcast is a false positive - casting uint256 to uint160 for address creation is standard practice.

📝 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.

Suggested change
address internal constant EXT_CODE_HELPER =
address(uint160(uint256(keccak256("EXT_CODE_HELPER"))));
address internal constant EXT_CODE_HELPER =
0x7000000000000000000000000000000000000000;
🧰 Tools
🪛 GitHub Check: Olympix Integrated Security

[notice] 12-12:
Performing a narrowing downcast may result in silent overflow due to bit truncation. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/unsafe-downcast

🤖 Prompt for AI Agents
In src/Libraries/LibSwap.sol at lines 11-12, the helper address is computed
using keccak256("EXT_CODE_HELPER"), which differs from the fixed address used in
LibAsset.sol (0x7000000000000000000000000000000000000000). To fix this, replace
the computed address with the fixed address literal used in LibAsset.sol to
ensure both libraries reference the same helper contract and avoid validation
failures.

@0xDEnYO 0xDEnYO closed this Jun 24, 2025
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.

2 participants