Skip to content

Commit

Permalink
feat: add IOwnable and OwnableTest
Browse files Browse the repository at this point in the history
  • Loading branch information
guidanoli committed Oct 10, 2024
1 parent 633ceb8 commit b7d6477
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/lovely-glasses-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/rollups": minor
---

Add `IOwnable` interface
11 changes: 11 additions & 0 deletions contracts/access/IOwnable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

pragma solidity ^0.8.8;

/// @notice The interface of OpenZeppelin's `Ownable` contract.
interface IOwnable {
function owner() external view returns (address);
function renounceOwnership() external;
function transferOwnership(address newOwner) external;
}
114 changes: 114 additions & 0 deletions test/foundry/util/OwnableTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

pragma solidity ^0.8.22;

import {IOwnable} from "contracts/access/IOwnable.sol";

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

import {Test} from "forge-std/Test.sol";

abstract contract OwnableTest is Test {
/// @notice Get ownable contract to be tested
function _getOwnableContract() internal view virtual returns (IOwnable);

function testRenounceOwnership(
address caller,
address randomOwner
) external {
vm.assume(caller != address(0));
vm.assume(randomOwner != address(0));

IOwnable ownable = _getOwnableContract();
address owner = ownable.owner();

vm.expectEmit(true, true, false, false);
emit Ownable.OwnershipTransferred(owner, address(0));

vm.startPrank(owner);
ownable.renounceOwnership();
vm.stopPrank();

assertEq(ownable.owner(), address(0));

vm.startPrank(caller);
vm.expectRevert(
abi.encodeWithSelector(
Ownable.OwnableUnauthorizedAccount.selector,
caller
)
);
ownable.transferOwnership(randomOwner);
vm.stopPrank();
}

function testUnauthorizedAccount(
address caller,
address randomOwner
) external {
vm.assume(randomOwner != address(0));

IOwnable ownable = _getOwnableContract();
address owner = ownable.owner();

vm.assume(caller != owner);

vm.startPrank(caller);
vm.expectRevert(
abi.encodeWithSelector(
Ownable.OwnableUnauthorizedAccount.selector,
caller
)
);
ownable.transferOwnership(randomOwner);
vm.stopPrank();
}

function testInvalidOwner() external {
IOwnable ownable = _getOwnableContract();
address owner = ownable.owner();

vm.startPrank(owner);
vm.expectRevert(
abi.encodeWithSelector(
Ownable.OwnableInvalidOwner.selector,
address(0)
)
);
ownable.transferOwnership(address(0));
vm.stopPrank();
}

function testTransferOwnership(
address newOwner,
address caller,
address randomOwner
) external {
vm.assume(newOwner != address(0));
vm.assume(caller != newOwner);
vm.assume(randomOwner != address(0));

IOwnable ownable = _getOwnableContract();
address owner = ownable.owner();

vm.expectEmit(true, true, false, false);
emit Ownable.OwnershipTransferred(owner, newOwner);

vm.startPrank(owner);
ownable.transferOwnership(newOwner);
vm.stopPrank();

assertEq(ownable.owner(), newOwner);

vm.startPrank(caller);
vm.expectRevert(
abi.encodeWithSelector(
Ownable.OwnableUnauthorizedAccount.selector,
caller
)
);
ownable.transferOwnership(randomOwner);
vm.stopPrank();
}
}

0 comments on commit b7d6477

Please sign in to comment.