Skip to content

Conversation

@tHeMaskedMan981
Copy link
Collaborator

@tHeMaskedMan981 tHeMaskedMan981 commented Nov 5, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Deposit transactions now include unique payload identifiers for improved tracking and auditability.
    • Added EVMX configuration support for enhanced chain compatibility.
  • Improvements

    • Optimized native amount handling with automatic credit conversion fallback mechanism.
    • Streamlined deposit submission through consolidated payload-based API.

@coderabbitai
Copy link

coderabbitai bot commented Nov 5, 2025

Walkthrough

The deposit API transitions from multi-parameter to payload-based architecture. IFeesManager interface signature changes to accept bytes calldata payload. Credit.sol decodes payload parameters and converts failed native withdrawals to credits. FeesPlug.sol encodes deposit data, sends through socket for payloadId tracking, and emits updated FeesDeposited event. Tests updated to encode parameters.

Changes

Cohort / File(s) Summary
Interface Updates
contracts/evmx/interfaces/IFeesManager.sol, contracts/evmx/interfaces/IFeesPlug.sol
IFeesManager.deposit signature simplified from multi-parameter to deposit(bytes calldata payload_). IFeesPlug.FeesDeposited event extended with bytes32 payloadId parameter.
Deposit Implementation
contracts/evmx/fees/Credit.sol
Deposit function refactored to accept encoded payload. Added payload decoding to extract chainSlug, token, receiver, creditAmount, nativeAmount. Native amount withdrawal failures now convert to additional credits instead of remaining as nativeAmount.
Payload Encoding & Socket Integration
contracts/evmx/plugs/FeesPlug.sol
_deposit now encodes parameters into payload, sends through socket__.sendPayload() to obtain payloadId. FeesDeposited event emission updated to include payloadId from socket response.
Test Infrastructure
test/SetupTest.t.sol
Updated FeesSetup.depositNativeAndCredits to call deposit with abi.encode(). Added FastSwitchboard.setEvmxConfig() call in DeploySetup._configureChain.

Sequence Diagram

sequenceDiagram
    participant Test as Test/Client
    participant FeesPlug
    participant Socket
    participant Credit as Credit/Vault
    participant FeesPool

    Test->>FeesPlug: _deposit(token, receiver, creditAmount, nativeAmount)
    FeesPlug->>Socket: chainSlug = chainSlug()
    FeesPlug->>FeesPlug: payload = encode(chainSlug, token, receiver, creditAmount, nativeAmount)
    FeesPlug->>Socket: payloadId = sendPayload(payload)
    activate Socket
    Socket-->>FeesPlug: payloadId (bytes32)
    deactivate Socket
    FeesPlug->>FeesPlug: emit FeesDeposited(..., payloadId)
    
    Note over FeesPlug,Credit: Later: Cross-chain delivery
    FeesPlug->>Credit: deposit(encoded_payload)
    activate Credit
    Credit->>Credit: decode payload
    Credit->>Credit: mint creditAmount to receiver
    alt nativeAmount > 0
        Credit->>FeesPool: withdraw(nativeAmount)
        alt Withdrawal succeeds
            FeesPool-->>Credit: nativeAmount transferred
        else Withdrawal fails
            Credit->>Credit: mint nativeAmount credits (additional)
            Credit->>Credit: nativeAmount = 0
        end
    end
    Credit->>Credit: emit Deposited(updated amounts)
    deactivate Credit
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Credit.sol payload decoding and native-to-credit conversion logic: Verify that nativeAmount conversion to credits correctly handles edge cases; ensure tokenOnChainBalances calculation reflects actual minted amounts.
  • FeesPlug.sol socket integration: Confirm payload encoding matches Credit.sol decoding; verify socket__.sendPayload() is idempotent or handles retries appropriately.
  • Event signature breakage: FeesDeposited now requires payloadId—audit all event emitters and consumers; check off-chain indexers or tools that depend on old event signature.
  • Test coverage: Encoded payload construction must match exact format Credit.sol expects during decoding; test native withdrawal failure path specifically.

Poem

Payloads now flow through socket's gate,
Encoding dreams of cross-chain fate—
When native fails, it breeds more credit,
No need to fret, the code will edit. 💾⛓️

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'updated deposit to trigger' is vague and does not clearly convey the primary changes: refactoring deposit from multi-parameter to payload-based API and adding payload tracking via payloadId. Use a more specific title like 'refactor: convert deposit to payload-based API with payloadId tracking' to accurately reflect the core architectural change.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/fee-deposit-to-trigger

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

