Skip to content

feat: Diamond switchboard#69

Merged
lucas-manuel merged 5 commits intodevfrom
feat/diamond-switchboard
Mar 23, 2026
Merged

feat: Diamond switchboard#69
lucas-manuel merged 5 commits intodevfrom
feat/diamond-switchboard

Conversation

@deluca-mike
Copy link
Copy Markdown
Collaborator

@deluca-mike deluca-mike commented Mar 19, 2026

Summary by CodeRabbit

  • New Features

    • Implemented diamond proxy pattern with dynamic facet-based function routing
    • Added admin-controlled facet configuration system for flexible contract upgrades
    • Enabled native ETH receiving capability
  • Refactor

    • Updated address type handling to support payable operations throughout the system
  • Tests

    • Added comprehensive integration and unit test suites validating new proxy and facet functionality

@octane-security-app
Copy link
Copy Markdown

Summary by Octane

New Contracts

No new contracts were added.

Updated Contracts

  • ControllerDeploy.sol: Changed controller returns to address payable for both Foreign and Mainnet, allowing payment functionality.
  • ControllerInstance.sol: The smart contract now features a payable controller address for enhanced transaction handling.
  • Controller.sol: The contract adds diamond function management, admin role checks, and fallback function forwarding, integrating parameters and access controls.

🔗 Commit Hash: 6d40c69

@deluca-mike deluca-mike changed the title Feat/diamond switchboard feat : Diamond switchboard Mar 19, 2026
@deluca-mike deluca-mike changed the title feat : Diamond switchboard feat: Diamond switchboard Mar 19, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 19, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6af8faec-a365-4848-b82d-aa6ba46f5f06

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The changes implement a diamond proxy pattern for the Controller contract, enabling facet-based function delegation. Deployment and script files were updated to return address payable controller instances. Core Controller logic was enhanced with admin-controlled facet registration and fallback-based delegation to registered facets. Comprehensive tests validate facet management, access control, and delegated calls.

Changes

Cohort / File(s) Summary
Deployment Type Updates
deploy/ControllerDeploy.sol, deploy/ControllerInstance.sol
Changed controller return types and struct fields from address to address payable to align with payable controller instances.
Script Updates
script/staging/Upgrade.s.sol, script/staging/test/StagingDeployment.t.sol
Wrapped controller address casts with payable() to accommodate updated deployment signatures.
Test Setup Updates
test/base-fork/InitAndUpgrade.t.sol, test/mainnet-fork/InitAndUpgrade.t.sol
Updated ControllerInstance struct field assignments to use payable() casts for controller addresses.
Core Diamond Implementation
src/Controller.sol, src/interfaces/IController.sol
Introduced diamond proxy pattern with setFacet() admin function, fallback-based facet delegation, parameter-persisted facet registry, access control checks, and corresponding event/error declarations.
Integration Testing
test/integration/Controller.t.sol
New test suite validating facet registration, access control enforcement, and delegated call behavior via MockFacet and ControllerIntegration_Tests.
Unit Testing
test/unit/Controller.t.sol
Comprehensive test refactor with mocked AccessControls/Parameters integration, validating setFacet, receive, and fallback facet dispatch including revert propagation and complex return data handling.

Sequence Diagram(s)

sequenceDiagram
    participant admin as Admin
    participant controller as Controller
    participant params as Parameters
    participant facet as Facet
    participant user as User

    admin->>controller: setFacet(selector, facetAddr, delegateSelector)
    activate controller
    controller->>controller: _revertIfNotAdmin()
    controller->>params: set(facetKey, facetData)
    activate params
    params-->>controller: ✓
    deactivate params
    controller->>controller: emit FacetSet(...)
    deactivate controller

    user->>controller: facetFunction(args)
    activate controller
    controller->>controller: fallback()
    controller->>params: get(facetKey)
    activate params
    params-->>controller: (facet, delegateSelector)
    deactivate params
    controller->>facet: delegatecall(delegateSelector || args[4:])
    activate facet
    facet-->>controller: result
    deactivate facet
    controller-->>user: return result
    deactivate controller
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • supercontracts
  • TheMj0ln1r

🐰 A diamond proxy blooms, facets dance with glee,
Admin gates the treasures in parameters' spree,
Fallback whispers secrets, delegation flows so free,
Tests with mocking magic ensure it all will be! ✨

🚥 Pre-merge checks | ✅ 3
✅ 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 "Diamond switchboard" accurately describes the main feature being added: a diamond-pattern switchboard/routing system for facet delegation in the Controller contract.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/diamond-switchboard

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.

