Skip to content

feat: Make OTCBuffer Upgradeable (DEV-1158)#232

Merged
lucas-manuel merged 8 commits intodevfrom
dev-1158-otcbuffer-upgradable
Jan 29, 2026
Merged

feat: Make OTCBuffer Upgradeable (DEV-1158)#232
lucas-manuel merged 8 commits intodevfrom
dev-1158-otcbuffer-upgradable

Conversation

@supercontracts
Copy link
Collaborator

@supercontracts supercontracts commented Jan 29, 2026

Summary by CodeRabbit

  • Chores

    • Migrated OTCBuffer contract to an upgradeable architecture with a proxy-based initialization pattern.
    • almProxy state variable changed from immutable to mutable for dynamic configuration.
  • Tests

    • Updated unit and integration tests to reflect the new initialization approach and proxy deployment pattern.

✏️ Tip: You can customize this high-level summary in your review settings.

@notion-workspace
Copy link

@octane-security-app
Copy link

Summary by Octane

New Contracts

No new contracts were added.

Updated Contracts

  • OTCBuffer.sol: The smart contract now supports upgradeability through UUPS with initializers, replacing the immutable almProxy with a settable variable.

🔗 Commit Hash: a5736a2

@coderabbitai
Copy link

coderabbitai bot commented Jan 29, 2026

Important

Review skipped

Auto incremental 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.

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

  • 🔍 Trigger a full review

Walkthrough

OTCBuffer is migrated to an upgradeable contract using OpenZeppelin's UUPS pattern. The contract now inherits from upgradeable base classes, replaces constructor-based initialization with an initializer function, and wraps deployment in ERC1967Proxy. Tests are updated to accommodate the new initialization flow.

Changes

Cohort / File(s) Summary
Upgradeable Contract Migration
src/OTCBuffer.sol
Converts contract to upgradeable pattern: inherits AccessControlEnumerableUpgradeable and UUPSUpgradeable, replaces parameterized constructor with parameterless variant that disables initializers, adds initialize(address admin, address _almProxy) external initializer, changes almProxy from immutable to mutable, and adds _authorizeUpgrade authorization hook.
Test Suite Updates
test/mainnet-fork/OTCSwaps.t.sol, test/unit/OTCBuffer.t.sol
Updates tests to wrap OTCBuffer instances in ERC1967Proxy and initialize via initialize() instead of constructor. Renames test contract from OTCBufferConstructorTest to OTCBufferInitializeTests and renames related test functions to reflect initialization pattern.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • deluca-mike
  • lucas-manuel

Poem

🐰 Hop hop, the buffer now upgrades with grace,
Behind a proxy, initialization finds its place,
From concrete constructors to initializers we bound,
UUPS patterns make our contracts safer and sound! 🌟

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 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.
Title check ✅ Passed The title 'feat: Make OTCBuffer Upgradable' directly and accurately describes the main change: migrating OTCBuffer to an upgradeable pattern with UUPSUpgradeable.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev-1158-otcbuffer-upgradable

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • DEV-1158: Entity not found: Issue - Could not find referenced Issue.

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

@supercontracts supercontracts changed the title feat: Make OTCBuffer Upgradable (DEV-1158) feat: Make OTCBuffer Upgradeable (DEV-1158) Jan 29, 2026
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

🤖 Fix all issues with AI agents
In `@src/OTCBuffer.sol`:
- Around line 25-34: The initialize function allows passing a zero admin; add a
validation to prevent granting roles to address(0) by checking admin is non-zero
(e.g., require(admin != address(0), "OTCBuffer/invalid-admin")) before calling
_grantRole(DEFAULT_ADMIN_ROLE, admin) in function initialize to ensure a valid
admin is set.
- Around line 34-36: OTCBuffer is UUPS-upgradeable but lacks a storage gap; add
a reserved storage array (e.g., uint256[50] private __gap) to the OTCBuffer
contract to preserve future storage layout compatibility. Place the __gap
declaration as a private state variable inside the OTCBuffer contract (near
other state declarations, alongside functions like _authorizeUpgrade) so future
upgrades can add variables without corrupting storage.

In `@test/unit/OTCBuffer.t.sol`:
- Around line 51-67: Add tests covering UUPS upgrade authorization and
re-initialization protection: (1) add a test that calling initialize again on
the already-initialized proxy (call OTCBuffer.initialize on buffer) reverts (use
vm.expectRevert before calling buffer.initialize(admin, almProxy)); (2) add a
test that a non-admin cannot perform upgrades by calling
buffer.upgradeToAndCall(...) and expecting a revert encoded with
AccessControlUnauthorizedAccount(address, DEFAULT_ADMIN_ROLE); (3) add a test
where admin (vm.prank(admin)) calls buffer.upgradeToAndCall(newImpl, "") to
ensure successful upgrade (verify by checking implementation slot or
post-upgrade behavior). Ensure tests reference buffer, OTCBuffer.initialize,
_authorizeUpgrade, and upgradeToAndCall.

