Skip to content

Conversation

@mirooon
Copy link
Contributor

@mirooon mirooon commented Apr 1, 2025

Which Jira task belongs to this PR?

LF-12880

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>

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 1, 2025

## Walkthrough
The changes introduce an enhanced error handling mechanism in the `Permit2Proxy` contract's `callDiamondWithEIP2612Signature` function, specifically addressing byte-based errors. A new abstract contract `BaseMockPermitToken` and a concrete implementation `MockPermitToken` are added for testing, which simulate various error conditions related to the permit functionality. This includes a custom error type, `CustomPermitError`, and multiple test functions that validate the expected behavior when the permit call fails under different scenarios. Additionally, an audit entry for the `Permit2Proxy` contract version 1.0.3 was added, documenting a completed audit.

## Changes

| File(s)                                  | Change Summary                                                                                                                                                                                                                                           |
|------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `src/Periphery/Permit2Proxy.sol`         | Introduced a new catch block in `callDiamondWithEIP2612Signature` to handle `bytes` errors by checking token allowance and reverting with the original error message if the allowance is insufficient.                                               |
| `test/solidity/Periphery/Permit2Proxy.t.sol` | Added abstract contract `BaseMockPermitToken` and concrete contract `MockPermitToken`, which includes an overridden `permit` function. Introduced multiple mock contracts for testing various revert scenarios and added several test functions to validate error handling. |
| `audit/auditLog.json`                     | Added a new audit entry "audit20250415" for the `Permit2Proxy` contract version 1.0.3, including auditor details, report path, and commit hash.                                                                                                         |

## Possibly related PRs
- lifinance/contracts#910: The main PR extends the error handling in `callDiamondWithEIP2612Signature` by adding a catch block for bytes errors and introduces comprehensive tests for various revert scenarios, building directly upon the error handling improvements introduced in the retrieved PR #910 for the same function in `Permit2Proxy.sol`.
- lifinance/contracts#912: The main PR enhances error handling in the `callDiamondWithEIP2612Signature` function of `Permit2Proxy.sol` by adding a `try-catch` block for `permit` calls and introduces extensive tests for various revert scenarios, while the retrieved PR #912 also modifies `Permit2Proxy.sol` but focuses primarily on replacing low-level ETH transfers with `SafeTransferLib.safeTransferETH` and adding a `try-catch` for `permit` calls without the detailed revert scenario tests; thus, both PRs modify the same function and contract with overlapping error handling improvements, making them related.

## Suggested labels
`AuditCompleted`

## 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 3943f8e and 33b7cdc.

📒 Files selected for processing (1)
  • audit/auditLog.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • audit/auditLog.json
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: run-unit-tests
  • GitHub Check: enforce-min-test-coverage

🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 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 April 1, 2025 12:39
@mirooon mirooon marked this pull request as ready for review April 1, 2025 12:41
@lifi-action-bot
Copy link
Collaborator

lifi-action-bot commented Apr 1, 2025

🤖 GitHub Action: Security Alerts Review 🔍