@octane-security-app
Copy link
Copy Markdown

Overview

Vulnerabilities found: 2                                                                                
Warnings found: 6                                                                                

🔗 Commit Hash: 6d40c69
🛡️ Octane Dashboard: All vulnerabilities

@lucas-manuel
Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 20, 2026

✅ 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
Copy Markdown

@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 (3)
src/Controller.sol (1)

76-93: Consider whether parameters being unset should have an explicit check.

The fallback implementation is correct for diamond-style dispatch. However, if $.parameters is address(0) (not initialized), the _getFacet call at line 77 will revert with a low-level call failure rather than a descriptive error. This may be acceptable given the constructor sets parameters, but consider whether an explicit guard would improve debuggability.

The selector replacement pattern (abi.encodePacked(delegateSelector, msg.data[4:])) and return data forwarding via assembly are correct.

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

In `@src/Controller.sol` around lines 76 - 93, Add an explicit guard at the start
of the fallback() before calling _getFacet to check that parameters (or
$.parameters) is not address(0) and revert with a clear error (e.g.,
ParametersNotSet or a descriptive revert message) if unset; this uses the
existing fallback() and _getFacet symbols so you only need to insert the check
prior to _getFacet(msg.sig) to provide a more descriptive failure when
parameters weren't initialized.
test/unit/Controller.t.sol (2)

176-181: Consider adding a balance assertion for completeness.

The test verifies that the receive() function doesn't revert, but adding a balance check would make the test more explicit about the expected behavior.

