diff --git a/docs/olympix/bugpocer/BugPoCer_Scan_Report_CMTAT.pdf b/docs/olympix/bugpocer/BugPoCer_Scan_Report_CMTAT.pdf
new file mode 100644
index 00000000..68c96035
Binary files /dev/null and b/docs/olympix/bugpocer/BugPoCer_Scan_Report_CMTAT.pdf differ
diff --git a/docs/olympix/fuzz_testing/Fuzz_Test_Report_f37cd9fe-cb1e-4732-821a-03c6811416dc_20260716_182652.pdf b/docs/olympix/fuzz_testing/Fuzz_Test_Report_f37cd9fe-cb1e-4732-821a-03c6811416dc_20260716_182652.pdf
new file mode 100644
index 00000000..56ba46aa
Binary files /dev/null and b/docs/olympix/fuzz_testing/Fuzz_Test_Report_f37cd9fe-cb1e-4732-821a-03c6811416dc_20260716_182652.pdf differ
diff --git a/docs/olympix/mutation_testing/mutation-results.csv b/docs/olympix/mutation_testing/mutation-results.csv
new file mode 100644
index 00000000..4b55a2e9
--- /dev/null
+++ b/docs/olympix/mutation_testing/mutation-results.csv
@@ -0,0 +1,94 @@
+File;Line Number;Original Code;Mutated Code;Was Mutation Killed?;Killer Tests
+contracts/modules/wrapper/core/ERC20BaseModule.sol;28;"0x9bd8d607565c0370ae5f91651ca67fd26d4438022bf72037316600e29e6a3a00";"0x0";False;""
+contracts/modules/wrapper/core/ERC20BaseModule.sol;54;") internal virtual onlyInitializing";") internal virtual";False;""
+contracts/modules/wrapper/core/ERC20BaseModule.sol;55;"ERC20BaseModuleStorage storage $";"ERC20BaseModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/wrapper/core/ERC20BaseModule.sol;80;"result";"!result";True;"testTransferByAnotherAccountWithTheRightAllowance"
+contracts/modules/wrapper/core/ERC20BaseModule.sol;83;"emit Spend(from, _msgSender(), value);";"";True;"testTransferByAnotherAccountWithTheRightAllowance"
+contracts/modules/wrapper/core/ERC20BaseModule.sol;96;"ERC20BaseModuleStorage storage $";"ERC20BaseModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/wrapper/core/ERC20BaseModule.sol;104;"ERC20BaseModuleStorage storage $";"ERC20BaseModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/wrapper/core/ERC20BaseModule.sol;113;"ERC20BaseModuleStorage storage $";"ERC20BaseModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/wrapper/core/ERC20BaseModule.sol;124;"function setName(string calldata name_) public virtual override(IERC3643ERC20Base) onlyERC20AttributeManager";"function setName(string calldata name_) public virtual override(IERC3643ERC20Base)";True;"testCannotNonAdminUpdateName"
+contracts/modules/wrapper/core/ERC20BaseModule.sol;125;"ERC20BaseModuleStorage storage $";"ERC20BaseModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/wrapper/core/ERC20BaseModule.sol;127;"emit Name(name_, name_);";"";True;"testAdminCanUpdateName, testCMTATIntegration"
+contracts/modules/wrapper/core/ERC20BaseModule.sol;133;"function setSymbol(string calldata symbol_) public virtual override(IERC3643ERC20Base) onlyERC20AttributeManager";"function setSymbol(string calldata symbol_) public virtual override(IERC3643ERC20Base)";True;"testCannotNonAdminUpdateName"
+contracts/modules/wrapper/core/ERC20BaseModule.sol;134;"ERC20BaseModuleStorage storage $";"ERC20BaseModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/wrapper/core/ERC20BaseModule.sol;136;"emit Symbol(symbol_, symbol_);";"";True;"testAdminCanUpdateSymbol"
+contracts/modules/wrapper/core/PauseModule.sol;32;"0xab1527b6135145d8da1edcbd6b7b270624e17f2b41c74a8c746ff388ad454700";"0x0";True;"reverts when trying to reschedule a snapshot in the past"
+contracts/modules/wrapper/core/PauseModule.sol;59;"function pause() public virtual override(IERC3643Pause, IERC7551Pause) onlyPauseManager";"function pause() public virtual override(IERC3643Pause, IERC7551Pause)";True;"testCannotBePausedByNonPauser, reverts when trying to schedule a snapshot in the past, testCannotBeTakenControlByAttacker"
+contracts/modules/wrapper/core/PauseModule.sol;68;"function unpause() public virtual override(IERC3643Pause, IERC7551Pause) onlyPauseManager";"function unpause() public virtual override(IERC3643Pause, IERC7551Pause)";True;"testCannotBeUnpausedByNonPauser"
+contracts/modules/wrapper/core/PauseModule.sol;69;"PauseModuleStorage storage $";"PauseModuleStorage memory $";False;""
+contracts/modules/wrapper/core/PauseModule.sol;83;"onlyDeactivateContractManager";"";True;"testCannotBeDeactivatedByNonAdmin"
+contracts/modules/wrapper/core/PauseModule.sol;87;"PauseModuleStorage storage $";"PauseModuleStorage memory $";True;"testCannotBeBurnIfContractIsDeactivated, testCannotBeBurnAndMintIfContractIsDeactivated, testCannotBeBatchBurnIfContractIsDeactivated, testCannotBeMintedIfContractIsDeactivated, testCannotBeBatchMintedIfContractIsDeactivated, testCanDeactivatedByAdminIfContractIsPaused, testCannotMintIfContractIsDeactivated"
+contracts/modules/wrapper/core/PauseModule.sol;89;"emit Deactivated(_msgSender());";"";True;"testCanDeactivatedByAdminIfContractIsPaused"
+contracts/modules/wrapper/core/PauseModule.sol;104;"PauseModuleStorage storage $";"PauseModuleStorage memory $";False;""
+contracts/modules/4_CMTATBaseERC20CrossChain.sol;113;"function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE)";"function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule)";True;"testCannotNonAdminSetCCIPAdmin"
+contracts/modules/4_CMTATBaseERC20CrossChain.sol;124;"function _checkTokenBridge(address caller) internal virtual override(ERC20CrossChainModule) whenNotPaused";"function _checkTokenBridge(address caller) internal virtual override(ERC20CrossChainModule)";True;"testCannotBeBurnIfContractIsDeactivated, testCannotBeBurnIfContractIsPaused, testCannotBeMintedIfContractIsPaused, testCannotBeMintedIfContractIsDeactivated"
+contracts/modules/4_CMTATBaseERC20CrossChain.sol;133;"function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused";"function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE)";True;"testCannotBeBurnFromIfContractIsPaused, testCannotBeBurnFromIfContractIsDeactivated"
+contracts/modules/4_CMTATBaseERC20CrossChain.sol;133;"function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused";"function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) whenNotPaused";True;"testCannotBeBurntWithoutBurnerFromRole"
+contracts/modules/4_CMTATBaseERC20CrossChain.sol;140;"function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused";"function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE)";True;"testCannotBeMBurnIfContractIsDeactivated, testCanBeBurnEvenIfContractIsPaused"
+contracts/modules/4_CMTATBaseERC20CrossChain.sol;140;"function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused";"function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) whenNotPaused";True;"testCannotBeBurntWithoutBurnerRole"
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol;48;") public virtual onlyRuleEngineManager";") public virtual";True;"testCannotBeSetByNonAdmin"
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol;49;"address(ruleEngine_) != address(ruleEngine())";"address(ruleEngine_) == address(ruleEngine())";True;"testCanCanTransferWithoutRuleEngine, testCanCanTransferFromWithoutRuleEngine, testCanCanMintWithoutRuleEngine, testCanBeSetByAdmin, testCanNotBeSetByAdminWithTheSameValue"
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol;87;"!ValidationModuleCore.canTransfer(from, to, value)";"ValidationModuleCore.canTransfer(from, to, value)";True;"testAdminCanFreezeAddress, testAdminCanBatchFreezeAddress, testAdminCanBatchPartialFreezeAddress, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testEnforcerRoleCanUnfreezeAddress, testCannotTransferTokenWhenPausedWithTransfer, testCannotTransferTokenWhenPausedWithTransferFrom, testCanDeactivatedByAdminIfContractIsPaused, testAdminCanFreezeAddressTwice, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testCanTransferTokenIfActiveBalanceIsEnough, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore, testCanCanTransferWithoutRuleEngine, testCanDetectTransferRestrictionValidTransfer, testCanTransferAllowedByRule, testCanCanMintWithoutRuleEngine, testCanMintAllowedByRule, testCannotMintIfNotAllowedByRule, testCanTransferReturnsFalseForMintToFrozenAddress, testCanTransferReturnsFalseForBurnFromFrozenAddress, testCanTransferAllowed, testCanTransfer"
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol;100;"!ValidationModuleCore.canTransferFrom(spender, from, to, value)";"ValidationModuleCore.canTransferFrom(spender, from, to, value)";True;"testCannotTransferTokenWhenSpenderIsFrozenWithTransferFrom, testCannotTransferTokenWhenPausedWithTransfer, testCannotTransferTokenWhenPausedWithTransferFrom, testCanDeactivatedByAdminIfContractIsPaused, testCanTransferTokenIfActiveBalanceIsEnough, testCanTransferFrom, testCanCanTransferFromWithoutRuleEngine, testCanApproveAllowedByRuleEngine"
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol;114;"address(ruleEngine_) != address(0)";"address(ruleEngine_) == address(0)";True;"testCannotTransferTokenWhenPausedWithTransferFrom, testCanTransferTokenIfActiveBalanceIsEnough, testCannotTransferIfNotAllowedByRule, testCanTransferFrom, testCanCanTransferFromWithoutRuleEngine, testCannotTransferFromIfNotAllowedByRuleEngine"
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol;126;"address(ruleEngine_) != address(0)";"address(ruleEngine_) == address(0)";True;"testAdminCanBatchPartialFreezeAddress, testAdminCanUnfreezeAddress, testEnforcerRoleCanUnfreezeAddress, testCannotTransferTokenWhenPausedWithTransferFrom, testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testCanTransferTokenIfActiveBalanceIsEnough, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore, testCanCanTransferWithoutRuleEngine, testCanDetectTransferRestrictionWithAmountTooHigh, testCannotTransferIfNotAllowedByRule, testCannotTransferFromIfNotAllowedByRuleEngine, testCanCanMintWithoutRuleEngine, testCanDetectTransferRestrictionWitMintAmountTooHigh, testCannotMintIfNotAllowedByRule, testCanDetectTransferRestrictionValidTransfer, testCanTransferAllowed, testCanTransfer"
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol;140;"address(ruleEngine_) != address(0)";"address(ruleEngine_) == address(0)";True;"testCanSendTokenToReceiverContract, testCannotSendTokenToEOAWithERC1363Functions, testCanBeMintedByAdmin, testCanMintByANewMinter, testCanBeMintedWithReasonByAdmin, testCanMintWithReasonByANewMinter, testCanBeMintedEvenIfContractIsPaused, testCanBeMintedBatchByAdmin, testCanBeMintBatchdByANewMinter, testCanBeMintedBatchEvenIfContractIsPaused, testCannotTransferIfNotAllowedByRule, testCannotBatchTransferIfNotAllowedByRule, testCannotTransferFromIfNotAllowedByRuleEngine, testCannotMintIfNotAllowedByRule, testCannotBatchMintIfNotAllowedByRule, testKeepStorageForTokens, testAdminCanTransmitAdminship, testCMTATIntegration"
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol;141;"spender != address(0)";"spender == address(0)";False;""
+contracts/modules/internal/ERC20BurnModuleInternal.sol;30;"accounts.length != 0";"accounts.length == 0";True;"testCanBeBurntBatchByAdmin, testCanBeBurntBatchByAdminWithoutReason, testCanBeBurntBatchByBurnerRoleWithoutReason, testCanBeBurntBatchByBurnerRole, testCannotBeBurntBatchIfOneBalanceExceeds, testCannotBatchBurnIfLengthMismatchMissingAddresses, testCannotBatchBurnIfLengthMismatchTooManyAddresses, testCannotBatchBurnIfAccountsIsEmpty, testCanBeBatchBurnEvenIfContractIsPaused, testCannotBeBatchBurnIfContractIsDeactivated, testCannotBeBatchBurnIfToIsFrozen, testCannotBatchBurnFromNoWhitelistedAddress"
+contracts/modules/internal/ERC20BurnModuleInternal.sol;33;"accounts.length == values.length";"accounts.length != values.length";True;"testCanBeBurntBatchByAdmin, testCanBeBurntBatchByAdminWithoutReason, testCanBeBurntBatchByBurnerRoleWithoutReason, testCanBeBurntBatchByBurnerRole, testCannotBeBurntBatchIfOneBalanceExceeds, testCannotBatchBurnIfLengthMismatchMissingAddresses, testCannotBatchBurnIfLengthMismatchTooManyAddresses, testCanBeBatchBurnEvenIfContractIsPaused, testCannotBeBatchBurnIfContractIsDeactivated, testCannotBeBatchBurnIfToIsFrozen, testCannotBatchBurnFromNoWhitelistedAddress"
+contracts/modules/wrapper/controllers/ValidationModule.sol;43;"from == address(0)";"from != address(0)";True;"testAdminCanFreezeAddress, testAdminCanBatchFreezeAddress, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testEnforcerRoleCanUnfreezeAddress, testCannotTransferTokenWhenSpenderIsFrozenWithTransferFrom, testCannotTransferTokenWhenPausedWithTransfer, testCannotTransferTokenWhenPausedWithTransferFrom, testCanTransferReturnsFalseForBurnFromFrozenAddress, testCannotBurnFromUnWhitelistedAddress, testCannotTransferTokenWhenSpenderIsNotAllowlistWithTransferFrom"
+contracts/modules/wrapper/controllers/ValidationModule.sol;60;"from == address(0)";"from != address(0)";True;"testCannotBeBurnIfAddressIsFrozen, testCanBeBurnAndMintEvenIFContractIsPaused, testCannotBeBatchBurnIfToIsFrozen, testCanBeMintedEvenIfContractIsPaused, testCannotBeMintedIfContractIsDeactivated, testCanBeMintedBatchEvenIfContractIsPaused, testCannotBeBatchMintedIfContractIsDeactivated, testCannotBeBatchTransferIfContractIsPaused, testCannotBeBatchMTransferIfContractIsDeactivated, testCannotTransferWhenFromIsFrozenWithTransfer, testCannotTransferTokenWhenSpenderIsFrozenWithTransferFrom, testCanBePausedByAdmin, testCanBePausedByPauserRole, testCannotTransferTokenWhenPausedWithTransfer, testCannotTransferTokenWhenPausedWithTransferFrom, testCanDeactivatedByAdminIfContractIsPaused, testCannotBeBurnFromIfAccountIsFrozen, testCanBeMintedByAdmin, testCanMintByANewMinter, testCanBeMintedWithReasonByAdmin, testCanMintWithReasonByANewMinter, testCanBeMintedBatchByAdmin, testCanBeMintBatchdByANewMinter, testCannotBeBatchMintedIfToIsFrozen, testCannotTransferWhenFromIsNotAllowlistWithTransfer, testCannotBatchBurnFromNoWhitelistedAddress, testCannotBurnFromUnWhitelistedAddress, testCannotTransferTokenWhenSpenderIsNotAllowlistWithTransferFrom, testCannotTransferIfContractIsPaused"
+contracts/modules/wrapper/controllers/ValidationModule.sol;79;"PauseModule.deactivated() || EnforcementModule.isFrozen(target)";"PauseModule.deactivated() && EnforcementModule.isFrozen(target)";True;"testCanTransferReturnsFalseForMintToFrozenAddress, testCanTransferReturnsFalseForBurnFromFrozenAddress"
+contracts/modules/wrapper/controllers/ValidationModule.sol;115;"EnforcementModule.isFrozen(spender) || EnforcementModule.isFrozen(from) || EnforcementModule.isFrozen(to)";"EnforcementModule.isFrozen(spender) && EnforcementModule.isFrozen(from) && EnforcementModule.isFrozen(to)";True;"testAdminCanFreezeAddress, testAdminCanBatchFreezeAddress, testAdminCanBatchPartialFreezeAddress, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testEnforcerRoleCanUnfreezeAddress, testCannotTransferTokenWhenSpenderIsFrozenWithTransferFrom"
+contracts/modules/wrapper/controllers/ValidationModule.sol;147;"_canTransferisFrozen(spender, from, to) || PauseModule.paused()";"_canTransferisFrozen(spender, from, to) && PauseModule.paused()";True;"testAdminCanFreezeAddress, testAdminCanBatchFreezeAddress, testAdminCanBatchPartialFreezeAddress, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testEnforcerRoleCanUnfreezeAddress, testCannotTransferTokenWhenSpenderIsFrozenWithTransferFrom, testCannotTransferTokenWhenPausedWithTransfer, testCannotTransferTokenWhenPausedWithTransferFrom, testCanDeactivatedByAdminIfContractIsPaused"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;24;"0x9d8059a24cb596f1948a937c2c163cf14465c2a24abfd3cd009eec4ac4c39800";"0x0";False;""
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;34;"ERC20EnforcementModuleStorage storage $";"ERC20EnforcementModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;37;"value < frozenTokensLocal";"value > frozenTokensLocal";True;"testAdminCanFreezeAddress, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testEnforcerRoleCanUnfreezeAddress, testCannotTransferMoreThanActiveBalance, testCanTransferTokenIfActiveBalanceIsEnough, testCannotTransferFromTokenIfActiveBalanceIsNotEnough"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;38;"frozenTokensLocal - value";"frozenTokensLocal + value";True;"testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanUnfreezeAddress, testEnforcerRoleCanUnfreezeAddress"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;43;"value - frozenTokensLocal";"value + frozenTokensLocal";True;"testAdminCanFreezeAddressWithTokenFrozenDifferentMore"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;53;"ERC20EnforcementModuleStorage storage $";"ERC20EnforcementModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;56;"$._frozenTokens[account] + value";"$._frozenTokens[account] - value";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testCannotNonEnforcerUnfreezeAddress, testCannotTransferMoreThanActiveBalance, testCanTransferTokenIfActiveBalanceIsEnough, testCannotTransferFromTokenIfActiveBalanceIsNotEnough, testAdminCanFreezeAddressWithTokenFrozen, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;58;"balance >= frozenTokensLocal";"balance < frozenTokensLocal";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testCannotNonEnforcerUnfreezeAddress, testCannotTransferMoreThanActiveBalance, testCanTransferTokenIfActiveBalanceIsEnough, testCannotTransferFromTokenIfActiveBalanceIsNotEnough, testAdminCanFreezeAddressWithTokenFrozen, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;65;"ERC20EnforcementModuleStorage storage $";"ERC20EnforcementModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;66;"$._frozenTokens[account] >= value";"$._frozenTokens[account] < value";True;"testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;68;"$._frozenTokens[account] - value";"$._frozenTokens[account] + value";True;"testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;78;"value > balance";"value < balance";True;"testCanForceTransferFromAddress1ToAddress2AsAdmin, testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowanceToZero, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance, testCanForceBurnWithForceTransferAsAdmin, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutReason, testCannotForceTransferFromAddress1ToAddress2IfBalanceNotEnough"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;81;"ERC20EnforcementModuleStorage storage $";"ERC20EnforcementModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;83;"balance - $._frozenTokens[account]";"balance + $._frozenTokens[account]";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;84;"value > activeBalance";"value < activeBalance";True;"testCanForceTransferFromAddress1ToAddress2AsAdmin, testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowanceToZero, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance, testCanForceBurnWithForceTransferAsAdmin, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutReason"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;85;"value - activeBalance";"value + activeBalance";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;86;"$._frozenTokens[account] - tokensToUnfreeze";"$._frozenTokens[account] + tokensToUnfreeze";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;94;"to == address(0)";"to != address(0)";True;"testCanForceTransferFromAddress1ToAddress2AsAdmin, testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowanceToZero, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance, testCanForceBurnWithForceTransferAsAdmin, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutReason"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;100;"currentAllowance > 0 && currentAllowance < type(uint256).max";"currentAllowance > 0 || currentAllowance < type(uint256).max";False;""
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;100;"currentAllowance < type(uint256).max";"currentAllowance > type(uint256).max";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowanceToZero, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance, reverts when trying to schedule a snapshot in the past"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;100;"currentAllowance > 0";"currentAllowance < 0";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowanceToZero, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;101;"currentAllowance < value";"currentAllowance > value";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowanceToZero, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;107;"currentAllowance - value";"currentAllowance + value";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;114;"emit Enforcement(_msgSender(), from, value, data);";"";True;"testCanForceTransferFromAddress1ToAddress2AsAdmin, testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowanceToZero, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance, testCanForceBurnWithForceTransferAsAdmin, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutReason"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;115;"emit ForcedTransfer(from, to, value);";"";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowanceToZero, testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance, testCanForceBurnWithForceTransferAsAdmin, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutReason"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;119;"emit TokensFrozen(account, difference, data);";"";True;"testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testAdminCanFreezeAddressWithTokenFrozenDifferentMore"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;120;"emit IERC7943FungibleEnforcementEventAndError.Frozen(account, frozenTokens);";"";True;"testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testAdminCanFreezeAddressWithTokenFrozenDifferentMore"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;124;"emit TokensUnfrozen(account, difference, data);";"";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testAdminCanFreezeAddressWithTokenFrozenDifferentLess"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;125;"emit IERC7943FungibleEnforcementEventAndError.Frozen(account, frozenTokens );";"";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testAdminCanFreezeAddressWithTokenFrozenDifferentLess"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;141;"frozenTokensLocal > 0";"frozenTokensLocal < 0";True;"testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testCannotTransferMoreThanActiveBalance, testCannotTransferFromTokenIfActiveBalanceIsNotEnough, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;143;"ERC20Upgradeable.balanceOf(from) - frozenTokensLocal";"ERC20Upgradeable.balanceOf(from) + frozenTokensLocal";True;"testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testCannotTransferMoreThanActiveBalance, testCannotTransferFromTokenIfActiveBalanceIsNotEnough, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;144;"value > activeBalance";"value < activeBalance";True;"testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testCannotTransferMoreThanActiveBalance, testCannotTransferFromTokenIfActiveBalanceIsNotEnough, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore"
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;154;"ERC20EnforcementModuleStorage storage $";"ERC20EnforcementModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;159;"ERC20EnforcementModuleStorage storage $";"ERC20EnforcementModuleStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol;160;"ERC20Upgradeable.balanceOf(account) - $._frozenTokens[account]";"ERC20Upgradeable.balanceOf(account) + $._frozenTokens[account]";True;"testCanForceTransferFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testCanForceTransferFromAddress1ToAddress2AsAdminWithoutUnfreezeTokens, testCanForceTransferBurnFromAddress1ToAddress2AsAdminAndUnfreezeTokens, testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testEnforcerRoleCanUnfreezeAddress, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore"
+contracts/modules/2_CMTATBaseAllowlist.sol;53;") public virtual initializer";") public virtual";False;""
+contracts/modules/2_CMTATBaseAllowlist.sol;69;") internal virtual onlyInitializing";") internal virtual";False;""
+contracts/modules/2_CMTATBaseAllowlist.sol;87;"function __CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes memory ERC20Attributes_) internal virtual onlyInitializing";"function __CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes memory ERC20Attributes_) internal virtual";False;""
+contracts/modules/2_CMTATBaseAllowlist.sol;98;"function __CMTAT_modules_init_unchained(address admin, ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, ICMTATConstructor.ExtraInformationAttributes memory ExtraInformationAttributes_ ) internal virtual onlyInitializing";"function __CMTAT_modules_init_unchained(address admin, ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, ICMTATConstructor.ExtraInformationAttributes memory ExtraInformationAttributes_ ) internal virtual";False;""
+contracts/modules/2_CMTATBaseAllowlist.sol;119;"function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool)";"function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) returns (bool)";True;"testCannotApproveIfPaused"
+contracts/modules/2_CMTATBaseAllowlist.sol;132;"!isValid";"isValid";True;"testCannotTransferTokenWhenPausedWithTransferFrom, testAdminCanBatchPartialFreezeAddress, testAdminCanUnfreezeAddress, testEnforcerRoleCanUnfreezeAddress, testCanCanTransferWithoutRuleEngine, testCanDetectTransferRestrictionValidTransfer, testCanTransferAllowed, testCanTransfer, testAdminCanFreezeAddress, testAdminCanFreezeAddressTwice, testEnforcerRoleCanFreezeAddress, testAdminCanUnfreezeAddressAndTransferMoreActiveBalance, testAdminCanUnfreezeAddressTwice, testAdminCanFreezeAddressReason, testEnforcerRoleCanFreezeAddressReason, testAdminCanUnfreezeAddressReason, testEnforcerRoleCanUnfreezeAddressReason, testCanTransferTokenIfActiveBalanceIsEnough, testCannotTransferFromTokenIfActiveBalanceIsNotEnough, testAdminCanFreezeAddressWithTokenFrozenDifferentLess, testAdminCanFreezeAddressWithTokenFrozenDifferentMore, testAdminCanAllowlistAddress, testAdminCanBatchAllowlistAddress, testAdminCanBatchPartialAllowlistAddress, testEnforcerRoleCanAllowlistAddress, testCanBurnFromWhitelistedAddress, testCannotBurnFromUnWhitelistedAddress"
+contracts/modules/2_CMTATBaseAllowlist.sol;150;"!isValid";"isValid";True;"testCannotTransferTokenWhenPausedWithTransferFrom, testCanTransferTokenIfActiveBalanceIsEnough, testCannotTransferFromTokenIfActiveBalanceIsNotEnough, testCanTransferTokenWithTransferFrom"
+contracts/modules/2_CMTATBaseAllowlist.sol;162;"function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE)";"function _authorizePause() internal virtual override(PauseModule)";True;"testCannotBePausedByNonPauser, testCannotBeUnpausedByNonPauser"
+contracts/modules/2_CMTATBaseAllowlist.sol;163;"function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE)";"function _authorizeDeactivate() internal virtual override(PauseModule)";True;"testCannotBeDeactivatedByNonAdmin"
+contracts/modules/2_CMTATBaseAllowlist.sol;165;"function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE)";"function _authorizeFreeze() internal virtual override(EnforcementModule)";True;"testCannotNonEnforcerFreezeAddress, testCannotNonEnforcerBatchFreezeAddress, testCannotNonEnforcerUnfreezeAddress"
+contracts/modules/2_CMTATBaseAllowlist.sol;167;"function _authorizeAllowlistManagement() internal virtual override(AllowlistModule) onlyRole(ALLOWLIST_ROLE)";"function _authorizeAllowlistManagement() internal virtual override(AllowlistModule)";True;"testCannotNonEnforcerAllowlistAddress, testCannotNonEnforcerBatchAllowlistAddress, testCannotNonEnforcerUnWhitelistAddress"
+contracts/modules/internal/EnforcementModuleInternal.sol;21;"0x0c7bc8a17be064111d299d7669f49519cb26c58611b72d9f6ccc40a1e1184e00";"0x0";False;""
+contracts/modules/internal/EnforcementModuleInternal.sol;33;"EnforcementModuleInternalStorage storage $";"EnforcementModuleInternalStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/internal/EnforcementModuleInternal.sol;43;"EnforcementModuleInternalStorage storage $";"EnforcementModuleInternalStorage memory $";True;"Failed to compile after introducing mutation."
+contracts/modules/internal/EnforcementModuleInternal.sol;54;"EnforcementModuleInternalStorage storage $";"EnforcementModuleInternalStorage memory $";True;"Failed to compile after introducing mutation."
\ No newline at end of file
diff --git a/docs/olympix/report.md b/docs/olympix/report.md
new file mode 100644
index 00000000..abb28164
--- /dev/null
+++ b/docs/olympix/report.md
@@ -0,0 +1,149 @@
+# Olympix Security Verification — CMTAT
+
+**Target:** [`CMTA/CMTAT`](https://github.com/CMTA/CMTAT) · security-token / RWA tokenization framework
+**Commit:** `49544f4d` · **Branch:** `master` · **Date:** 16–17 July 2026 UTC
+**Toolchain:** Olympix BugPoCer · Mutation Testing · Symbolic-execution Fuzzing
+
+> This page is a presentation-format demo: it collects three independent Olympix runs against CMTAT into a single reviewable surface. Every number links back to a shipped artifact (findings JSON, mutation CSV, runnable PoC tests).
+
+---
+
+## At a glance
+
+| Tool | What it measured | Headline result |
+|------|------------------|-----------------|
+| **BugPoCer** | End-to-end exploit generation across the codebase | **21 true-positive findings** — 2 High · 7 Medium · 12 Low |
+| **Mutation testing** | Does the existing test suite actually catch bugs? | **87.1% killed** (81 / 93 mutants) — 10 of 12 survivors are equivalent mutants |
+| **Fuzzing (symbolic)** | Adversarial reachability across the core surface | **35,188 paths → 27,252 feasible**, 0 exploitable path found in this run |
+
+---
+
+## BugPoCer — exploit-driven findings
+
+BugPoCer decomposes the codebase into units, explores reachable paths, and for each candidate issue attempts to write a **runnable Foundry/Hardhat PoC that fails on the vulnerable code**. Only confirmed true positives are listed below.
+
+**Severity breakdown:** 2 High · 7 Medium · 12 Low — **21 total**
+
+| # | Sev | Finding | Location | PoC |
+|---|-----|---------|----------|-----|
+| 1 | High | Missing deactivation guard on `forcedBurn` | `modules/0_CMTATBaseCore.sol` | [runnable](./tests/olympix/pocs/missing_deactivation_guard.t.sol) |
+| 2 | High | Unchecked over-frozen balance underflow | `modules/wrapper/extensions/ERC20EnforcementModule.sol` | documented |
+| 3 | Med | Burn operator-context bypass | `modules/wrapper/options/ERC20CrossChainModule.sol` | [runnable](./tests/olympix/pocs/burn_operator_context_bypass.t.sol) |
+| 4 | Med | Incomplete mint validation | `modules/0_CMTATBaseCommon.sol` | [runnable](./tests/olympix/pocs/incomplete_mint_validation.t.sol) |
+| 5 | Med | Missing zero-address validation (batch freeze) | `modules/internal/common/EnforcementModuleLibrary.sol` | [runnable](./tests/olympix/pocs/missing_zero_address_validation.t.sol) |
+| 6 | Med | Over-frozen balance transfer DoS | `modules/6_CMTATBaseERC1363.sol` | documented |
+| 7 | Med | Snapshot hook runs after state update | `modules/0_CMTATBaseCommon.sol` | documented |
+| 8 | Med | Unchecked frozen-token cap | `modules/wrapper/core/EnforcementModule.sol` | documented |
+| 9 | Med | Unchecked over-frozen balance | `modules/wrapper/core/EnforcementModule.sol` | documented |
+| 10 | Low | `approve` missing pause protection | `modules/0_CMTATBaseCore.sol` | [runnable](./tests/olympix/pocs/approve_missing_pause_protection.t.sol) |
+| 11 | Low | Over-frozen balance accounting corruption | `modules/wrapper/extensions/ERC20EnforcementModule.sol` | [runnable](./tests/olympix/pocs/overfrozen_balance_accounting_corruption.t.sol) |
+| 12 | Low | Inconsistent compliance view | `modules/wrapper/controllers/ValidationModule.sol` | [runnable](./tests/olympix/pocs/inconsistent_compliance_view.t.sol) |
+| 13 | Low | Zero-address transfer validation mismatch | `modules/wrapper/core/ValidationModuleCore.sol` | [runnable](./tests/olympix/pocs/zero_address_transfer_validation_mismatch.t.sol) |
+| 14 | Low | View / validation mismatch | `modules/wrapper/controllers/ValidationModule.sol` | documented |
+| 15 | Low | Incomplete predicate view | `modules/wrapper/controllers/ValidationModule.sol` | documented |
+| 16 | Low | External-call DoS | `modules/0_CMTATBaseCommon.sol` | documented |
+| 17 | Low | Cross-interface event inconsistency | `modules/wrapper/extensions/ExtraInformationModule.sol` | documented |
+| 18 | Low | Rule-engine setter invariant mismatch | `modules/internal/ValidationModuleRuleEngineInternal.sol` | documented |
+| 19 | Low | Misleading burn-authority surface | `modules/wrapper/core/ERC20BurnModule.sol` | documented |
+| 20 | Low | Misleading access-control docs (CCIP) | `modules/wrapper/options/ERC20CrossChainModule.sol` | documented |
+| 21 | Low | Misleading access-control docs (enforcer) | `modules/wrapper/core/EnforcementModule.sol` | documented |
+
+
+High #1 — Missing deactivation guard on forcedBurn
+
+**Location:** `contracts/modules/0_CMTATBaseCore.sol` — `forcedBurn()`
+
+`forcedBurn` can still reduce balances and `totalSupply` **after the token has been permanently deactivated**. Normal burn paths route through `_burnOverride()`, which calls the validation module and rejects a deactivated contract. `forcedBurn` deliberately skips that path and calls `ERC20Upgradeable._burn()` directly after only checking that the account is frozen. After `pause()` + `deactivateContract()`, a `DEFAULT_ADMIN_ROLE` holder can freeze an account and destroy its tokens — despite the deactivation guarantee that burn operations stop permanently.
+
+**PoC:** [`pocs/missing_deactivation_guard.t.sol`](./tests/olympix/pocs/missing_deactivation_guard.t.sol) — mints to a holder, pauses, deactivates, confirms the normal `burn()` reverts with `EnforcedDeactivation`, then shows `forcedBurn()` still succeeds (assertion fails on the vulnerable code).
+
+
+
+High #2 — Unchecked over-frozen balance underflow
+
+**Location:** `contracts/modules/internal/ERC20EnforcementModuleInternal.sol` — `_checkActiveBalance()` / `_setFrozenTokens()`
+
+Active-balance logic assumes `frozenTokens(account) <= balanceOf(account)` and subtracts directly, but the absolute `setFrozenTokens` / `_setFrozenTokens` path can write an arbitrary frozen amount without enforcing that cap. An over-frozen account makes `_checkActiveBalance`, `getActiveBalanceOf`, transfer/burn validation, forced-transfer recovery, and `canTransfer` reads revert via arithmetic underflow until a privileged correction. Setting a nonzero frozen amount for `address(0)` is especially damaging: mint validation treats `address(0)` as the source, so ordinary and cross-chain minting can be **globally bricked**.
+
+**Cross-signal:** this same enforcement-arithmetic surface is the most heavily mutated file (see mutation section) — 33/35 mutants killed, confirming the tests exercise it, while BugPoCer shows the *absolute-set* path is the one that escapes the cap invariant.
+
+
+**Findings source:** `.opix/agent/24c6f02a-…/findings.json` · **Session:** `24c6f02a-cca3-43b5-853f-d84b2bcef93c`
+
+---
+
+## Mutation testing
+
+Mutation testing measures whether the existing test suite actually *detects* bugs by injecting small faults and checking that a test fails ("kills" the mutant).
+
+**Overall: 81 / 93 killed — `87.1%`** · Session `6b2c6237-f5d3-42fb-addb-f505c5bb78c2`
+
+| File | Killed / Total | Score |
+|------|----------------|-------|
+| `4_CMTATBaseERC20CrossChain.sol` | 6 / 6 | 100% |
+| `ERC20BurnModuleInternal.sol` | 2 / 2 | 100% |
+| `ValidationModule.sol` | 5 / 5 | 100% |
+| `ERC20EnforcementModuleInternal.sol` | 33 / 35 | 94.3% |
+| `ValidationModuleRuleEngine.sol` | 7 / 8 | 87.5% |
+| `ERC20BaseModule.sol` | 12 / 14 | 85.7% |
+| `PauseModule.sol` | 6 / 8 | 75.0% |
+| `EnforcementModuleInternal.sol` | 3 / 4 | 75.0% |
+| `2_CMTATBaseAllowlist.sol` | 7 / 11 | 63.6% |
+
+
+Surviving mutants (12) — 10 equivalent, 2 worth a look
+
+Most survivors are **equivalent mutants** (semantically identical — cannot be killed by any test):
+
+| Location | Mutation | Why it survives |
+|----------|----------|-----------------|
+| `ERC20BaseModule.sol:28`, `ERC20EnforcementModuleInternal.sol:24`, `EnforcementModuleInternal.sol:21` | ERC-7201 storage-slot constant → `0x0` | Slot constant; value never asserted in tests |
+| `ERC20BaseModule.sol:54`, `2_CMTATBaseAllowlist.sol:53/69/87/98` | remove `initializer`/`onlyInitializing` | Init guards; tests never double-initialize |
+| `PauseModule.sol:69/104` | `storage $` → `memory $` | Read-only access; no observable difference |
+
+**Worth a look (2):**
+
+| Location | Mutation | Note |
+|----------|----------|------|
+| `ValidationModuleRuleEngine.sol:141` | `spender != address(0)` → `== address(0)` | Zero-address branch not covered — **corroborates BugPoCer #5 (missing zero-address validation)** |
+| `ERC20EnforcementModuleInternal.sol:100` | `&&` → `\|\|` in allowance-cap check | `currentAllowance > 0 && < max` boundary not asserted |
+
+
+
+**Raw data:** [`mutation-results.csv`](./docs/olympix/mutation_testing/mutation-results.csv)
+
+---
+
+## Fuzzing — symbolic-execution-driven
+
+The engine performs whole-contract symbolic execution, keeps only SMT-feasible paths, and (per attack strategy) turns them into concrete adversarial Foundry tests.
+
+**Session `f37cd9fe-cb1e-4732-821a-03c6811416dc` · 6 min wall-clock**
+
+| Contract | Paths | Feasible | Exploits |
+|----------|-------|----------|----------|
+| `CMTATStandalone` | 19,974 | 15,518 | 0 |
+| `CMTATUpgradeable` | 8,138 | 5,910 | 0 |
+| `CMTATStandaloneAllowlist` | 7,076 | 5,824 | 0 |
+| **Total** | **35,188** | **27,252** | **0** |
+
+The engine enumerated 35,188 execution paths across the 3 highest-value deployment variants and kept the 27,252 SMT-feasible ones. Guarded entry points were unreachable to an unauthorized caller — a positive signal, not a coverage gap.
+
+> **Maturity note (honest framing):** this run exercised **0 adversarial attack strategies** — that is the fuzz engine's *current* concrete-test-generation set (it is under active development; more strategies and deeper multi-call sequences land each release). So the "0 exploits" result here is a **floor on the path-reachability signal, not a proof of security**. Treat it as reachability coverage, not negative assurance, until the strategy set matures.
+
+---
+
+## Artifacts & reproducibility
+
+| Artifact | Source |
+|----------|--------|
+| BugPoCer report | [`BugPoCer_Scan_Report_CMTAT.pdf`](./docs/olympix/bugpocer/BugPoCer_Scan_Report_CMTAT.pdf) (43 pp) |
+| Mutation results | [`mutation-results.csv`](./docs/olympix/mutation_testing/mutation-results.csv) (93 mutants) |
+| Fuzz report | [`Fuzz_Test_Report.pdf`](./docs/olympix/fuzz_testing/Fuzz_Test_Report_f37cd9fe-cb1e-4732-821a-03c6811416dc_20260716_182652.pdf) (7 pp) |
+| Runnable PoCs | [`tests/olympix/pocs/`](./tests/olympix/pocs/) — 8 confirmed exploit tests |
+
+| Run | Session ID |
+|-----|-----------|
+| BugPoCer | `24c6f02a-cca3-43b5-853f-d84b2bcef93c` |
+| Mutation | `6b2c6237-f5d3-42fb-addb-f505c5bb78c2` |
+| Fuzz | `f37cd9fe-cb1e-4732-821a-03c6811416dc` |
diff --git a/tests/olympix/pocs/approve_missing_pause_protection.t.sol b/tests/olympix/pocs/approve_missing_pause_protection.t.sol
new file mode 100644
index 00000000..2a7f93dd
--- /dev/null
+++ b/tests/olympix/pocs/approve_missing_pause_protection.t.sol
@@ -0,0 +1,25 @@
+const { expect } = require('chai')
+const { ethers } = require('hardhat')
+
+const TERMS = [
+ 'doc1',
+ 'https://example.com/doc1',
+ '0x6a12eff2f559a5e529ca2c563c53194f6463ed5c61d1ae8f8731137467ab0279'
+]
+const ZERO = ethers.ZeroAddress
+
+/*
+ * Vulnerability: approve missing pause protection (CMTATBaseCore / Light approve()).
+ * The Light deployment does not gate approve with whenNotPaused, so allowances can be
+ * created while the token is paused, unlike the full variants.
+ */
+describe('PoC: Light approve() is callable while paused', function () {
+ it('approve must revert while the contract is paused', async function () {
+ const [deployer, admin, holder, spender] = await ethers.getSigners()
+ const cmtat = await ethers.deployContract('CMTATStandaloneLight', [admin.address, ['CMTA Token', 'CMTAT', 0]])
+ await cmtat.waitForDeployment()
+ await cmtat.connect(admin).pause()
+ // FIXED: approve reverts while paused. VULNERABLE: it succeeds -> assertion FAILS.
+ await expect(cmtat.connect(holder).approve(spender.address, 100n)).to.be.reverted
+ })
+})
diff --git a/tests/olympix/pocs/burn_operator_context_bypass.t.sol b/tests/olympix/pocs/burn_operator_context_bypass.t.sol
new file mode 100644
index 00000000..683c54b1
--- /dev/null
+++ b/tests/olympix/pocs/burn_operator_context_bypass.t.sol
@@ -0,0 +1,101 @@
+const { expect } = require('chai')
+const { ethers } = require('hardhat')
+const {
+ deployCMTATStandalone,
+ fixture,
+ loadFixture
+} = require('../deploymentUtils')
+
+const VALUE = 10n
+
+describe('PoC - burnFrom drops operator context before RuleEngine validation', function () {
+ async function deployFixture () {
+ const accounts = await loadFixture(fixture)
+ const cmtat = await deployCMTATStandalone(
+ accounts._.address,
+ accounts.admin.address,
+ accounts.deployerAddress.address
+ )
+
+ const holder = accounts.address2
+ const recipient = accounts.address3
+ const authorizedSpender = accounts.address1
+ const unauthorizedBurner = accounts.attacker
+
+ // RuleEngineMock rejects canTransferFrom/transferred(spender, ...) for every
+ // non-zero spender except `authorizedSpender`, while allowing the
+ // no-operator canTransfer/transferred(from, ...) path for VALUE.
+ const RuleEngineMock = await ethers.getContractFactory('RuleEngineMock')
+ const ruleEngine = await RuleEngineMock.deploy(authorizedSpender.address)
+ await ruleEngine.waitForDeployment()
+
+ await cmtat.connect(accounts.admin).setRuleEngine(await ruleEngine.getAddress())
+
+ const burnerFromRole = await cmtat.BURNER_FROM_ROLE()
+ await cmtat.connect(accounts.admin).grantRole(burnerFromRole, unauthorizedBurner.address)
+
+ await cmtat.connect(accounts.admin).mint(holder.address, VALUE)
+ await cmtat.connect(holder).approve(unauthorizedBurner.address, VALUE)
+
+ return {
+ cmtat,
+ ruleEngine,
+ holder,
+ recipient,
+ authorizedSpender,
+ unauthorizedBurner
+ }
+ }
+
+ it('should reject burnFrom when the RuleEngine rejects the actual burner/spender', async function () {
+ const {
+ cmtat,
+ ruleEngine,
+ holder,
+ recipient,
+ unauthorizedBurner
+ } = await loadFixture(deployFixture)
+
+ // Sanity check: the configured RuleEngine explicitly rejects this operator.
+ expect(
+ await ruleEngine.canTransferFrom(
+ unauthorizedBurner.address,
+ holder.address,
+ ethers.ZeroAddress,
+ VALUE
+ )
+ ).to.equal(false)
+
+ // The token's spender-aware pre-check also reports that this burn-from
+ // should be non-compliant.
+ expect(
+ await cmtat.canTransferFrom(
+ unauthorizedBurner.address,
+ holder.address,
+ ethers.ZeroAddress,
+ VALUE
+ )
+ ).to.equal(false)
+
+ // Sibling path check: ordinary transferFrom carries _msgSender() into the
+ // validation pipeline, so the same unauthorized operator is rejected.
+ await expect(
+ cmtat
+ .connect(unauthorizedBurner)
+ .transferFrom(holder.address, recipient.address, VALUE)
+ )
+ .to.be.revertedWithCustomError(ruleEngine, 'RuleEngine_InvalidTransfer')
+ .withArgs(holder.address, recipient.address, VALUE)
+
+ // Security expectation: burnFrom must be validated with the real spender as
+ // well. On vulnerable code this DOES NOT revert: burnFrom spends the
+ // allowance and CMTATBaseCommon._burnOverride calls _checkTransferred with
+ // spender = address(0), selecting RuleEngine.transferred(from, to, value)
+ // instead of transferred(spender, from, to, value).
+ await expect(
+ cmtat.connect(unauthorizedBurner).burnFrom(holder.address, VALUE)
+ )
+ .to.be.revertedWithCustomError(ruleEngine, 'RuleEngine_InvalidTransfer')
+ .withArgs(holder.address, ethers.ZeroAddress, VALUE)
+ })
+})
diff --git a/tests/olympix/pocs/incomplete_mint_validation.t.sol b/tests/olympix/pocs/incomplete_mint_validation.t.sol
new file mode 100644
index 00000000..ce60445d
--- /dev/null
+++ b/tests/olympix/pocs/incomplete_mint_validation.t.sol
@@ -0,0 +1,27 @@
+const { expect } = require('chai')
+const { ethers } = require('hardhat')
+
+const TERMS = [
+ 'doc1',
+ 'https://example.com/doc1',
+ '0x6a12eff2f559a5e529ca2c563c53194f6463ed5c61d1ae8f8731137467ab0279'
+]
+const ZERO = ethers.ZeroAddress
+
+/*
+ * Vulnerability: incomplete mint validation via base _checkTransferred (CMTATBaseCommon._mintOverride).
+ * Mint validation runs _checkTransferred(address(0), address(0), to, value); over-freezing the
+ * address(0) sentinel makes the active-balance check underflow and bricks every mint path.
+ */
+describe('PoC: freezing address(0) bricks minting through base validation', function () {
+ it('mint must still succeed when a benign frozen amount is set on address(0)', async function () {
+ const [deployer, admin, forwarder, holder] = await ethers.getSigners()
+ const cmtat = await ethers.deployContract('CMTATStandalone', [
+ forwarder.address, admin.address, ['CMTA Token', 'CMTAT', 0], ['CMTAT_ISIN', TERMS, 'CMTAT_info'], [ZERO]
+ ])
+ await cmtat.waitForDeployment()
+ await cmtat.connect(admin).setFrozenTokens(ZERO, 1n)
+ // FIXED: mint succeeds (sentinel ignored). VULNERABLE: mint reverts -> assertion FAILS.
+ await expect(cmtat.connect(admin).mint(holder.address, 10n)).to.not.be.reverted
+ })
+})
diff --git a/tests/olympix/pocs/inconsistent_compliance_view.t.sol b/tests/olympix/pocs/inconsistent_compliance_view.t.sol
new file mode 100644
index 00000000..99722e64
--- /dev/null
+++ b/tests/olympix/pocs/inconsistent_compliance_view.t.sol
@@ -0,0 +1,26 @@
+const { expect } = require('chai')
+const { ethers } = require('hardhat')
+
+const TERMS = [
+ 'doc1',
+ 'https://example.com/doc1',
+ '0x6a12eff2f559a5e529ca2c563c53194f6463ed5c61d1ae8f8731137467ab0279'
+]
+const ZERO = ethers.ZeroAddress
+
+/*
+ * Vulnerability: inconsistent compliance view (ValidationModule._canTransferGenericByModule).
+ * A zero-to-zero request is classified as a mint and can return true even though it is not a
+ * valid transfer, so canTransfer reports an impossible movement as compliant.
+ */
+describe('PoC: canTransfer reports a zero-to-zero movement as valid', function () {
+ it('canTransfer(address(0), address(0), 1) must be false', async function () {
+ const [deployer, admin, forwarder] = await ethers.getSigners()
+ const cmtat = await ethers.deployContract('CMTATStandalone', [
+ forwarder.address, admin.address, ['CMTA Token', 'CMTAT', 0], ['CMTAT_ISIN', TERMS, 'CMTAT_info'], [ZERO]
+ ])
+ await cmtat.waitForDeployment()
+ // FIXED: false. VULNERABLE: true -> assertion FAILS.
+ expect(await cmtat.canTransfer(ZERO, ZERO, 1n)).to.equal(false)
+ })
+})
diff --git a/tests/olympix/pocs/missing_deactivation_guard.t.sol b/tests/olympix/pocs/missing_deactivation_guard.t.sol
new file mode 100644
index 00000000..b0c1a718
--- /dev/null
+++ b/tests/olympix/pocs/missing_deactivation_guard.t.sol
@@ -0,0 +1,60 @@
+const { expect } = require('chai')
+const { ethers } = require('hardhat')
+const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers')
+const { deployCMTATLightStandalone } = require('../deploymentUtils')
+
+// PoC for contracts/modules/0_CMTATBaseCore.sol:CMTATBaseCore.forcedBurn()
+// CMTATStandaloneLight is the concrete deployment artifact that inherits CMTATBaseCore
+// and exposes forcedBurn().
+describe('CMTATBaseCore forcedBurn deactivation guard PoC', function () {
+ const INITIAL_SUPPLY = 50n
+ const BURN_AMOUNT = 20n
+ const REASON = '0x'
+
+ async function deployFixture () {
+ const [deployer, admin, holder] = await ethers.getSigners()
+ const cmtat = await deployCMTATLightStandalone(
+ admin.address,
+ deployer.address
+ )
+ await cmtat.waitForDeployment()
+
+ return { cmtat, admin, holder }
+ }
+
+ it('should not allow forcedBurn to reduce balances or totalSupply after deactivateContract()', async function () {
+ const { cmtat, admin, holder } = await loadFixture(deployFixture)
+
+ // Arrange: mint tokens to a holder, then permanently deactivate the token.
+ await cmtat.connect(admin).mint(holder.address, INITIAL_SUPPLY)
+ expect(await cmtat.balanceOf(holder.address)).to.equal(INITIAL_SUPPLY)
+ expect(await cmtat.totalSupply()).to.equal(INITIAL_SUPPLY)
+
+ await cmtat.connect(admin).pause()
+ await cmtat.connect(admin).deactivateContract()
+ expect(await cmtat.paused()).to.equal(true)
+ expect(await cmtat.deactivated()).to.equal(true)
+
+ // Sanity check: the normal burn path routes through _burnOverride(), which
+ // calls ValidationModule._canMintBurnByModuleAndRevert() and rejects a
+ // deactivated contract.
+ await expect(cmtat.connect(admin).burn(holder.address, 1n))
+ .to.be.revertedWithCustomError(cmtat, 'EnforcedDeactivation')
+
+ // The holder can still be frozen after deactivation; forcedBurn only checks
+ // this frozen flag and then calls ERC20Upgradeable._burn() directly.
+ await cmtat.connect(admin).setAddressFrozen(holder.address, true)
+ expect(await cmtat.isFrozen(holder.address)).to.equal(true)
+
+ // Security expectation: deactivation guarantees burn operations stop
+ // permanently, so forcedBurn should also revert with EnforcedDeactivation.
+ // On the vulnerable implementation this transaction succeeds, reducing both
+ // holder balance and totalSupply, so this assertion fails and proves the bug.
+ await expect(cmtat.connect(admin).forcedBurn(holder.address, BURN_AMOUNT, REASON))
+ .to.be.revertedWithCustomError(cmtat, 'EnforcedDeactivation')
+
+ // These post-conditions are reachable only on a fixed implementation.
+ expect(await cmtat.balanceOf(holder.address)).to.equal(INITIAL_SUPPLY)
+ expect(await cmtat.totalSupply()).to.equal(INITIAL_SUPPLY)
+ })
+})
diff --git a/tests/olympix/pocs/missing_zero_address_validation.t.sol b/tests/olympix/pocs/missing_zero_address_validation.t.sol
new file mode 100644
index 00000000..f4895fb0
--- /dev/null
+++ b/tests/olympix/pocs/missing_zero_address_validation.t.sol
@@ -0,0 +1,66 @@
+const { expect } = require('chai')
+const { ethers } = require('hardhat')
+const {
+ deployCMTATLightStandalone,
+ fixture,
+ loadFixture
+} = require('../deploymentUtils')
+
+// PoC for contracts/modules/internal/common/EnforcementModuleLibrary.sol:_checkInput().
+// The vulnerable batch freeze path accepts address(0). In CMTATBaseCore.transfer(),
+// direct ERC20 transfers validate with address(0) as the spender sentinel, so a frozen
+// zero address makes every direct transfer fail even though the token is not paused.
+describe('PoC - batch freeze of address(0) disables direct transfers', function () {
+ async function deployFixture () {
+ const ctx = await fixture()
+ const cmtat = await deployCMTATLightStandalone(
+ ctx.admin.address,
+ ctx.deployerAddress.address
+ )
+ return { ...ctx, cmtat }
+ }
+
+ it('does not let ENFORCER_ROLE globally block direct transfers by freezing address(0)', async function () {
+ const { cmtat, admin, address1, address2 } = await loadFixture(deployFixture)
+
+ // Arrange: admin is the default admin and is implicitly authorized to mint/freeze.
+ // A normal holder-to-holder direct transfer succeeds before the zero-address freeze.
+ await cmtat.connect(admin).mint(address1.address, 100n)
+ await expect(cmtat.connect(address1).transfer(address2.address, 1n))
+ .to.emit(cmtat, 'Transfer')
+ .withArgs(address1.address, address2.address, 1n)
+
+ // Act: attempt the exact vulnerable batch path. A fixed implementation should
+ // reject address(0) here; if so, direct transfers remain available and the test passes.
+ let zeroAddressFreezeAccepted = false
+ try {
+ await cmtat
+ .connect(admin)
+ .batchSetAddressFrozen([ethers.ZeroAddress], [true])
+ zeroAddressFreezeAccepted = true
+ } catch (e) {
+ zeroAddressFreezeAccepted = false
+ }
+
+ if (!zeroAddressFreezeAccepted) {
+ expect(await cmtat.isFrozen(ethers.ZeroAddress)).to.equal(false)
+ await expect(cmtat.connect(address1).transfer(address2.address, 1n))
+ .to.emit(cmtat, 'Transfer')
+ .withArgs(address1.address, address2.address, 1n)
+ return
+ }
+
+ // Vulnerable state: address(0) was written into the frozen-address mapping/list,
+ // while the global pause switch remains off. This should not be enough to stop
+ // ordinary direct ERC20 transfers; if it is, the ENFORCER_ROLE has bypassed PAUSER_ROLE.
+ expect(await cmtat.isFrozen(ethers.ZeroAddress)).to.equal(true)
+ expect(await cmtat.paused()).to.equal(false)
+
+ // Secure expectation: targeted account freezing must not globally disable all direct
+ // transfers. On the vulnerable code this assertion fails because transfer() uses
+ // address(0) as the spender sentinel and ValidationModule rejects frozen spenders.
+ await expect(cmtat.connect(address1).transfer(address2.address, 1n))
+ .to.emit(cmtat, 'Transfer')
+ .withArgs(address1.address, address2.address, 1n)
+ })
+})
diff --git a/tests/olympix/pocs/overfrozen_balance_accounting_corruption.t.sol b/tests/olympix/pocs/overfrozen_balance_accounting_corruption.t.sol
new file mode 100644
index 00000000..b607bb6c
--- /dev/null
+++ b/tests/olympix/pocs/overfrozen_balance_accounting_corruption.t.sol
@@ -0,0 +1,28 @@
+const { expect } = require('chai')
+const { ethers } = require('hardhat')
+
+const TERMS = [
+ 'doc1',
+ 'https://example.com/doc1',
+ '0x6a12eff2f559a5e529ca2c563c53194f6463ed5c61d1ae8f8731137467ab0279'
+]
+const ZERO = ethers.ZeroAddress
+
+/*
+ * Vulnerability: overfrozen balance accounting corruption (ERC20EnforcementModule.setFrozenTokens).
+ * setFrozenTokens writes the ABSOLUTE frozen amount without the `value <= balanceOf(account)`
+ * cap that _freezePartialTokens enforces, so getActiveBalanceOf underflows (Panic 0x11).
+ */
+describe('PoC: setFrozenTokens above balance corrupts active-balance accounting', function () {
+ it('a frozen amount greater than the balance must not brick getActiveBalanceOf', async function () {
+ const [deployer, admin, forwarder, holder] = await ethers.getSigners()
+ const cmtat = await ethers.deployContract('CMTATStandalone', [
+ forwarder.address, admin.address, ['CMTA Token', 'CMTAT', 0], ['CMTAT_ISIN', TERMS, 'CMTAT_info'], [ZERO]
+ ])
+ await cmtat.waitForDeployment()
+ await cmtat.connect(admin).mint(holder.address, 50n)
+ await cmtat.connect(admin).setFrozenTokens(holder.address, 100n)
+ // FIXED: getActiveBalanceOf returns a bounded value. VULNERABLE: 50-100 underflows -> assertion FAILS.
+ await expect(cmtat.getActiveBalanceOf(holder.address)).to.not.be.reverted
+ })
+})
diff --git a/tests/olympix/pocs/zero_address_transfer_validation_mismatch.t.sol b/tests/olympix/pocs/zero_address_transfer_validation_mismatch.t.sol
new file mode 100644
index 00000000..3bcdf150
--- /dev/null
+++ b/tests/olympix/pocs/zero_address_transfer_validation_mismatch.t.sol
@@ -0,0 +1,26 @@
+const { expect } = require('chai')
+const { ethers } = require('hardhat')
+
+const TERMS = [
+ 'doc1',
+ 'https://example.com/doc1',
+ '0x6a12eff2f559a5e529ca2c563c53194f6463ed5c61d1ae8f8731137467ab0279'
+]
+const ZERO = ethers.ZeroAddress
+
+/*
+ * Vulnerability: zero-address transfer validation mismatch (ValidationModuleCore.canTransfer).
+ * canTransfer does not reject zero-address endpoints; a zero `from` is treated as a mint and
+ * can return true for an impossible ERC-20 transfer.
+ */
+describe('PoC: canTransfer reports a zero-from transfer as valid', function () {
+ it('canTransfer(address(0), holder, 1) must be false', async function () {
+ const [deployer, admin, forwarder, holder] = await ethers.getSigners()
+ const cmtat = await ethers.deployContract('CMTATStandalone', [
+ forwarder.address, admin.address, ['CMTA Token', 'CMTAT', 0], ['CMTAT_ISIN', TERMS, 'CMTAT_info'], [ZERO]
+ ])
+ await cmtat.waitForDeployment()
+ // FIXED: false (invalid endpoint). VULNERABLE: true -> assertion FAILS.
+ expect(await cmtat.canTransfer(ZERO, holder.address, 1n)).to.equal(false)
+ })
+})