feat: Make OTCBuffer Upgradeable (DEV-1158)#232
Conversation
Summary by OctaneNew ContractsNo new contracts were added. Updated Contracts
🔗 Commit Hash: a5736a2 |
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the
WalkthroughOTCBuffer 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Comment |
There was a problem hiding this comment.
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.
src/OTCBuffer.sol
Outdated
| 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; | ||
| } |
There was a problem hiding this comment.
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.
| 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.
Overview
🔗 Commit Hash: a5736a2 |
src/OTCBuffer.sol
Outdated
| 0xa8ff6143ce9b2840ac86932ea3c593f97be7f3f4c76899ca3e385ef6d4c71f00; | ||
|
|
||
| function _getBufferStorage() internal pure returns (BufferStorage storage $) { | ||
| // slither-disable-next-line assembly |
| ) | ||
| ); | ||
|
|
||
| assertEq(newBuffer.hasRole(DEFAULT_ADMIN_ROLE, newAdmin), true); |
There was a problem hiding this comment.
Need to check almProxy address too
|
Coverage after merging dev-1158-otcbuffer-upgradable into dev will be
Coverage Report
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Summary by CodeRabbit
Chores
Tests
✏️ Tip: You can customize this high-level summary in your review settings.