Skip to content

Commit 76c93a3

Browse files
committed
fix: Pausing & Unpausing Have The Same Role
1 parent b5f6ef7 commit 76c93a3

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

src/token/Hoku.sol

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ contract Hoku is
3131
bytes32 internal _itsSalt;
3232

3333
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); // solhint-disable-line var-name-mixedcase
34+
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); // solhint-disable-line var-name-mixedcase
3435
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); // solhint-disable-line var-name-mixedcase
3536

3637
/// @custom:oz-upgrades-unsafe-allow constructor
@@ -55,7 +56,9 @@ contract Hoku is
5556

5657
_grantRole(ADMIN_ROLE, msg.sender);
5758
_grantRole(MINTER_ROLE, msg.sender);
59+
_grantRole(PAUSER_ROLE, msg.sender);
5860
_setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);
61+
_setRoleAdmin(PAUSER_ROLE, ADMIN_ROLE);
5962
_setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);
6063
}
6164

@@ -67,7 +70,7 @@ contract Hoku is
6770
}
6871

6972
/// @dev Pauses all token transfers
70-
function pause() external onlyRole(ADMIN_ROLE) {
73+
function pause() external onlyRole(PAUSER_ROLE) {
7174
_pause();
7275
}
7376

test/Hoku.t.sol

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,67 @@ contract HokuTest is Test {
156156
vm.prank(user);
157157
token.transfer(address(0x456), 100);
158158
}
159+
160+
function testPauserRolePermissions() public {
161+
address pauser = address(0x789);
162+
bytes32 pauserRole = token.PAUSER_ROLE();
163+
bytes32 adminRole = token.ADMIN_ROLE();
164+
165+
// Grant PAUSER_ROLE to new address
166+
vm.prank(TESTER);
167+
token.grantRole(pauserRole, pauser);
168+
169+
// Pauser can pause
170+
vm.prank(pauser);
171+
token.pause();
172+
assertTrue(token.paused());
173+
174+
// Pauser cannot unpause (only ADMIN can)
175+
vm.prank(pauser);
176+
vm.expectRevert(
177+
abi.encodeWithSignature("AccessControlUnauthorizedAccount(address,bytes32)",
178+
pauser,
179+
adminRole
180+
)
181+
);
182+
token.unpause();
183+
184+
// Random address cannot pause
185+
vm.prank(user);
186+
vm.expectRevert(
187+
abi.encodeWithSignature("AccessControlUnauthorizedAccount(address,bytes32)",
188+
user,
189+
pauserRole
190+
)
191+
);
192+
token.pause();
193+
194+
// Admin can unpause
195+
vm.prank(TESTER);
196+
token.unpause();
197+
assertFalse(token.paused());
198+
}
199+
200+
function testRemoveAdminPauserRole() public {
201+
bytes32 pauserRole = token.PAUSER_ROLE();
202+
203+
// Initially admin can pause
204+
vm.prank(TESTER);
205+
token.pause();
206+
assertTrue(token.paused());
207+
208+
// Remove PAUSER_ROLE from admin
209+
vm.prank(TESTER);
210+
token.revokeRole(pauserRole, TESTER);
211+
212+
// Admin can no longer pause after role removal
213+
vm.prank(TESTER);
214+
vm.expectRevert(
215+
abi.encodeWithSignature("AccessControlUnauthorizedAccount(address,bytes32)",
216+
TESTER,
217+
pauserRole
218+
)
219+
);
220+
token.pause();
221+
}
159222
}

0 commit comments

Comments
 (0)