🟢 Dismissed Security Alerts with Comments
The following alerts were dismissed with proper comments:

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 Test functions fail to thoroughly test all aspects of contract constructors, potentially missing critical initialization issues. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/incomplete-constructor-tests
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: Although there isn’t a dedicated test for the constructor, the success of all other tests confirms that the constructor parameters are configured correctly

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 The contract contains functions with inadequate validation of input parameters, potentially leading to unexpected behavior or vulnerabilities. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/insufficient-parameter-assertion
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: Additional validation on the calldata is intentionally omitted because the permit and witness signature checks already verify that the calldata is both authorized and correctly constructed. Extra checks would only add gas overhead without improving security

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 The contract contains functions with inadequate validation of input parameters, potentially leading to unexpected behavior or vulnerabilities. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/insufficient-parameter-assertion
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: observation is valid, but it’s not a priority right now. Although we could add a check to ensure the values are not zero, they are already authenticated by their signature. This enhancement can be addressed in a future update

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 The contract contains functions with inadequate validation of input parameters, potentially leading to unexpected behavior or vulnerabilities. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/insufficient-parameter-assertion
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: observation is valid, but it’s not a priority right now. Although we could add a check to ensure the values are not zero, they are already authenticated by their signature. This enhancement can be addressed in a future update

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 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
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: it is safe in this context because the diamond contract is trusted

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 The contract is vulnerable to signature replay attacks, potentially allowing malicious actors to reuse valid signatures. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/signature-replay-attacks
🔹 Dismiss Reason: False positive
🔹 Dismiss Comment: replay protection is inherently provided by the underlying nonce mechanisms in the EIP-2612 and Permit2 implementations

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 The contract is vulnerable to signature replay attacks, potentially allowing malicious actors to reuse valid signatures. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/signature-replay-attacks
🔹 Dismiss Reason: False positive
🔹 Dismiss Comment: replay protection is inherently provided by the underlying nonce mechanisms in the EIP-2612 and Permit2 implementations

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 Using a payable fallback (including receive) with no access control may lead to inadvertently locked funds. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/no-access-control-payable-fallback
🔹 Dismiss Reason: False positive
🔹 Dismiss Comment: Funds can be withdrawn. Permit2Proxy inherits from WithdrawablePeriphery

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 Parameters passed to a constructor that are not validated for correct values may lead to contract creation in an undesired state. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/no-parameter-validation-in-constructor
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: This is a valid observation but can be skipped for now. The parameters are set during deployment by us, so there’s no immediate risk. It’s not urgent but can be improved later if needed

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 Parameters passed to a constructor that are not validated for correct values may lead to contract creation in an undesired state. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/no-parameter-validation-in-constructor
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: This is a valid observation but can be skipped for now. The addresses (_lifiDiamond and _permit2) are known contracts controlled or trusted by the deployerm so there’s no immediate risk. It’s not urgent but can be improved later

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 Parameters passed to a constructor that are not validated for correct values may lead to contract creation in an undesired state. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/no-parameter-validation-in-constructor
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: This is a valid observation but can be skipped for now. The addresses (_lifiDiamond and _permit2) are known contracts controlled or trusted by the deployerm so there’s no immediate risk. It’s not urgent but can be improved later

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 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
🔹 Dismiss Reason: False positive
🔹 Dismiss Comment: the narrowing cast is intentional and fits our nonce encoding scheme. The lower 8 bits extracted with uint8(start) are guaranteed to be within the valid range (0–255) by design

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 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
🔹 Dismiss Reason: False positive
🔹 Dismiss Comment: the cast from uint256 to uint248 is intentionally safe because start >> 8 is guaranteed not to exceed 2^248 - 1. so narrowing is safe

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 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
🔹 Dismiss Reason: Won't fix
🔹 Dismiss Comment: we are calling a trusted diamond contract that may need full gas to execute its bridging or swap logic. If the diamond call requires more gas than available, the transaction will naturally revert

🟢 View Alert - File: src/Periphery/Permit2Proxy.sol
🔹 Using a payable fallback (including receive) with no explicit functionality may indicate incomplete contract logic. For more information, visit: http://detectors.olympixdevsectools.com/article/web3-vulnerability/empty-payable-fallback
🔹 Dismiss Reason: False positive
🔹 Dismiss Comment: it's for receiving native token which later on can be withdrawn with WithdrawablePeriphery parent contract

No unresolved security alerts! 🎉

@lifi-action-bot lifi-action-bot marked this pull request as draft April 1, 2025 12:42
@lifi-action-bot
Copy link
Collaborator

lifi-action-bot commented Apr 1, 2025

Test Coverage Report

Line Coverage: 79.67% (2113 / 2652 lines)
Function Coverage: 84.90% ( 360 / 424 functions)
Branch Coverage: 47.92% ( 254 / 530 branches)
Test coverage (79.67%) is above min threshold (76%). Check passed.

@mirooon mirooon marked this pull request as ready for review April 1, 2025 14:14
0xDEnYO
0xDEnYO previously approved these changes Apr 7, 2025
@0xDEnYO 0xDEnYO dismissed their stale review April 7, 2025 02:31

erroneous approval

0xDEnYO
0xDEnYO previously approved these changes Apr 7, 2025
@lifi-action-bot lifi-action-bot changed the title LF-12880 Added new error case LF-12880 Added new error case [Permit2Proxy v1.0.3] Apr 7, 2025
0xDEnYO
0xDEnYO previously approved these changes Apr 7, 2025
@mirooon mirooon force-pushed the lf-12880-handle-all-possible-revert-cases-in-permit2proxy branch from d643b11 to b378d5b Compare April 14, 2025 13:09
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.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/solidity/Periphery/Permit2Proxy.t.sol (1)

709-730: Comment mismatch regarding the amount triggering require.
Although the comment says “Amount less than 1000 to trigger require,” the actual revert is require(true == false), which ignores the input entirely. Consider aligning the commented explanation with the actual logic, or switching the require condition to use the supplied amount if that is the intended test scenario.

-        500, // Amount less than 1000 to trigger require
+        500, // This value is not used in the require logic; consider removing or reusing it
🛑 Comments failed to post (1)
test/solidity/Periphery/Permit2Proxy.t.sol (1)