@arthcp
Copy link
Contributor

arthcp commented Nov 6, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 6, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@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: 3

🧹 Nitpick comments (1)
contracts/evmx/interfaces/IFeesManager.sol (1)

6-6: Document the expected payload format.

The interface should document the expected payload structure for implementers. Consider adding a NatSpec comment specifying the encoding format.

Apply this diff:

 interface IFeesManager {
+    /// @param payload_ Encoded as: (uint32 chainSlug, address token, address receiver, uint256 creditAmount, uint256 nativeAmount)
     function deposit(bytes calldata payload_) external;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c55c6a and 933900b.

📒 Files selected for processing (5)
  • contracts/evmx/fees/Credit.sol (2 hunks)
  • contracts/evmx/interfaces/IFeesManager.sol (1 hunks)
  • contracts/evmx/interfaces/IFeesPlug.sol (1 hunks)
  • contracts/evmx/plugs/FeesPlug.sol (1 hunks)
  • test/SetupTest.t.sol (2 hunks)
🔇 Additional comments (4)
contracts/evmx/interfaces/IFeesPlug.sol (1)

6-12: LGTM - Breaking change for event listeners.

The addition of payloadId to the FeesDeposited event enables tracking of deposit payloads. Off-chain systems listening to this event will need to be updated to handle the new parameter.

test/SetupTest.t.sol (1)

221-221: LGTM - EVMX configuration added.

The setEvmxConfig call enables trigger payload handling for the EVMX slug, which is necessary for the new payload-based deposit flow.

contracts/evmx/fees/Credit.sol (1)

134-144: LGTM - Robust fallback for failed native withdrawals.

The logic correctly handles failed native withdrawals by converting them to credits. This ensures users always receive value even if the native transfer fails, and the emitted event accurately reflects the final state.

contracts/evmx/plugs/FeesPlug.sol (1)

71-81: Transfer-before-payload sequencing exposes tokens to temporary lock if Socket fails; recovery path exists but should be validated.

The concern is valid: line 70 transfers tokens unconditionally before line 81 calls socket__.sendPayload(). If sendPayload() reverts (via _verifyPlugSwitchboard or ISwitchboard.processPayload failures), tokens sit locked in the contract until manually rescued.

This is by design—the contract functions as a fee escrow with async Socket synchronization. Recovery is available via rescueFunds() (line 147), protected by RESCUE_ROLE, but depends on:

  • The RESCUE_ROLE being properly managed
  • Admins monitoring and acting on failed deposits
  • The role not being revoked unexpectedly

Verify: Is this transfer-first pattern intentional and are the RESCUE_ROLE permissions maintained? If sendPayload() failures are expected to be rare, the current flow is acceptable with the recovery mechanism in place. If failures are common, consider wrapping sendPayload() in try/catch or reordering to create payload first.

emit Deposited(chainSlug_, address(token), user_, credits_, native_);
hoax(watcherEOA);
feesManager.deposit(chainSlug_, address(token), user_, native_, credits_);
feesManager.deposit(abi.encode(chainSlug_, address(token), user_, native_, credits_));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix critical parameter order mismatch.

The test encodes parameters as (chainSlug_, address(token), user_, native_, credits_) with native_ before credits_, but FeesPlug.sol line 76 encodes as (chainSlug_, token_, receiver_, creditAmount_, nativeAmount_) with creditAmount_ before nativeAmount_. This mismatch will cause the decoder in Credit.sol to assign values to the wrong variables, breaking the deposit flow.

Apply this diff to fix the parameter order:

-        feesManager.deposit(abi.encode(chainSlug_, address(token), user_, native_, credits_));
+        feesManager.deposit(abi.encode(chainSlug_, address(token), user_, credits_, native_));
📝 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
feesManager.deposit(abi.encode(chainSlug_, address(token), user_, native_, credits_));
feesManager.deposit(abi.encode(chainSlug_, address(token), user_, credits_, native_));
🤖 Prompt for AI Agents
In test/SetupTest.t.sol around line 434, the abi.encode call passes parameters
as (chainSlug_, address(token), user_, native_, credits_) but FeesPlug.sol
expects (chainSlug_, token_, receiver_, creditAmount_, nativeAmount_); swap the
last two arguments so the call becomes (chainSlug_, address(token), user_,
credits_, native_) to match FeesPlug/Credit.sol decoding and ensure
creditAmount_ and nativeAmount_ map correctly.

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.

3 participants