Comment on lines 25 to 34
function initialize(address admin, address _almProxy) external initializer {
require(_almProxy != address(0), "OTCBuffer/invalid-alm-proxy");

__AccessControlEnumerable_init();
__UUPSUpgradeable_init();

_grantRole(DEFAULT_ADMIN_ROLE, admin);

almProxy = _almProxy;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider validating admin address is non-zero.

The _almProxy parameter is validated against address(0), but admin is not. Granting DEFAULT_ADMIN_ROLE to address(0) would result in an unusable contract since no one could perform admin actions or upgrades.

🛡️ Proposed fix to add validation
 function initialize(address admin, address _almProxy) external initializer {
+    require(admin != address(0), "OTCBuffer/invalid-admin");
     require(_almProxy != address(0), "OTCBuffer/invalid-alm-proxy");
📝 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
function initialize(address admin, address _almProxy) external initializer {
require(_almProxy != address(0), "OTCBuffer/invalid-alm-proxy");
__AccessControlEnumerable_init();
__UUPSUpgradeable_init();
_grantRole(DEFAULT_ADMIN_ROLE, admin);
almProxy = _almProxy;
}
function initialize(address admin, address _almProxy) external initializer {
require(admin != address(0), "OTCBuffer/invalid-admin");
require(_almProxy != address(0), "OTCBuffer/invalid-alm-proxy");
__AccessControlEnumerable_init();
__UUPSUpgradeable_init();
_grantRole(DEFAULT_ADMIN_ROLE, admin);
almProxy = _almProxy;
}
🤖 Prompt for AI Agents
In `@src/OTCBuffer.sol` around lines 25 - 34, The initialize function allows
passing a zero admin; add a validation to prevent granting roles to address(0)
by checking admin is non-zero (e.g., require(admin != address(0),
"OTCBuffer/invalid-admin")) before calling _grantRole(DEFAULT_ADMIN_ROLE, admin)
in function initialize to ensure a valid admin is set.

@octane-security-app
Copy link

Overview

Warnings found: 4                                                                                

🔗 Commit Hash: a5736a2
🛡️ Octane Dashboard: All vulnerabilities

0xa8ff6143ce9b2840ac86932ea3c593f97be7f3f4c76899ca3e385ef6d4c71f00;

function _getBufferStorage() internal pure returns (BufferStorage storage $) {
// slither-disable-next-line assembly
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't use slither

)
);

assertEq(newBuffer.hasRole(DEFAULT_ADMIN_ROLE, newAdmin), true);
Copy link
Contributor

Choose a reason for hiding this comment

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

Need to check almProxy address too

Copy link
Contributor

Choose a reason for hiding this comment

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

Before and after

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@deluca-mike deluca-mike self-requested a review January 29, 2026 16:21
deluca-mike
deluca-mike previously approved these changes Jan 29, 2026
@lucas-manuel lucas-manuel merged commit 8f97905 into dev Jan 29, 2026
4 checks passed
@lucas-manuel lucas-manuel deleted the dev-1158-otcbuffer-upgradable branch January 29, 2026 16:59
@github-actions
Copy link

Coverage after merging dev-1158-otcbuffer-upgradable into dev will be

99.40%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
deploy
   ControllerDeploy.sol100%100%100%100%
   ForeignControllerInit.sol100%100%100%100%
   MainnetControllerInit.sol97.37%93.33%100%100%152, 90
src
   ALMProxy.sol100%100%100%100%
   ALMProxyFreezable.sol100%100%100%100%
   ForeignController.sol96.08%89.66%95.65%98.02%130–131, 131, 131, 551
   MainnetController.sol99.18%100%98.36%99.24%596–597
   OTCBuffer.sol92.31%100%83.33%93.75%55
   RateLimitHelpers.sol100%100%100%100%
   RateLimits.sol100%100%100%100%
   WEETHModule.sol92.86%75%100%100%29, 41
src/libraries
   AaveLib.sol100%100%100%100%
   ApproveLib.sol100%100%100%100%
   CCTPLib.sol100%100%100%100%
   CurveLib.sol100%100%100%100%
   ERC4626Lib.sol97.06%90%100%100%117
   LayerZeroLib.sol100%100%100%100%
   PSMLib.sol100%100%100%100%
   UniswapV4Lib.sol99.32%95.65%100%100%282
   WEETHLib.sol100%100%100%100%

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.

3 participants