Skip to content

test: tighten 44 bare expectReverts + 17 new tests (Phase 9) - #11

Merged
Solthodox merged 1 commit into
mainfrom
post-audit-phase-9
May 6, 2026
Merged

test: tighten 44 bare expectReverts + 17 new tests (Phase 9)#11
Solthodox merged 1 commit into
mainfrom
post-audit-phase-9

Conversation

@fepvenancio

Copy link
Copy Markdown
Contributor

Summary

  • Tighten 44 bare vm.expectRevert() calls across all 3 unit test files to use specific selectors. A bare expectRevert() succeeds on any revert; this lets a role-check regression pass silently behind an allowance failure, balance failure, or proxy-init revert. Specific selectors prevent that.
  • Add 17 missing tests in kToken.t.sol (revoke role flows, emergencyWithdraw input validation, initialize zero-address checks, UUPS upgrade authorization).
  • Mutation-verified: 12 strategic source mutations on kToken.sol — all 12 killed.
  • Suite: 120 → 137 passing, zero regressions.

Tightened reverts (44 total)

File Count Selectors used
test/unit/kToken.t.sol 29 KTOKEN_WRONG_ROLE, KTOKEN_IS_PAUSED, KTOKEN_ACCOUNT_FROZEN, KTOKEN_ZERO_ADDRESS, ERC20.InsufficientBalance, ERC20.InsufficientAllowance, Ownable.Unauthorized, Initializable.InvalidInitialization
test/unit/kOFT.t.sol 11 same plus kOFT.ZeroAddress, OZ's OwnableUnauthorizedAccount(address) for OFTCoreUpgradeable's owner check
test/unit/kOFTAdater.t.sol 4 KTOKEN_WRONG_ROLE, Initializable.InvalidInitialization

New tests (17, all in kToken.t.sol)

  • Role revocation flowsrevokeAdminRole (success / non-owner / revoked-admin-cannot-grant-minter), revokeEmergencyRole (success / non-admin / revoked-emergency-admin-cannot-pause), grantEmergencyRole non-admin revert.
  • emergencyWithdraw input validation — zero destination, zero amount, and the ETH-transfer-failure branch (via a non-payable ETHRejector helper contract).
  • initialize zero-address checks — separate tests for zero owner / admin / emergency admin / minter, each going through MinimalUUPSFactory.deployAndCall so the revert lands during the initializer call.
  • UUPS upgrade authorization — success (reads the ERC-1967 implementation slot to verify), non-owner revert, zero-implementation revert.

Mutation verification

12 strategic mutations applied to src/kToken.sol, full suite (137 tests) run after each, source restored between runs:

# Mutation Test killed
M1 mint() skip _checkMinter test_Mint_RevertsForNonMinter
M2 grantMinterRole() skip _checkAdmin test_GrantMinterRole_RevertsForNonAdmin
M3 _authorizeUpgrade skip _checkOwner test_AuthorizeUpgrade_RevertsForNonOwner
M4 _beforeTokenTransfer skip _checkPaused test_Pause_BlocksTransfers
M5 _beforeTokenTransfer skip _checkNotFrozen test_FrozenAccount_CannotTransfer
M6 freeze() skip _checkBlacklistAdmin test_FreezeAccount_RevertsForNonAdmin
M7 setPaused() skip _checkEmergencyAdmin test_SetPaused_RevertsForNonEmergencyAdmin
M8 emergencyWithdraw() skip _checkEmergencyAdmin test_EmergencyWithdraw_RevertsForNonEmergencyAdmin
M9 freeze() weaken _account != owner() test_CannotFreezeOwner
M10 emergencyWithdraw weaken _amount != 0 test_EmergencyWithdraw_RevertsForZeroAmount
M11 emergencyWithdraw weaken _to != address(0) test_EmergencyWithdraw_RevertsForZeroDestination
M12 initialize() weaken _owner != address(0) test_Initialize_RevertsForZeroOwner

Source MD5 verified equal to baseline before and after the run.

Test plan

  • forge test — 137 passed, 0 failed (89 in kTokenUnitTest, 39 in kOFTUnitTest, 9 in kOFTAdapterTest)
  • All 12 mutations killed; clean restore confirmed via MD5 match
  • No bare vm.expectRevert() remaining in test/

🤖 Generated with Claude Code

Tighten every `vm.expectRevert()` (bare) across kToken / kOFT / kOFTAdapter
unit tests to use specific selectors so role-check or state-check regressions
cannot pass silently behind unrelated reverts (insufficient balance, allowance,
proxy initialization, etc.).

Tightened reverts (44 total):
- kToken.t.sol (29) — KTOKEN_WRONG_ROLE / KTOKEN_IS_PAUSED /
  KTOKEN_ACCOUNT_FROZEN / KTOKEN_ZERO_ADDRESS, ERC20.InsufficientBalance,
  ERC20.InsufficientAllowance, Ownable.Unauthorized,
  Initializable.InvalidInitialization
- kOFT.t.sol (11) — same plus kOFT.ZeroAddress and OZ's
  OwnableUnauthorizedAccount(address) for OFTCoreUpgradeable's owner check
- kOFTAdater.t.sol (4) — KTOKEN_WRONG_ROLE,
  Initializable.InvalidInitialization

Added missing tests (17 in kToken.t.sol):
- Role revocation: revokeAdminRole (success / non-owner / revoked admin
  cannot grant minter), revokeEmergencyRole (success / non-admin / revoked
  emergency admin cannot pause), grantEmergencyRole non-admin revert.
- emergencyWithdraw input validation: zero destination, zero amount, ETH
  transfer failure (via a non-payable rejector contract).
- initialize zero-address checks: zero owner / admin / emergency admin /
  minter — each spun up via MinimalUUPSFactory so the revert lands during
  the initializer call.
- UUPS upgrade authorization: success (verifies the ERC-1967 implementation
  slot), non-owner revert, zero-implementation revert.

Mutation-verified: 12 strategic source mutations on kToken.sol — all 12
killed by the suite (skip role checks in mint / grantMinterRole / freeze /
setPaused / emergencyWithdraw, skip _checkOwner in _authorizeUpgrade, skip
_checkPaused / _checkNotFrozen in _beforeTokenTransfer, weaken the owner /
zero-amount / zero-address / zero-owner-init guards).

Suite: 120 -> 137 passing, no regressions.
@Solthodox
Solthodox self-requested a review May 6, 2026 17:36

@Solthodox Solthodox left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

forge fmt missing but good

@Solthodox
Solthodox merged commit 45b0f4d into main May 6, 2026
0 of 2 checks passed
@fepvenancio
fepvenancio deleted the post-audit-phase-9 branch May 14, 2026 23:54
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.

2 participants