732-753: 🛠️ Refactor suggestion

Test name does not match the overflow scenario.
The test is named testRevert_FailsOnDivisionByZero, but the contract triggers an addition overflow. Update the test name or the contract logic for consistency.

-function testRevert_FailsOnDivisionByZero() public {
+function testRevert_FailsOnAdditionOverflow() public {
📝 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.

    function testRevert_FailsOnAdditionOverflow() public {
        MockPermitTokenAdditionOverflow token = new MockPermitTokenAdditionOverflow();
        address tokenAddress = address(token);

        vm.startPrank(permit2User);
        bytes memory callData = _getCalldataForBridging();

        // Expect arithmetic overflow panic
        vm.expectRevert(stdError.arithmeticError);

        permit2Proxy.callDiamondWithEIP2612Signature(
            tokenAddress,
            defaultUSDCAmount,
            block.timestamp + 1000,
            27, // dummy v
            bytes32(0), // dummy r
            bytes32(0), // dummy s
            callData
        );

        vm.stopPrank();
    }

…s, including custom errors, panic assertions, empty reverts, string reverts, require statements and overflow addtion (audit issue#1)

created multiple mock token contracts to test various revert scenarios, including custom errors, panic assertions, empty reverts, string reverts, require statements and overflow addtion (audit issue#1)
@mirooon mirooon force-pushed the lf-12880-handle-all-possible-revert-cases-in-permit2proxy branch from a9b1729 to 5b212bd Compare April 14, 2025 13:40
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: 0

🧹 Nitpick comments (2)
test/solidity/Periphery/Permit2Proxy.t.sol (2)

13-36: Abstract contract structure is well-defined.

Clearly separating the core ERC20 + ERC20Permit functionality in an abstract base is commendable and makes mocking easier. Consider removing solhint-disable-next-line no-unused-vars if no longer needed.


624-646: Custom error revert test is cohesive.

The test effectively expects the correct custom error revert for MockPermitToken. If the reference to “Allowance” in the name is unneeded, consider a clearer function name.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a9b1729 and 5b212bd.

📒 Files selected for processing (1)
  • test/solidity/Periphery/Permit2Proxy.t.sol (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: run-unit-tests
  • GitHub Check: enforce-min-test-coverage
  • GitHub Check: generate-tag
🔇 Additional comments (15)
test/solidity/Periphery/Permit2Proxy.t.sol (15)

4-6: Imports look appropriate.

These additional imports from OpenZeppelin and local TestBase are valid and align with the usage below.


11-11: Use of stdError is a good approach.

Referencing stdError from forge-std/Test.sol is helpful for verifying specific panic and arithmetic reverts.


38-45: Custom error usage is clear.

Throwing a custom error in _permit() effectively tests revert scenarios. Implementation is straightforward.


46-52: Panic test token is correct.

Forcing an assertion failure is the right way to simulate a panic revert in Foundry.


53-58: Empty revert logic is sound.

This contract properly simulates a revert with no reason.


60-66: String revert test is well-structured.

Including a custom message ensures coverage for string-based revert scenarios.


67-73: Require-based revert is clearly demonstrated.

The require(true == false) exemplifies a typical logical revert scenario.


74-80: Overflow scenario is adequately modeled.

Using type(uint256).max + 1 checks arithmetic overflow handling.


81-88: Division by zero scenario is valid.

Explicitly dividing by zero is a suitable test for arithmetic revert conditions.


648-670: Panic during allowance simulation is effective.

Testing with MockPermitTokenPanic accurately captures assertion-based panics.


672-693: Empty revert scenario is well-tested.

Verifying an untyped revert ensures coverage of minimal revert contexts.


695-716: String revert scenario is validated correctly.

Matching revert messages with vm.expectRevert("Custom error message") is the recommended approach.


718-739: Require revert is correct.

Unconditional require statements confirm the revert reason is checked properly.


741-762: Arithmetic overflow scenario test is comprehensive.

Using stdError.arithmeticError ensures the test captures any overflows triggered by addition.


764-785: Division by zero scenario test is appropriate.

stdError.divisionError precisely validates a zero divisor revert.

@0xDEnYO 0xDEnYO enabled auto-merge (squash) April 16, 2025 07:56
@0xDEnYO 0xDEnYO merged commit 85952e3 into main Apr 16, 2025
21 checks passed
@0xDEnYO 0xDEnYO deleted the lf-12880-handle-all-possible-revert-cases-in-permit2proxy branch April 16, 2025 07:56
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.

4 participants