✨ Suggested improvement
 function test_receive() external {
     deal(admin, 1 ether);

     vm.prank(admin);
-    payable(controller).call{value: 1 ether}("");
+    (bool success,) = payable(controller).call{value: 1 ether}("");
+    assertTrue(success);
+    assertEq(address(controller).balance, 1 ether);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/Controller.t.sol` around lines 176 - 181, The test_receive()
currently only ensures receive() doesn't revert; add explicit balance assertions
to confirm the controller contract actually received the 1 ether: capture the
controller's starting balance (address(controller).balance == 0 or store it),
call payable(controller).call{value: 1 ether}("") as done, then assert the final
balance increased by 1 ether (e.g. assertEq(address(controller).balance, start +
1 ether)). Use the existing symbols test_receive, admin, controller, and
vm.prank to place the assertions.

229-229: Rename test for clarity.

The test name test_fallback_xxx is non-descriptive. Consider renaming to better convey the test's purpose.

✏️ Suggested rename
-function test_fallback_xxx() external {
+function test_fallback_complexAbiTypes() external {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/Controller.t.sol` at line 229, Rename the non-descriptive test
function test_fallback_xxx to a clear, purpose-revealing name (e.g.,
test_fallback_calls_receive_or_fallback_when_no_data or another name that
describes the expected behavior); update the function declaration for
test_fallback_xxx and any references to it (calls or annotations) so the test
suite still runs, and ensure the new name follows the project's test naming
conventions and compiles in the Controller test contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/Controller.sol`:
- Around line 76-93: Add an explicit guard at the start of the fallback() before
calling _getFacet to check that parameters (or $.parameters) is not address(0)
and revert with a clear error (e.g., ParametersNotSet or a descriptive revert
message) if unset; this uses the existing fallback() and _getFacet symbols so
you only need to insert the check prior to _getFacet(msg.sig) to provide a more
descriptive failure when parameters weren't initialized.

In `@test/unit/Controller.t.sol`:
- Around line 176-181: The test_receive() currently only ensures receive()
doesn't revert; add explicit balance assertions to confirm the controller
contract actually received the 1 ether: capture the controller's starting
balance (address(controller).balance == 0 or store it), call
payable(controller).call{value: 1 ether}("") as done, then assert the final
balance increased by 1 ether (e.g. assertEq(address(controller).balance, start +
1 ether)). Use the existing symbols test_receive, admin, controller, and
vm.prank to place the assertions.
- Line 229: Rename the non-descriptive test function test_fallback_xxx to a
clear, purpose-revealing name (e.g.,
test_fallback_calls_receive_or_fallback_when_no_data or another name that
describes the expected behavior); update the function declaration for
test_fallback_xxx and any references to it (calls or annotations) so the test
suite still runs, and ensure the new name follows the project's test naming
conventions and compiles in the Controller test contract.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 12c0671f-b695-4924-82fc-7c9b0fd353f1

📥 Commits

Reviewing files that changed from the base of the PR and between c546df5 and 6d40c69.

📒 Files selected for processing (10)
  • deploy/ControllerDeploy.sol
  • deploy/ControllerInstance.sol
  • script/staging/Upgrade.s.sol
  • script/staging/test/StagingDeployment.t.sol
  • src/Controller.sol
  • src/interfaces/IController.sol
  • test/base-fork/InitAndUpgrade.t.sol
  • test/integration/Controller.t.sol
  • test/mainnet-fork/InitAndUpgrade.t.sol
  • test/unit/Controller.t.sol

Comment thread src/Controller.sol Outdated
Comment thread src/Controller.sol
Comment thread src/Controller.sol
Comment thread src/Controller.sol Outdated
Comment thread test/integration/Controller.t.sol
Comment thread src/Controller.sol Outdated
Comment thread src/Controller.sol
Comment thread src/Controller.sol
Comment thread src/Controller.sol
Comment thread src/Controller.sol
Comment thread test/unit/Controller.t.sol Outdated
function test_receive() external {
deal(admin, 1 ether);

vm.prank(admin);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Remove prank and assert balance changes

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this (the test contract) should not be an actor in any test.

Comment thread test/unit/Controller.t.sol Outdated
abi.encodeWithSelector(IController.FacetNotFound.selector, IMockController.facetFoo.selector)
);

vm.prank(admin);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Rm prank

Comment thread test/unit/Controller.t.sol Outdated
IMockController(address(controller)).facetFoo();
}

function test_fallback_xxx() external {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Rm _xxx

@deluca-mike deluca-mike force-pushed the feat/diamond-switchboard branch from 3971be5 to cd082d3 Compare March 23, 2026 17:50
@lucas-manuel lucas-manuel merged commit 52dddd3 into dev Mar 23, 2026
4 checks passed
@lucas-manuel lucas-manuel deleted the feat/diamond-switchboard branch March 23, 2026 17:54
@github-actions
Copy link
Copy Markdown

Coverage after merging feat/diamond-switchboard into dev will be

98.80%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
deploy
   ControllerDeploy.sol100%100%100%100%
   ForeignControllerInit.sol100%100%100%100%
   MainnetControllerInit.sol97.37%93.33%100%100%159, 97
src
   ALMProxy.sol100%100%100%100%
   ALMProxyFreezable.sol100%100%100%100%
   AccessControls.sol100%100%100%100%
   Controller.sol100%100%100%100%
   ForeignController.sol98%100%97.83%98.04%473–474
   MainnetController.sol98.88%100%98.78%98.91%526–527
   OTCBuffer.sol92.31%100%83.33%93.75%61
   ParameterHelpers.sol100%100%100%100%
   Parameters.sol100%100%100%100%
   RateLimitHelpers.sol75%100%75%75%38–39
   RateLimits.sol100%100%100%100%
   WEETHModule.sol93.18%90%85.71%96.30%101, 94
src/libraries
   AaveLib.sol100%100%100%100%
   ApproveLib.sol100%100%100%100%
   CCTPLib.sol100%100%100%100%
   CentrifugeLib.sol100%100%100%100%
   CurveLib.sol100%100%100%100%
   DAIUSDSLib.sol100%100%100%100%
   ERC4626Lib.sol97.87%92.31%100%100%155
   ERC7540Lib.sol100%100%100%100%
   FarmLib.sol100%100%100%100%
   LayerZeroLib.sol96.15%83.33%100%100%117
   MapleLib.sol100%100%100%100%
   MerklLib.sol100%100%100%100%
   OTCLib.sol100%100%100%100%
   PSM3Lib.sol100%100%100%100%
   PSMLib.sol100%100%100%100%
   PendleLib.sol100%100%100%100%
   SparkVaultLib.sol100%100%100%100%
   SuperstateLib.sol100%100%100%100%
   TransferAssetLib.sol100%100%100%100%
   USDELib.sol100%100%100%100%
   USDSLib.sol100%100%100%100%
   UniswapV3Lib.sol99.18%96.92%100%100%884–885
   UniswapV4Lib.sol99.38%96%100%100%305
   WEETHLib.sol100%100%100%100%
   WSTETHLib.sol100%100%100%100%
   WrapProxyETHLib.sol100%100%100%100%
src/libraries/uniswap-v3
   UniswapV3OracleLib.sol94.74%66.67%100%100%38
   UniswapV3UtilsLib.sol38.89%16.67%33.33%45.83%10, 106, 11, 11, 11, 111–112, 12, 23, 25, 40–41, 47, 69–70, 84, 89–90

@coderabbitai coderabbitai Bot mentioned this pull request Apr 8, 2026
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.

2 participants