Skip to content

Conversation

@adamgall
Copy link
Collaborator

@adamgall adamgall commented Oct 26, 2025

Problem

Previously, the libraries allowed transferOwnership() to be called even after the owner was set to address(0) through renouncement. This meant ownership renouncement was not truly permanent and could be reversed, violating the expected behavior.

Solution

Added OwnerAlreadyRenounced error and validation in both libraries:

  • LibOwner.transferOwnership() now reverts if previousOwner == address(0)
  • LibOwnerTwoSteps.transferOwnership() now reverts if previousOwner == address(0)

Changes

  • Added error OwnerAlreadyRenounced() to both LibOwner and LibOwnerTwoSteps
  • Added renouncement checks in transferOwnership() functions
  • Updated 5 tests to expect reverts when attempting transfers from renounced owner

Testing

All 122 tests in the access control module pass:

  • OwnerFacet: 19 tests ✓
  • LibOwner: 25 tests ✓
  • LibOwnerTwoSteps: 35 tests ✓
  • OwnerTwoStepsFacet: 43 tests ✓

Impact

This is a breaking change for any code that relied on the ability to transfer ownership after renouncement. However, this was incorrect behavior that needed to be fixed for security.

Fixes #116
Fixes #46

…rTwoSteps

## Problem
Previously, the libraries allowed `transferOwnership()` to be called even after the owner was
set to `address(0)` through renouncement. This meant ownership renouncement was not truly
permanent and could be reversed, violating the expected behavior.

## Solution
Added `OwnerAlreadyRenounced` error and validation in both libraries:
- `LibOwner.transferOwnership()` now reverts if `previousOwner == address(0)`
- `LibOwnerTwoSteps.transferOwnership()` now reverts if `previousOwner == address(0)`

## Changes
- Added `error OwnerAlreadyRenounced()` to both LibOwner and LibOwnerTwoSteps
- Added renouncement checks in transferOwnership() functions
- Updated 5 tests to expect reverts when attempting transfers from renounced owner

## Testing
All 122 tests in the access control module pass:
- OwnerFacet: 19 tests ✓
- LibOwner: 25 tests ✓
- LibOwnerTwoSteps: 35 tests ✓
- OwnerTwoStepsFacet: 43 tests ✓

## Impact
This is a breaking change for any code that relied on the ability to transfer ownership
after renouncement. However, this was incorrect behavior that needed to be fixed for security.

Fixes Perfect-Abstractions#116
@github-actions
Copy link

Coverage Report

Coverage

Metric Coverage Details
Lines 33% 306/936 lines
Functions 47% 71/152 functions
Branches 19% 33/171 branches

Last updated: Sun, 26 Oct 2025 20:42:22 GMT for commit 4af8827

@mudgen
Copy link
Contributor

mudgen commented Oct 26, 2025

Yes, thanks!

@mudgen mudgen merged commit 7507731 into Perfect-Abstractions:main Oct 26, 2025
3 checks passed
@adamgall adamgall deleted the renounce-check branch October 26, 2025 20:56
JackieXu pushed a commit to JackieXu/Compose that referenced this pull request Nov 6, 2025
fix: make ownership renouncement irreversible in LibOwner and LibOwnerTwoSteps
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.

[BUG] Add Renouncement Check to LibOwner.transferOwnership() [Improvement] Align renounce logic between ERC173Facet and LibERC173

2 participants