Purpose: Knowledge library of security threats relevant to Bloxchain Protocol
Last Updated: April 11, 2026
Status: Living Knowledge Base
This codex serves as a comprehensive knowledge base of attack vectors identified in the Bloxchain Protocol. Each entry includes attack descriptions, current protections, severity classifications, and verification requirements. This document consolidates information from security analysis documents and serves as the authoritative reference for security threats.
Line numbers and file paths: Many entries cite Contract.sol:start-end line ranges from earlier snapshots. Solidity files evolve; treat line numbers as approximate. Prefer locating logic by function name (e.g. EngineBlox.verifySignature, BaseStateMachine._validateMetaTxHandlerBinding) or your editor’s symbol search. Authoritative behavior is always contracts/core/ (and linked experimental paths) plus NatSpec.
Total Attack Vectors: 190+
Critical Severity: 14
High Severity: 36
Medium Severity: 64
Low Severity: 43
Informational: 30+
- Access Control & Authorization
- Meta-Transaction Security
- State Machine & Transaction Lifecycle
- Reentrancy Attacks
- Input Validation & Data Manipulation
- Payment & Economic Security
- Composite & Multi-Vector Attacks
- Cryptographic & Signature Attacks
- Time-Based Attacks
- Role Management
- Target Whitelist & Function Schema
- Initialization & Upgrade
- Hook System
- Event Forwarding & Monitoring
- Definition Contracts & Schema Security
- New Attack Vectors (2026 Security Analysis)
- Gas Exhaustion & System Limits
- Protocol-Vulnerabilities-Index Derived Vectors
- AgentArena Audit-Derived Vectors (April 2026)
- ID:
AC-001 - Location:
EngineBlox.sol:765-789,RuntimeRBAC.sol:242-248 - Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Attempts to modify protected roles (OWNER, BROADCASTER, RECOVERY) through batch operations or direct modification.
Attack Scenario:
// Attacker creates batch action to ADD_WALLET to OWNER_ROLE
RoleConfigAction[] memory actions = new RoleConfigAction[](1);
actions[0] = RoleConfigAction({
actionType: RoleConfigActionType.ADD_WALLET,
data: abi.encode(OWNER_ROLE, attackerAddress)
});
executeRoleConfigBatch(actions);Current Protection:
- ✅ Protected role check at
RuntimeRBAC.sol:246-248 - ✅ Protected role check at
EngineBlox.sol:773-775(removeRole) - ✅ Protected role check at
EngineBlox.sol:864-866(revokeWallet) - ✅ Batch operations validate protected roles before execution
Verification:
- Test batch operations with protected role modification
- Test direct protected role modification attempts
- Verify
CannotModifyProtectederror is raised
Related Tests:
testFuzz_CannotAddWalletToProtectedRoleViaBatchtestFuzz_CannotRevokeLastWalletFromProtectedRoletestFuzz_CannotRemoveProtectedRoletest_BatchWithProtectedRoleModification
- ID:
AC-002 - Location:
EngineBlox.sol:858-873 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Attempting to remove the last wallet from a protected role, which would lock out legitimate access.
Attack Scenario:
// OWNER_ROLE has only one wallet (owner)
// Attacker attempts to revoke the owner wallet
revokeWallet(OWNER_ROLE, ownerAddress);
// Should fail - cannot remove last wallet from protected roleCurrent Protection:
- ✅ Check at line 864-866:
if (roleData.isProtected && roleData.authorizedWallets.length() <= 1) - ✅ Reverts with
CannotModifyProtected
Verification:
- Test with protected role containing exactly 1 wallet
- Test with protected role containing 2 wallets (remove one, then attempt to remove last)
- Test concurrent removal attempts
Related Tests:
testFuzz_CannotRevokeLastWalletFromProtectedRole
- ID:
AC-003 - Location:
EngineBlox.sol:946-966,EngineBlox.sol:1949-1964 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Manipulating function selectors to gain unauthorized permissions through handler selector relationships.
Attack Scenario:
// Attacker creates role with permission for function A
// Function A has handlerForSelectors pointing to function B
// Attacker gains indirect access to function B
// Step 1: Create function schema for A with handler pointing to B
createFunctionSchema("functionA()", FUNCTION_A_SELECTOR, "OPERATION_A",
bitmap(SIGN_META_APPROVE), false, [FUNCTION_B_SELECTOR]);
// Step 2: Create role with permission for A
addFunctionToRole(roleHash, FunctionPermission({
functionSelector: FUNCTION_A_SELECTOR,
grantedActionsBitmap: SIGN_META_APPROVE,
handlerForSelectors: [FUNCTION_B_SELECTOR]
}));Current Protection:
- ✅
_validateHandlerForSelectorschecks handler relationships - ✅ Handler selectors must exist in schema's
handlerForSelectorsarray - ✅ Protected functions cannot be accessed via handlers
Verification:
- Test handler selector validation in
addFunctionToRole - Test that handlers cannot point to protected functions
- Test complete attack chain
Related Tests:
testFuzz_HandlerSelectorValidationPreventsEscalation
- ID:
AC-004 - Location:
EngineBlox.sol:1974-2011 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Execution selectors use self-reference in handlerForSelectors. Non-execution selectors should not be able to use self-reference.
Attack Scenario:
// Attacker creates handler function schema (not execution)
// Attempts to add permission with self-reference
addFunctionToRole(roleHash, FunctionPermission({
functionSelector: HANDLER_SELECTOR,
grantedActionsBitmap: SIGN_META_APPROVE,
handlerForSelectors: [HANDLER_SELECTOR] // Self-reference - should fail
}));Current Protection:
- ✅ Line 1992-1995: Self-reference allowed only for execution selectors
- ✅ Validation checks if handler selector matches function selector (self-reference)
- ✅ Non-execution selectors cannot use self-reference
Verification:
- Test that non-execution selectors cannot use self-reference
- Test execution selector self-reference (should be allowed)
- Test handler selector pointing to execution (should be allowed)
Related Tests:
testFuzz_SelfReferenceOnlyForExecutionSelectors
- ID:
AC-005 - Location:
EngineBlox.sol:946-966 - Severity: HIGH
- Status:
⚠️ INTENTIONAL BEHAVIOR
Description:
Wallet with multiple roles accumulates permissions across all roles (OR logic), potentially exceeding intended security model.
Attack Scenario:
// Wallet has Role1 with permission for function A
// Wallet also has Role2 with permission for function B
// Combined, wallet has access to both A and B
// This is actually correct behavior (OR logic), but might be unexpected
// if roles are meant to be mutually exclusiveCurrent Behavior:
- ✅ Permission check iterates all roles (OR logic)
- ✅ If wallet has ANY role with permission, access granted
⚠️ This is intentional design, but consider if AND logic needed for critical operations
Verification:
- Test wallet with multiple roles
- Verify wallet can access all functions from all roles
- Test if this matches intended security model
Related Tests:
testFuzz_PermissionAccumulationAcrossRoles
- ID:
AC-006 - Location:
RuntimeRBAC.sol:208-302 - Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Batch operations must be atomic - if any action fails, all actions should be reverted. This prevents partial execution that could leave system in inconsistent state.
Attack Scenario:
// Batch with multiple actions
RoleConfigAction[] memory actions = new RoleConfigAction[](2);
// Action 1: Valid operation (should succeed)
actions[0] = RoleConfigAction({
actionType: CREATE_ROLE,
data: abi.encode("VALID_ROLE", 10, permissions)
});
// Action 2: Invalid operation (should fail)
actions[1] = RoleConfigAction({
actionType: ADD_WALLET,
data: abi.encode(OWNER_ROLE, wallet) // Protected role - should fail
});
// If batch is not atomic, Action 1 might execute even though Action 2 fails
executeRoleConfigBatch(actions);Current Protection:
- ✅ Batch operations use try-catch for error handling
- ✅ Failed actions cause entire batch to revert
- ✅ State changes are atomic
Verification:
- Test batch with valid action followed by invalid action
- Verify valid action does NOT execute if invalid action fails
- Test batch with multiple invalid actions
- Verify complete rollback on failure
Related Tests:
testFuzz_BatchOperationAtomicitytest_BatchWithProtectedRoleModificationtestFuzz_BatchWithMultipleProtectedRoleAttempts
- ID:
AC-007 - Location:
EngineBlox.sol:809-823 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Bypassing maxWallets limit through concurrent operations or race conditions.
Attack Scenario:
// Role has maxWallets = 10, currently has 9 wallets
// Attacker submits multiple ADD_WALLET transactions simultaneously
// Race condition might allow exceeding maxWallets limitCurrent Protection:
- ✅
validateWalletLimitchecks before adding - ✅ Check happens before state modification
Verification:
- Test concurrent wallet additions
- Test adding wallet when at limit
- Verify
WalletLimitExceedederror
Related Tests:
testFuzz_RoleWalletLimitEnforced
- ID:
AC-008 - Location:
EngineBlox.sol:809-823 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Attempting to add the same wallet to a role multiple times.
Attack Scenario:
// Wallet already in role
// Attacker attempts to add same wallet again
assignWallet(roleHash, existingWallet);Current Protection:
- ✅
ItemAlreadyExistserror if wallet already in role - ✅ Check happens before state modification
Verification:
- Test adding duplicate wallet
- Verify
ItemAlreadyExistserror
Related Tests:
testFuzz_CannotAddDuplicateWallet
- ID:
AC-009 - Location:
EngineBlox.sol:731-757 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Creating role with name that hashes to protected role hash.
Attack Scenario:
// Attacker finds string that hashes to OWNER_ROLE
// Attempts to create role with that name
createRole("collision_string", 10, permissions);
// Should fail if hash matches protected roleCurrent Protection:
- ✅ Protected roles created during initialization
- ✅ Role name hashing unlikely to collide with protected roles
⚠️ Consider explicit protected role name list
Verification:
- Test role name collision attempts
- Verify protected roles cannot be recreated
Related Tests:
testFuzz_CannotCreateRoleWithProtectedRoleName
- ID:
MT-001 - Location:
EngineBlox.sol:1507-1548,EngineBlox.sol:1477 - Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Replaying a valid signature from one blockchain network on another network with a different chainId.
Attack Scenario:
// Attacker captures valid meta-transaction signature on Ethereum Mainnet (chainId = 1)
MetaTransaction memory metaTx = {
params: {
chainId: 1, // Ethereum Mainnet
// ... other params
},
signature: validSignature // Signed for chainId = 1
};
// Attacker attempts to replay on Polygon (chainId = 137)
// Modify chainId in params
metaTx.params.chainId = 137; // Polygon
// Execute on Polygon - should fail chain ID validationCurrent Protection:
- ✅
validateChainId(metaTx.params.chainId)at line 1477 - ✅ Domain separator includes
block.chainidat line 1518 - ✅ Signature verification includes chainId in message hash
Verification:
- Test signature replay with different chain IDs
- Verify
ChainIdMismatcherror - Test with correct chainId (should succeed)
Related Tests:
testFuzz_CrossChainSignatureReplayPrevented
- ID:
MT-002 - Location:
EngineBlox.sol:1446-1457,EngineBlox.sol:1484 - Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Reusing nonces to replay transactions before nonce increments.
Attack Scenario:
// Attacker captures meta-transaction with nonce N
// Replays transaction before nonce increments
// Double-spend or duplicate execution
MetaTransaction memory metaTx1 = createMetaTx(nonce: N);
MetaTransaction memory metaTx2 = createMetaTx(nonce: N); // Same nonce
// Execute both - second should fail
executeMetaTransaction(metaTx1); // Succeeds, nonce becomes N+1
executeMetaTransaction(metaTx2); // Should fail - nonce mismatchCurrent Protection:
- ✅ Nonce incremented BEFORE execution (line 1456)
- ✅ Nonce validation checks current nonce matches expected
- ✅
InvalidNonceerror if nonce mismatch
Verification:
- Test nonce increment timing
- Test nonce replay attempts
- Verify nonce increments before external calls
Related Tests:
testFuzz_NonceReplayPreventedtestFuzz_NonceIncrementsBeforeExecutiontestFuzz_ConcurrentNonceUsagePreventedtestFuzz_NoncePredictionReplayPrevented
- ID:
MT-003 - Location:
EngineBlox.sol:1556-1587,SharedValidation.sol:212-217 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
ECDSA signature malleability (s-value manipulation) allowing creation of different valid signatures for the same message.
Attack Scenario:
// Attacker modifies s-value to create different valid signature
// Original signature: (r, s, v)
// Malleable signature: (r, secp256k1_order - s, v)
// Both signatures are valid for same messageCurrent Protection:
- ✅
validateSignatureParamschecks s-value - ✅ S-value must be <= secp256k1_order / 2
- ✅ Prevents signature malleability
Verification:
- Test signature with modified s-value
- Verify signature validation rejects malleable signatures
Related Tests:
testFuzz_SignatureMalleabilityPrevented
- ID:
MT-004 - Location:
EngineBlox.sol:1507-1548 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Manipulating EIP-712 message hash components after signing to change transaction details while keeping signature valid.
Attack Scenario:
// Attacker modifies txRecord or metaTxParams after signing
// Different message hash but same signature
// Attempts to execute with modified parametersCurrent Protection:
- ✅ Signature verified against complete message hash
- ✅ Message hash includes all transaction parameters
- ✅ Any modification invalidates signature
Verification:
- Test signature with modified message components
- Verify signature validation fails
Related Tests:
testFuzz_MessageHashManipulationPrevented
- ID:
MT-005 - Location:
EngineBlox.sol:1478,EngineBlox.sol:1700 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Executing meta-transactions after deadline expiration.
Attack Scenario:
// Meta-transaction with deadline in past
MetaTransaction memory metaTx = {
params: {
deadline: block.timestamp - 1 hour, // Expired
// ... other params
}
};
// Attempt to execute - should failCurrent Protection:
- ✅
validateMetaTxDeadlinechecks expiration - ✅ Reverts if
block.timestamp > deadline
Verification:
- Test expired meta-transactions
- Verify deadline enforcement
Related Tests:
testFuzz_ExpiredMetaTransactionRejected
- ID:
MT-006 - Location:
EngineBlox.sol:1481,SharedValidation.sol:357-364 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Exceeding maxGasPrice limit in meta-transaction parameters.
Attack Scenario:
// Meta-transaction with gas price exceeding limit
MetaTransaction memory metaTx = {
params: {
maxGasPrice: 1000 gwei, // Exceeds limit
// ... other params
}
};
// Attempt to execute - should failCurrent Protection:
- ✅
validateGasPricecheck - ✅ Reverts if gas price exceeds limit
Verification:
- Test with gas price exceeding limit
- Verify
GasPriceExceedsMaxerror
Related Tests:
testFuzz_GasPriceLimitEnforced
- ID:
MT-008 - Finding: AgentArena #1 (mitigated). Same underlying issue as AUDIT-001 (§19.1).
- Location:
BaseStateMachine.sol:_validateMetaTxHandlerBinding,SharedValidation.sol:validateMetaTxHandlerSelectorBinding,validateMetaTxHandlerContractBinding,EngineBlox.sol:verifySignature(handler contract binding) - Severity: HIGH (matches AgentArena Finding 1 and
AUDIT-001; high impact if unmitigated — now protected) - Status: ✅ PROTECTED
Description:
A meta-tx signed for one public wrapper (handlerSelector / EIP-712 intent) must not be executable through another sibling entrypoint with different checks (e.g. routing a role-config batch signature through a guard-config batch function).
Current Protection:
- ✅ Wrapper enforces
metaTx.params.handlerSelector == bytes4(msg.sig)before engine work - ✅ Library enforces
metaTx.params.handlerContract == address(this)inverifySignature - ✅ Custom errors
MetaTxHandlerSelectorMismatch,MetaTxHandlerContractMismatch
Related Tests:
testFuzz_Finding1_HandlerSelectorMismatchRejectedtestFuzz_Finding1_HandlerMismatch_GuardSignedRoleSubmittedtestFuzz_Finding1_HandlerContractMismatchRejected
- ID:
MT-007 - Location:
EngineBlox.sol:1556-1587 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Rejecting meta-transactions with invalid signatures (wrong signer, corrupted signature, etc.).
Attack Scenario:
// Meta-transaction with signature from wrong signer
MetaTransaction memory metaTx = {
params: {
signer: owner,
// ... other params
},
signature: attackerSignature // Signed by attacker, not owner
};
// Attempt to execute - should failCurrent Protection:
- ✅ Signature verification checks recovered signer matches
params.signer - ✅ Invalid signatures cause revert
Verification:
- Test with signatures from wrong signer
- Test with corrupted signatures
- Test with invalid signature length
Related Tests:
testFuzz_InvalidSignatureRejectedtestFuzz_InvalidSignatureLengthRejected
- ID:
SM-001 - Location:
EngineBlox.sol:360-378,EngineBlox.sol:387-399,EngineBlox.sol:426-457 - Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Race condition where concurrent approval and cancellation operations on the same transaction might both succeed, leading to inconsistent state.
Attack Scenario:
// Transaction txId is PENDING
// Attacker submits two transactions simultaneously:
// Transaction 1: Approve
approveTransaction(txId);
// Transaction 2: Cancel (submitted in same block)
cancelTransaction(txId);
// Both check status is PENDING (both pass)
// Both attempt to modify status
// Race condition - which one wins?Current Protection:
- ✅ Status check at line 367, 394, 443:
_validateTxStatus(self, txId, TxStatus.PENDING) - ✅ Status updated to EXECUTING/CANCELLED before external calls
- ✅ Second operation fails with
TransactionStatusMismatch
Verification:
- Test concurrent approval and cancellation
- Verify only one succeeds
- Verify second fails with
TransactionStatusMismatch
Related Tests:
testFuzz_ConcurrentApprovalCancellationPrevented
- ID:
SM-002 - Location:
EngineBlox.sol:1928-1937 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Bypassing required status transitions by attempting invalid transitions.
Attack Scenario:
// Transaction is in EXECUTING status
// Attacker attempts to approve again
approveTransaction(txId); // Should fail - not PENDING
// Or transaction is COMPLETED
// Attacker attempts to cancel
cancelTransaction(txId); // Should fail - not PENDINGCurrent Protection:
- ✅
_validateTxStatusenforces expected status - ✅ Status transitions are one-way: PENDING → EXECUTING → (COMPLETED/FAILED)
- ✅ Status transitions: PENDING → CANCELLED
Verification:
- Test status transition enforcement
- Test invalid status transitions
- Verify
TransactionStatusMismatcherror
Related Tests:
testFuzz_InvalidStatusTransitionPrevented
- ID:
SM-003 - Location:
EngineBlox.sol:360-378,EngineBlox.sol:186 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Approving transaction before time-lock expires, bypassing security delay.
Attack Scenario:
// Transaction requested with time-lock
uint256 txId = requestTransaction(...);
// releaseTime = block.timestamp + timeLockPeriod
// Attacker attempts to approve immediately
approveTransaction(txId); // Should fail - time-lock not expiredCurrent Protection:
- ✅
validateReleaseTimecheck at line 186 - ✅ Reverts with
BeforeReleaseTimeifblock.timestamp < releaseTime
Verification:
- Test premature approval attempts
- Verify time-lock enforcement
- Test approval after time-lock expires
Related Tests:
testFuzz_PrematureApprovalPrevented
- ID:
RE-001 - Location:
EngineBlox.sol:502-534 - Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Reentrancy through target contract callback during transaction execution.
Attack Scenario:
// Target contract calls back into state machine
contract MaliciousTarget {
function execute() external {
// Reenter state machine
stateMachine.approveTimeLockExecution(otherTxId);
// Bypass state machine protection
}
}
// Transaction executes target contract
// Target contract reenters state machine
// Attempts to bypass protectionCurrent Protection:
- ✅ Status set to EXECUTING before external call (line 503)
- ✅ Reentrant calls see EXECUTING status, not PENDING
- ✅ Reentrant operations fail status check
Verification:
- Test reentrancy through target contract
- Verify status-based protection
- Test multiple reentrant calls
Related Tests:
testFuzz_TargetReentrancyPrevented
- ID:
RE-002 - Location:
EngineBlox.sol:550-590 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Reentrancy through payment recipient during payment execution.
Attack Scenario:
// Payment recipient is malicious contract
contract MaliciousRecipient {
receive() external payable {
// Reenter state machine
stateMachine.approveTimeLockExecution(txId);
}
}
// Payment sent to malicious recipient
// Recipient reenters during payment
// Attempts to bypass protectionCurrent Protection:
- ✅ Status is PROCESSING_PAYMENT during payment
- ✅ Reentrant calls see PROCESSING_PAYMENT status
- ✅ Reentrant operations fail status check
Verification:
- Test reentrancy through payment recipient
- Verify payment protection
- Test with malicious payment recipient
Related Tests:
testFuzz_PaymentRecipientReentrancyPrevented
- ID:
RE-003 - Location:
EngineBlox.sol:588 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Reentrancy through malicious ERC20 token during safeTransfer.
Attack Scenario:
// ERC20 token calls back during safeTransfer
contract MaliciousERC20 {
function transfer(address to, uint256 amount) external returns (bool) {
// Reenter state machine
stateMachine.approveTimeLockExecution(txId);
return true;
}
}
// ERC20 payment sent
// Token contract reenters during transfer
// Attempts to bypass protectionCurrent Protection:
- ✅ SafeERC20 library used
- ✅ Status-based protection prevents reentrancy
- ✅ Try-catch handles token failures
Verification:
- Test with malicious ERC20 token
- Verify reentrancy protection
- Test token transfer failures
Related Tests:
testFuzz_ERC20TokenReentrancyPrevented
- ID:
SM-004 - Location:
EngineBlox.sol:246-249,SecureOwnable.sol:296-303 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Reducing time-lock period to bypass security delay.
Attack Scenario:
// Attacker updates time-lock to very short period
updateTimeLockPeriod(1); // 1 second instead of 24 hours
// Bypass intended security delayCurrent Protection:
- ✅ Time-lock update requires owner approval
- ✅ Time-lock updates are time-locked themselves
- ✅ Requires proper authorization
Verification:
- Test time-lock period updates
- Verify authorization requirements
- Test minimum time-lock period
Related Tests:
testFuzz_TimeLockPeriodManipulationPrevented
- ID:
SM-005 - Location:
EngineBlox.sol:638,EngineBlox.sol:186 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Miner manipulation of block.timestamp to accelerate time-lock expiration.
Attack Scenario:
// Miner manipulates timestamp to accelerate time-lock
// releaseTime = block.timestamp + timeLockPeriod
// Miner sets block.timestamp to future value
// Time-lock appears expiredCurrent Protection:
- ✅ Time-lock periods should be sufficiently long (24+ hours)
- ✅ Miner can only manipulate ~15 seconds per block
- ✅ Long time-lock periods prevent meaningful manipulation
Verification:
- Test with manipulated timestamps
- Verify time-lock still enforced
- Test with maximum timestamp manipulation
Related Tests:
testFuzz_BlockTimestampManipulationLimited
- ID:
SM-006 - Location:
EngineBlox.sol:508-511,EngineBlox.sol:516 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Manipulating gas limit to cause execution failure or out-of-gas errors.
Attack Scenario:
// Attacker sets very low gas limit
requestTransaction(target, value, selector, params, 1000, operationType);
// Transaction fails due to out-of-gas
// Status marked as FAILED instead of revertingCurrent Protection:
- ✅ Transaction execution handles out-of-gas gracefully
- ✅ Status updated to FAILED on execution failure
- ✅ State remains consistent
Verification:
- Test with various gas limits
- Test with insufficient gas
- Verify graceful failure handling
Related Tests:
testFuzz_GasLimitManipulationHandled
- ID:
SM-007 - Location:
EngineBlox.sol:516-518,EngineBlox.sol:528-530 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Target contract reverts to manipulate state or cause unexpected behavior.
Attack Scenario:
// Target contract always reverts
contract RevertingTarget {
function execute() external {
revert("Always fails");
}
}
// Transaction executes target
// Target reverts
// State machine should handle gracefullyCurrent Protection:
- ✅ State machine updates status to FAILED
- ✅ Revert reason captured in
resultfield - ✅ State remains consistent
Verification:
- Test with reverting target contracts
- Verify graceful failure handling
- Test with various revert reasons
Related Tests:
testFuzz_TargetContractRevertHandled
- ID:
SM-008 - Location:
EngineBlox.sol:563-565,EngineBlox.sol:580-582 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Executing payment with insufficient contract balance.
Attack Scenario:
// Transaction with payment exceeding contract balance
requestTransaction(target, value, selector, params, gasLimit, operationType);
updatePayment(txId, PaymentDetails({
nativeTokenAmount: 1000 ether, // Exceeds balance
// ...
}));
// Attempt to execute - should failCurrent Protection:
- ✅ Balance check before payment (line 563-565, 580-582)
- ✅ Reverts with
InsufficientBalanceif balance insufficient
Verification:
- Test with insufficient balance
- Verify
InsufficientBalanceerror - Test with exact balance
Related Tests:
testFuzz_InsufficientBalanceHandled
[See Section 3.2 for reentrancy attack vectors]
- ID:
IV-001 - Location: Multiple locations using
validateNotZeroAddress - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Injecting zero address (address(0)) in parameters where it's not expected.
Attack Scenarios:
- Role wallet assignment:
assignWallet(roleHash, address(0)) - Target address in transaction:
requestTransaction(address(0), ...) - Meta-transaction signer:
metaTx.params.signer = address(0)
Current Protection:
- ✅
validateNotZeroAddressused extensively - ✅ Comprehensive zero address checks
Verification:
- Test all functions with
address(0)input - Verify
InvalidAddresserror
Related Tests:
testFuzz_ZeroAddressInjectionPreventedtestFuzz_ZeroAddressInRoleAssignment
- ID:
IV-002 - Location:
EngineBlox.sol:775,RuntimeRBAC.sol:208-302 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Manipulating array lengths in batch operations to cause gas exhaustion.
Attack Scenario:
// Attacker provides very large arrays
RoleConfigAction[] memory actions = new RoleConfigAction[](10000);
// Gas exhaustion or out-of-gas attacksCurrent Protection:
- ✅ Gas limits prevent excessive operations
- ✅ Reasonable array size limits in tests
Verification:
- Test with maximum array sizes
- Test with very large arrays
- Verify gas limits
Related Tests:
testFuzz_ArrayLengthManipulationHandledtestFuzz_ArrayLengthMismatchPrevented
- ID:
IV-003 - Location:
EngineBlox.sol:1410-1414 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Accessing array elements beyond bounds using invalid indices.
Attack Scenario:
// Array has 5 elements (indices 0-4)
// Attacker provides index 10
getWalletsInRole(roleHash)[10]; // Out of boundsCurrent Protection:
- ✅
validateIndexInBoundscheck - ✅ Index validation before access
Verification:
- Test with invalid indices
- Test with negative indices (if applicable)
- Verify bounds checking
Related Tests:
testFuzz_ArrayIndexOutOfBoundsPrevented
- ID:
IV-004 - Location:
RuntimeRBAC.sol:208-302 - Severity: MEDIUM
- Status:
⚠️ ALLOWED
Description:
Exploiting empty arrays in batch operations (no-op execution).
Attack Scenario:
// Attacker submits empty batch
RoleConfigAction[] memory actions = new RoleConfigAction[](0);
executeRoleConfigBatch(actions);
// No-op execution but consumes gasCurrent Protection:
⚠️ Empty batches are allowed (intentional)- ✅ No state changes occur
Verification:
- Test empty batch operations
- Verify no state changes
- Test gas consumption
Related Tests:
testFuzz_EmptyArrayHandled
- ID:
IV-005 - Location:
EngineBlox.sol:731-757 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Very long role names causing gas issues or storage problems.
Attack Scenario:
// Attacker provides extremely long role name
string memory longName = "A" * 10000; // Very long string
createRole(longName, 10, permissions);
// Gas exhaustionCurrent Protection:
- ✅ Reasonable length limits in tests
- ✅ Gas limits prevent excessive operations
Verification:
- Test with maximum length strings
- Test with very long strings
- Verify gas limits
Related Tests:
testFuzz_RoleNameLengthHandled
- ID:
IV-006 - Location:
EngineBlox.sol:1029-1088 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Manipulating function signatures to bypass validation.
Attack Scenario:
// Attacker provides signature that doesn't match selector
createFunctionSchema("wrongSignature()", SELECTOR, ...);
// Should fail - signature must match selectorCurrent Protection:
- ✅ Signature must match selector
- ✅
FunctionSelectorMismatcherror if mismatch
Verification:
- Test with mismatched signatures
- Verify signature validation
Related Tests:
testFuzz_FunctionSignatureValidation
- ID:
IV-007 - Location: Multiple locations
- Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Using zero function selector (bytes4(0)) to bypass validation.
Attack Scenario:
// Attacker uses zero selector
requestTransaction(target, value, bytes4(0), params, ...);
// Should fail validationCurrent Protection:
- ✅ Zero selector validation
- ✅
ZeroOperationTypeNotAllowedor similar error
Verification:
- Test with zero selectors
- Verify validation
Related Tests:
testFuzz_ZeroFunctionSelectorPrevented
- ID:
IV-008 - Location: Multiple locations
- Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Using zero operation type (bytes32(0)) to bypass validation.
Attack Scenario:
// Attacker uses zero operation type
requestTransaction(target, value, selector, params, gasLimit, bytes32(0));
// Should fail validationCurrent Protection:
- ✅ Zero operation type validation
- ✅
ZeroOperationTypeNotAllowederror
Verification:
- Test with zero operation types
- Verify validation
Related Tests:
testFuzz_ZeroOperationTypePrevented
- ID:
IV-009 - Location:
EngineBlox.sol:246-249 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Manipulating time-lock period to extreme values (very small or very large).
Attack Scenario:
// Attacker sets time-lock to 0 or very large value
updateTimeLockPeriod(0); // No delay
updateTimeLockPeriod(type(uint256).max); // Overflow riskCurrent Protection:
- ✅ Solidity 0.8.34 overflow protection
- ✅ Reasonable bounds in tests
Verification:
- Test with extreme time-lock values
- Test with zero time-lock
- Verify bounds
Related Tests:
testFuzz_TimeLockPeriodBounds
- ID:
IV-010 - Location:
EngineBlox.sol:731-757 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Setting maxWallets to extreme values (0 or very large).
Attack Scenario:
// Attacker creates role with maxWallets = 0
createRole("ROLE", 0, permissions); // Cannot add any wallets
// Or maxWallets = type(uint256).max
createRole("ROLE", type(uint256).max, permissions); // No limitCurrent Protection:
- ✅ Reasonable bounds in tests
- ✅ Wallet limit enforcement
Verification:
- Test with extreme maxWallets values
- Verify wallet limit enforcement
Related Tests:
testFuzz_MaxWalletsValidation
- ID:
PAY-001 - Location:
EngineBlox.sol:697-707 - Severity: HIGH
- Status:
⚠️ REQUIRES VERIFICATION
Description:
Updating payment recipient after transaction request to redirect funds to attacker address.
Attack Scenario:
// Legitimate transaction request
uint256 txId = requestTransaction(...);
// Attacker updates payment recipient (if has permission)
updatePaymentForTransaction(txId, PaymentDetails({
recipient: attackerAddress, // Redirect to attacker
nativeTokenAmount: 10 ether,
// ...
}));
// Transaction executes, payment goes to attackerCurrent Protection:
- ✅ Payment update requires PENDING status
⚠️ CRITICAL: Need to verify who can update payments⚠️ CRITICAL: Need to verify payment update permissions
Verification:
- Test payment recipient updates
- Verify permission requirements
- Test unauthorized payment updates
Related Tests:
testFuzz_PaymentRecipientUpdateAccessControl
- ID:
PAY-002 - Location:
EngineBlox.sol:697-707 - Severity: HIGH
- Status:
⚠️ REQUIRES VERIFICATION
Description:
Manipulating payment amounts to drain contract balance or exceed limits.
Attack Scenario:
// Transaction with initial payment
uint256 txId = requestTransaction(...);
updatePayment(txId, PaymentDetails({
nativeTokenAmount: 1 ether, // Initial amount
// ...
}));
// Attacker updates to excessive amount
updatePayment(txId, PaymentDetails({
nativeTokenAmount: 1000 ether, // Excessive amount
// ...
}));Current Protection:
- ✅ Payment updates require permissions
⚠️ Need to verify amount limits
Verification:
- Test payment amount updates
- Verify amount limits
- Test with excessive amounts
Related Tests:
testFuzz_PaymentAmountManipulationPrevented
- ID:
PAY-003 - Location:
EngineBlox.sol:550-590 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Receiving payment multiple times through transaction replay or duplicate execution.
Attack Scenario:
// Transaction executed multiple times
// Payment sent multiple times
approveTransaction(txId); // First execution
approveTransaction(txId); // Second execution - should failCurrent Protection:
- ✅ Transaction can only execute once
- ✅ Status prevents duplicate execution
Verification:
- Test double execution attempts
- Verify payment sent only once
Related Tests:
testFuzz_DoublePaymentPrevented
- ID:
PAY-004 - Location:
EngineBlox.sol:576-589 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Using malicious ERC20 token address or non-ERC20 contract.
Attack Scenario:
// Attacker sets payment to malicious ERC20
updatePayment(txId, PaymentDetails({
erc20TokenAddress: maliciousContract, // Not ERC20
erc20TokenAmount: 1000,
// ...
}));
// Token contract behaves unexpectedlyCurrent Protection:
- ✅ SafeERC20 library used
- ✅ Try-catch handles token failures
Verification:
- Test with malicious ERC20 tokens
- Test with non-ERC20 contracts
- Verify graceful failure handling
Related Tests:
testFuzz_ERC20TokenAddressValidation
- ID:
PAY-005 - Location:
EngineBlox.sol:562-573 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Draining contract native token balance through multiple transactions with large payments.
Attack Scenario:
// Attacker creates multiple transactions with large native payments
// Each transaction drains balance
// Total payments exceed contract balanceCurrent Protection:
- ✅ Balance check before each payment
- ✅
InsufficientBalanceerror if balance insufficient
Verification:
- Test balance drain scenarios
- Test with multiple transactions
- Verify balance protection
Related Tests:
testFuzz_BalanceDrainPrevented
- ID:
PAY-006 - Location:
EngineBlox.sol:697-707 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Updating payment details just before transaction execution to redirect funds.
Attack Scenario:
// Transaction pending, time-lock about to expire
// Attacker updates payment recipient just before approval
// Payment goes to attacker instead of original recipientCurrent Protection:
- ✅ Payment updates require PENDING status
- ✅ Payment updates require permissions
Verification:
- Test payment update timing
- Verify update restrictions
- Test update just before execution
Related Tests:
testFuzz_PaymentUpdateTiming
- ID:
COMP-001 - Location: Multiple components
- Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Combining multiple vulnerabilities for privilege escalation through a multi-stage attack chain.
Attack Chain:
- Attacker gains low-privilege role
- Exploits function selector manipulation
- Bypasses handler validation
- Gains unauthorized permissions
Current Protection:
- ✅ Handler selector validation prevents escalation
- ✅ Protected functions cannot be accessed via handlers
- ✅ Permission checks validate all components
Verification:
- Test complete attack chain
- Verify each stage is protected
- Test handler validation
Related Tests:
testFuzz_MultiStagePermissionEscalationPrevented
- ID:
COMP-002 - Location:
EngineBlox.sol:360-378,EngineBlox.sol:1477-1548 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Using meta-transactions as a privileged path to approve time-locked transactions, potentially bypassing the time-lock delay if meta-approval is not properly gated by RBAC and schema configuration.
Attack Scenario:
- Attacker (or misconfigured role) requests time-locked transaction
- Immediately signs meta-transaction approval
- Broadcaster executes meta-approval before time-lock expires
- If meta-approval is not properly gated, time-lock protection is effectively bypassed
Current Protection:
- ✅ Meta-transaction approval is gated by dedicated RBAC actions (e.g.
SIGN_META_APPROVE/EXECUTE_META_APPROVE) - ✅ Function schema and target whitelist validation enforced for meta-approval flows
- ✅ Unauthorized or misconfigured meta-approval attempts revert with
NoPermission/ResourceNotFound
Verification:
- Test meta-transaction approval immediately after requesting a time-locked transaction
- Verify that only properly authorized and correctly configured meta-approval flows succeed
- Verify that unauthorized or schema/whitelist-misconfigured meta-approvals revert
Related Tests:
testFuzz_TimeLockAppliesToMetaTransactions
- ID:
COMP-003 - Location:
EngineBlox.sol:697-707,EngineBlox.sol:550-590 - Severity: HIGH
- Status:
⚠️ REQUIRES VERIFICATION
Description:
Combining payment update with execution to redirect funds during execution.
Attack Scenario:
- Legitimate transaction requested
- Payment updated to attacker address
- Transaction executed
- Funds redirected to attacker
Current Protection:
- ✅ Payment updates require permissions
- ✅ Payment updates require PENDING status
Verification:
- Test payment update + execution combination
- Verify update restrictions
- Test unauthorized updates
Related Tests:
testFuzz_PaymentUpdateExecutionCombination
- ID:
COMP-004 - Location:
EngineBlox.sol:1446-1457,EngineBlox.sol:1484 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Predicting next nonce and creating front-run transaction to replay signature.
Attack Scenario:
- Attacker predicts next nonce (current + 1)
- Creates meta-transaction with predicted nonce
- Front-runs legitimate transaction
- Replays signature with predicted nonce
Current Protection:
- ✅ Nonce incremented before execution
- ✅ Nonce validation prevents replay
- ✅ Invalid nonce causes revert
Verification:
- Test nonce prediction attempts
- Verify nonce increment timing
- Test front-run scenarios
Related Tests:
testFuzz_NoncePredictionReplayPrevented
[See Section 2.1 for cryptographic attack vectors - covered in Meta-Transaction Security section]
- ID:
TIME-001 - Location:
SecureOwnable.sol:296-303 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Reducing time-lock period to minimum to bypass security delay.
Attack Scenario:
// Attacker updates time-lock to 1 second
updateTimeLockPeriod(1); // 1 second instead of 24 hours
// Bypass intended security delayCurrent Protection:
- ✅ Time-lock update requires owner approval
- ✅ Time-lock updates are time-locked themselves
- ✅ Requires proper authorization
Verification:
- Test time-lock period updates
- Verify authorization requirements
- Test minimum time-lock period
Related Tests:
testFuzz_TimeLockPeriodManipulationPrevented
- ID:
TIME-002 - Location:
EngineBlox.sol:638,EngineBlox.sol:186 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Miner manipulation of block.timestamp to accelerate time-lock expiration.
Attack Scenario:
// Miner manipulates timestamp to accelerate time-lock
// releaseTime = block.timestamp + timeLockPeriod
// Miner sets block.timestamp to future value
// Time-lock appears expiredCurrent Protection:
- ✅ Time-lock periods should be sufficiently long (24+ hours)
- ✅ Miner can only manipulate ~15 seconds per block
- ✅ Long time-lock periods prevent meaningful manipulation
Verification:
- Test with manipulated timestamps
- Verify time-lock still enforced
- Test with maximum timestamp manipulation
Related Tests:
testFuzz_BlockTimestampManipulationLimited
- ID:
TIME-003 - Location:
EngineBlox.sol:1700 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Setting very long deadlines for meta-transactions to extend signature validity.
Attack Scenario:
// Attacker sets deadline far in future
MetaTransaction memory metaTx = {
params: {
deadline: block.timestamp + 10 years, // Very long deadline
// ...
}
};
// Signature remains valid indefinitelyCurrent Protection:
- ✅ Deadline validation checks expiration
⚠️ Impact: Low - signature still requires proper permissions
Verification:
- Test with long deadlines
- Verify deadline enforcement
- Test deadline expiration
- ID:
RM-001 - Location:
EngineBlox.sol:731-757 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Creating duplicate roles with the same name to bypass duplicate checks.
Attack Scenario:
// Attacker creates role with same name
createRole("EXISTING_ROLE", 10, permissions); // First call
createRole("EXISTING_ROLE", 10, permissions); // Second call - should failCurrent Protection:
- ✅
ResourceAlreadyExistscheck - ✅ Role name hashing prevents duplicates
Verification:
- Test duplicate role creation
- Verify
ResourceAlreadyExistserror
Related Tests:
testFuzz_CannotCreateRoleWithProtectedRoleName
- ID:
RM-002 - Location:
EngineBlox.sol:809-823 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Exceeding role wallet limits through concurrent operations.
Attack Scenario:
// Role has maxWallets = 10, currently has 9 wallets
// Attacker submits multiple ADD_WALLET transactions simultaneously
// Race condition might allow exceeding maxWallets limitCurrent Protection:
- ✅
validateWalletLimitchecks before adding - ✅ Check happens before state modification
Verification:
- Test concurrent wallet additions
- Test adding wallet when at limit
- Verify
WalletLimitExceedederror
Related Tests:
testFuzz_RoleWalletLimitEnforced
- ID:
RM-003 - Location:
EngineBlox.sol:858-873 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Removing last wallet from protected role to lock out legitimate access.
Attack Scenario:
// OWNER_ROLE has only one wallet (owner)
// Attacker attempts to revoke the owner wallet
revokeWallet(OWNER_ROLE, ownerAddress);
// Should fail - cannot remove last wallet from protected roleCurrent Protection:
- ✅ Check at line 864-866:
if (roleData.isProtected && roleData.authorizedWallets.length() <= 1) - ✅ Reverts with
CannotModifyProtected
Verification:
- Test with protected role containing exactly 1 wallet
- Test with protected role containing 2 wallets (remove one, then attempt to remove last)
- Test concurrent removal attempts
Related Tests:
testFuzz_CannotRevokeLastWalletFromProtectedRole
- ID:
WL-001 - Location:
EngineBlox.sol:1227-1231 - Severity: CRITICAL
- Status: ✅ INTENTIONAL
Description:
Using address(this) to bypass whitelist requirements for internal function calls.
Attack Scenario:
// Attacker targets address(this) for any function
requestTransaction(address(this), value, selector, params, ...);
// Bypass whitelist requirementCurrent Protection:
- ✅ This is intentional design - internal calls allowed
- ✅ Internal functions have additional protection (
validateInternalCall) - ✅ External calls still require whitelist
Verification:
- Verify this is intentional and secure
- Test internal function protection
- Verify external calls still require whitelist
- ID:
WL-002 - Location:
EngineBlox.sol:1217-1242 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Exploiting empty whitelist behavior (all targets denied except address(this)).
Attack Scenario:
// Function has empty whitelist (no entries)
// All targets denied except address(this)
// Attacker cannot execute on external targetsCurrent Protection:
- ✅ Empty whitelist = deny all (secure by default)
- ✅ Only
address(this)allowed when whitelist empty
Verification:
- Test empty whitelist behavior
- Verify external targets denied
- Test internal calls allowed
- ID:
WL-003 - Location:
EngineBlox.sol:1197-1206 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Removing target from whitelist after transaction request but before execution.
Attack Scenario:
// Attacker requests transaction with whitelisted target
uint256 txId = requestTransaction(whitelistedTarget, ...);
// Target removed from whitelist before approval
removeTargetFromWhitelist(selector, whitelistedTarget);
// Transaction fails at execution
approveTransaction(txId); // Should fail - target not whitelistedCurrent Protection:
- ✅ Whitelist checked at execution (line 1223)
- ✅ Transaction fails if target not whitelisted
Verification:
- Test whitelist removal during pending transaction
- Verify execution fails
- Test whitelist re-addition
- ID:
WL-004 - Location:
EngineBlox.sol:1223-1225 - Severity: MEDIUM
- Status: ✅ INTENTIONAL
Description:
Bypassing whitelist for unregistered selectors (whitelist validation skipped).
Attack Scenario:
// Function selector not in supportedFunctionsSet
// Whitelist validation skipped
// Attacker can execute unregistered functionsCurrent Protection:
- ✅ This is intentional design - unregistered functions skip validation
⚠️ Consider if this is desired behavior
Verification:
- Verify this is intentional design
- Test unregistered function execution
- Consider security implications
- ID:
FS-001 - Location:
EngineBlox.sol:1974-2011 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Bypassing handler selector validation by providing handler selector not in schema.
Attack Scenario:
// Attacker provides handler selector not in schema
addFunctionToRole(roleHash, FunctionPermission({
functionSelector: FUNCTION_SELECTOR,
handlerForSelectors: [INVALID_HANDLER_SELECTOR] // Not in schema
}));Current Protection:
- ✅
_validateHandlerForSelectorschecks all handlers - ✅ Handler must exist in schema's
handlerForSelectorsarray
Verification:
- Test with invalid handler selectors
- Verify validation prevents this
- Test handler selector requirements
Related Tests:
testFuzz_HandlerSelectorValidation
- ID:
FS-002 - Location:
EngineBlox.sol:1099-1144 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Attempting to modify or remove protected function schemas.
Attack Scenario:
// Attacker attempts to remove protected function schema
removeFunctionSchema(TRANSFER_OWNERSHIP_SELECTOR, false);
// Should fail with CannotModifyProtectedCurrent Protection:
- ✅ Check at line 1106-1108:
if (self.functions[functionSelector].isProtected) - ✅ Protected schemas cannot be modified
Verification:
- Test protected schema modification
- Verify
CannotModifyProtectederror - Test with
safeRemoval = trueandfalse
- ID:
FS-003 - Location:
EngineBlox.sol:1133-1143 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Exploiting operation type cleanup when removing functions.
Attack Scenario:
// Remove function using operation type
removeFunctionSchema(selector, false);
// Operation type removed from set
// Other functions using same type affectedCurrent Protection:
- ✅ Cleanup checks other functions
- ✅ Operation type only removed if no other functions use it
Verification:
- Test operation type cleanup
- Verify cleanup logic
- Test with multiple functions using same operation type
- ID:
FS-004 - Location:
EngineBlox.sol:1185-1239,EngineBlox.sol:2104-2129 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Using unregisterFunction(functionSelector, false) to remove a function schema while roles still hold permissions for the selector, then attempting to create or execute new transactions using the stale selector.
Attack Scenario:
// 1. Register function schema and grant role permission for EXECUTE_TIME_DELAY_REQUEST
registerFunction(schemaSelector, ...);
addFunctionToRole(ROLE, FunctionPermission({ functionSelector: schemaSelector, ... }));
// 2. Unsafely unregister schema while role still references selector
unregisterFunction(schemaSelector, false); // safeRemoval = false
// 3. Attempt to create or approve new transaction using stale selector
txRequest(..., handlerSelector = schemaSelector, executionSelector = schemaSelector, ...); // Should failCurrent Protection:
- ✅
_validateFunctionSchemaExistsensures a function schema exists for any selector being executed - ✅
_validateExecutionAndHandlerPermissionsenforces schema existence for bothexecutionSelectorandhandlerSelector - ✅ Requests and approvals using unregistered selectors revert with
ResourceNotFound
Verification:
- Test unsafe unregistration followed by
txRequestand approval flows - Verify that requests and approvals revert when function schema has been unregistered
- Confirm that
safeRemoval = truecontinues to enforce "no stale role permissions" invariant
Related Tests:
UnregisterFunctionFuzz.t.sol::test_UnsafeUnregisterPreventsNewRequests
- ID:
INIT-001 - Location:
EngineBlox.sol:209-239,BaseStateMachine.sol:79-92 - Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Initializing contract multiple times to reset state or modify initial configuration.
Attack Scenario:
// Attacker calls initialize multiple times
initialize(owner, broadcaster, recovery, ...); // First call
initialize(attacker, attacker, attacker, ...); // Second call - should failCurrent Protection:
- ✅
AlreadyInitializedcheck - ✅
initializedflag prevents re-initialization
Verification:
- Test multiple initialization attempts
- Verify
AlreadyInitializederror - Test uninitialized contract access
- ID:
INIT-002 - Location:
EngineBlox.sol:209-239 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Exploiting uninitialized contract state by calling functions before initialization.
Attack Scenario:
// Contract deployed but not initialized
// Attacker calls functions before initialization
requestTransaction(...); // Should fail - not initializedCurrent Protection:
- ✅ Functions check
initializedflag - ✅ Revert if not initialized
Verification:
- Test uninitialized contract access
- Verify initialization requirement
- Test after initialization
- ID:
INIT-003 - Location:
EngineBlox.sol:209-239 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Manipulating initialization parameters to bypass validation or set invalid state.
Attack Scenario:
// Attacker provides invalid initialization parameters
initialize(address(0), broadcaster, recovery, ...); // Zero owner
initialize(owner, address(0), recovery, ...); // Zero broadcasterCurrent Protection:
- ✅ Comprehensive parameter validation
- ✅ Zero address checks
- ✅ Parameter validation before state changes
Verification:
- Test with invalid initialization parameters
- Verify parameter validation
- Test all parameter combinations
- ID:
INIT-004 - Location: All upgradeable contracts
- Severity: MEDIUM
- Status:
⚠️ REQUIRES REVIEW
Description:
Storage layout collision in upgrades causing state corruption.
Attack Scenario:
// Upgrade introduces storage layout changes
// State corruption occurs
// Unintended behaviorCurrent Protection:
⚠️ Follow OpenZeppelin upgrade patterns⚠️ Review storage layout compatibility
Verification:
- Review storage layout compatibility
- Test upgrade scenarios
- Verify state preservation
- ID:
HOOK-001 - Location:
contracts/experimental/hook/HookManager.sol—_executeActionHooks,_postActionHook - Severity: HIGH
- Status:
⚠️ TRUST MODEL (not “best-effort” for HookManager stacks)
Description:
Malicious or buggy hook contracts invoked after a core operation could harm liveness or try to reenter.
Attack Scenario:
// Owner sets malicious hook contract
setHook(selector, maliciousHookContract);
// Hook runs after state machine step completes for that tx pathCurrent Protection (HookManager, experimental):
- ✅ Hooks run after
super._postActionHook(core Checks-Effects already applied in the caller frame) ⚠️ IOnActionHook.onActionis a plain external call — if any hook reverts or runs out of gas, the entire parent request/approve/cancel reverts (no try/catch in_executeActionHooks). NatSpec: only register trusted, non-reverting hooks.- ✅
EngineBlox.MAX_HOOKS_PER_SELECTORcaps how many hooks can be registered per selector - ℹ️ Account / GuardController / RuntimeRBAC stacks in
contracts/core/pattern/Account.soldo not include HookManager; this surface exists only when a deployment opts into the experimental hook mixin.
Verification:
- Test with reverting hooks (parent tx must revert)
- Test hook reentrancy against
nonReentrantentrypoints - Prefer
ComprehensiveHookSystemFuzz.t.sol/ComprehensiveSecurityEdgeCasesFuzz.t.solfor hook suites
- ID:
HOOK-002 - Location:
contracts/experimental/hook/HookManager.sol,BaseStateMachine.sol(nonReentranton meta / tx entrypoints) - Severity: MEDIUM
- Status: ✅ PROTECTED (where HookManager is used)
Description:
Reentrancy through hook contracts calling back into the state machine.
Attack Scenario:
contract MaliciousHook {
function onAction(...) external {
stateMachine.approveTimeLockExecution(txId);
}
}Current Protection:
- ✅ State-changing entrypoints on
BaseStateMachine/GuardControllerusenonReentrant; a second nested entry in the same tx hits the guard ⚠️ Hooks are still trusted code; do not rely on hooks alone for authorization
Verification:
testFuzz_HookReentrancyPrevented(ComprehensiveSecurityEdgeCasesFuzz.t.sol)
- ID:
HOOK-003 - Location:
contracts/experimental/hook/HookManager.sol:_executeActionHooks,EngineBlox.sol(MAX_HOOKS_PER_SELECTOR) - Severity: MEDIUM
- Status:
⚠️ PARTIAL — count bound, no per-hook gas stipend
Description:
A hook that burns gas or reverts with OOG can fail the whole operation (same revert semantics as HOOK-001).
Attack Scenario:
contract GasIntensiveHook {
function onAction(...) external {
while (true) { } // OOG or revert
}
}Current Protection:
- ✅ At most
MAX_HOOKS_PER_SELECTORhooks per selector (limits fan-out) ⚠️ No explicit{gas: N}ononAction; hook shares the transaction’s remaining gas (EIP-150 applies to nested calls)⚠️ No try/catch — exhausting gas in a hook reverts the parent
Verification:
testFuzz_MultipleHooksGasExhaustionPrevented,testFuzz_HookExecutionGasConsumptionWithManyHooks(ComprehensiveGasExhaustionFuzz / SecurityEdgeCases)
- ID:
HOOK-004 - Location:
contracts/experimental/hook/HookManager.sol:setHook,clearHook - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Unauthorized hook configuration bypassing access control.
Attack Scenario:
// Attacker sets hook without owner permission
vm.prank(attacker);
setHook(HookType.ON_ACTION, maliciousHook); // Should failCurrent Protection:
- ✅ Owner-only function
- ✅ Access control enforced
Verification:
- Test unauthorized hook setting
- Verify access control
- Test authorized hook setting
- ID:
EVENT-001 - Location:
EngineBlox.sol:logTxEvent(forwarder subcall),IEventForwarder.forwardTxEvent - Severity: MEDIUM
- Status: ✅ PROTECTED (state);
⚠️ TRUST MODEL (gas / monitoring)
Description:
Malicious or buggy eventForwarder could waste gas or confuse off-chain consumers.
Attack Scenario:
setEventForwarder(maliciousForwarder);
// After tx completes, logTxEvent calls forwardTxEventCurrent Protection:
- ✅
try/catcharoundforwardTxEvent— forwarder revert does not roll back Bloxchain state updates that already completed in the same tx - ✅
TransactionEventis emitted before the forwarder call — authoritative on-chain trail ⚠️ No explicit gas stipend on the forwarder call; EIP-150 bounds the subcall gas share⚠️ Forwarder failure is silent off-chain; monitoring must not assume forwarder delivery (see audit Findings 18 / 35)
Verification:
testFuzz_MaliciousEventForwarderIsolated(ComprehensiveEventForwardingFuzz.t.sol)
- ID:
EVENT-002 - Location:
EngineBlox.sol:logTxEvent - Severity: LOW
- Status: ✅ PROTECTED (liveness of core state);
⚠️ GAS / OPS
Description:
Gas-intensive forwarder can burn gas in the same transaction; forwarder can revert and be swallowed.
Attack Scenario:
contract GasIntensiveForwarder {
function forwardTxEvent(...) external {
while(true) { /* ... */ }
}
}Current Protection:
- ✅
try/catch— forwarder OOG/revert does not revert core engine finalization that already reachedlogTxEvent ⚠️ Remaining gas in the frame can still be large; operator should use a trusted forwarder
Verification:
testFuzz_GasIntensiveEventForwarderHandled(ComprehensiveEventForwardingFuzz.t.sol)
- ID:
DEF-001 - Location:
EngineBlox.sol:1066-1069,BaseStateMachine.sol:756-783 - Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Definition contract omits isProtected: true for functions that exist in contract bytecode, allowing removal of critical system functions.
Attack Scenario:
// Malicious definition contract
function getFunctionSchemas() public pure returns (EngineBlox.FunctionSchema[] memory) {
// Missing isProtected: true for transferOwnership() which exists in bytecode
schemas[0] = EngineBlox.FunctionSchema({
functionSelector: TRANSFER_OWNERSHIP_SELECTOR,
isProtected: false, // ❌ Should be true - function exists in contract
// ...
});
}Current Protection:
- ✅
_validateContractFunctionProtectionchecks bytecode and requires protection - ✅
selectorExistsInContractvalidates function exists in contract - ✅ Reverts with
ContractFunctionMustBeProtectedif function exists but not protected
Verification:
- Test definition contracts with missing protected flags
- Verify
ContractFunctionMustBeProtectederror is raised - Test with system functions that exist in bytecode
Related Tests:
testFuzz_DefinitionWithMissingProtectedFlagRejected
- ID:
DEF-002 - Location:
EngineBlox.sol:1058-1064 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Definition provides function signature that doesn't match the selector, causing initialization failure or bypass validation.
Attack Scenario:
// Definition with mismatched signature
schemas[0] = EngineBlox.FunctionSchema({
functionSignature: "wrongSignature()", // Doesn't match selector
functionSelector: TRANSFER_OWNERSHIP_SELECTOR,
// ...
});Current Protection:
- ✅ Signature validation at line 1061-1064
- ✅
FunctionSelectorMismatcherror if mismatch detected
Verification:
- Test with mismatched signatures
- Verify
FunctionSelectorMismatcherror
Related Tests:
testFuzz_DefinitionWithMismatchedSignatureRejected
- ID:
DEF-003 - Location:
EngineBlox.sol:1999-2036 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Definition provides handler selectors that don't exist in schema's handlerForSelectors array, or creates circular/invalid dependencies.
Attack Scenario:
// Definition with invalid handler relationship
schemas[0] = EngineBlox.FunctionSchema({
functionSelector: HANDLER_SELECTOR,
handlerForSelectors: [INVALID_EXECUTION_SELECTOR], // Not in execution schema
// ...
});Current Protection:
- ✅
_validateHandlerForSelectorsvalidates relationships - ✅ Handler selectors must exist in schema's
handlerForSelectorsarray - ✅
HandlerForSelectorMismatcherror if invalid
Verification:
- Test with invalid handler relationships
- Verify validation prevents invalid handlers
Related Tests:
testFuzz_DefinitionWithInvalidHandlerSelectorsRejected
- ID:
DEF-004 - Location:
EngineBlox.sol:1096-1098 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Definition attempts to register the same function selector multiple times.
Attack Scenario:
// Definition with duplicate schemas
schemas[0] = EngineBlox.FunctionSchema({...functionSelector: SELECTOR_A...});
schemas[1] = EngineBlox.FunctionSchema({...functionSelector: SELECTOR_A...}); // DuplicateCurrent Protection:
- ✅
ResourceAlreadyExistscheck at line 1096-1098 - ✅ Duplicate selectors are rejected
Verification:
- Test with duplicate schemas
- Verify
ResourceAlreadyExistserror
Related Tests:
testFuzz_DefinitionWithDuplicateSchemasRejected
- ID:
DEF-005 - Location:
EngineBlox.sol:1080-1082 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Definition provides empty handlerForSelectors array, which is no longer allowed.
Attack Scenario:
// Definition with empty handlerForSelectors
schemas[0] = EngineBlox.FunctionSchema({
handlerForSelectors: [], // ❌ Empty array not allowed
// ...
});Current Protection:
- ✅ Empty array check at line 1080-1082
- ✅
OperationFailederror if empty
Verification:
- Test with empty arrays
- Verify
OperationFailederror
Related Tests:
testFuzz_DefinitionWithEmptyHandlerArrayRejected
- ID:
DEF-006 - Location:
BaseStateMachine.sol:777-781,EngineBlox.sol:2007-2009 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Definition provides role permissions for function selectors that haven't been registered in schemas yet.
Attack Scenario:
// Definition loads permissions before schemas, or references non-existent function
rolePermissions[0] = FunctionPermission({
functionSelector: NON_EXISTENT_SELECTOR, // Schema not registered
// ...
});Current Protection:
- ✅
_loadDefinitionsloads schemas first, then permissions - ✅
addFunctionToRolechecks function exists insupportedFunctionsSet - ✅
ResourceNotFounderror if function doesn't exist
Verification:
- Test permissions for non-existent functions
- Verify
ResourceNotFounderror
Related Tests:
testFuzz_PermissionForNonExistentFunctionRejected
- ID:
DEF-007 - Location:
BaseStateMachine.sol:775 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Definition provides mismatched array lengths between roleHashes and functionPermissions.
Attack Scenario:
// Definition with mismatched arrays
IDefinition.RolePermission memory permissions = IDefinition.RolePermission({
roleHashes: [ROLE_A, ROLE_B], // 2 roles
functionPermissions: [PERM_1] // Only 1 permission - mismatch!
});Current Protection:
- ✅
validateArrayLengthMatchat line 775 - ✅
ArrayLengthMismatcherror if lengths don't match
Verification:
- Test with mismatched arrays
- Verify
ArrayLengthMismatcherror
Related Tests:
testFuzz_DefinitionWithMismatchedPermissionArraysRejected
- ID:
DEF-008 - Location:
EngineBlox.sol:2044-2053 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Definition provides empty or invalid action bitmaps that don't match the function schema's supported actions.
Attack Scenario:
// Definition with empty bitmap
functionPermissions[0] = FunctionPermission({
grantedActionsBitmap: 0, // ❌ Empty bitmap not allowed
// ...
});Current Protection:
- ✅ Empty bitmap check at line 2051-2053
- ✅
NotSupportederror if bitmap is empty
Verification:
- Test with empty/invalid bitmaps
- Verify
NotSupportederror
Related Tests:
testFuzz_DefinitionWithEmptyBitmapRejected
- ID:
DEF-009 - Location:
EngineBlox.sol:2017-2020 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Definition provides self-reference in handlerForSelectors for non-execution selectors (only execution selectors can self-reference).
Attack Scenario:
// Definition with invalid self-reference
functionPermissions[0] = FunctionPermission({
functionSelector: HANDLER_SELECTOR, // Not execution
handlerForSelectors: [HANDLER_SELECTOR], // ❌ Self-reference not allowed for handlers
// ...
});Current Protection:
- ✅ Self-reference validation at line 2017-2020
- ✅ Self-reference only allowed for execution selectors
- ✅ Handler validation prevents invalid self-references
Verification:
- Test with invalid self-references
- Verify validation prevents handler self-reference
Related Tests:
testFuzz_DefinitionWithInvalidSelfReferenceRejected
- ID:
DEF-010 - Location:
BaseStateMachine.sol:756-783 - Severity: CRITICAL
- Status:
⚠️ REQUIRES USER VIGILANCE
Description:
Attacker deploys malicious definition contract that provides incorrect schemas/permissions to compromise system security.
Attack Scenario:
// Attacker deploys malicious definition
contract MaliciousDefinitions {
function getFunctionSchemas() public pure returns (EngineBlox.FunctionSchema[] memory) {
// Provides schemas that bypass security checks
// Or grants excessive permissions
}
}
// Attacker tricks user into using malicious definition during initializationCurrent Protection:
⚠️ Relies on users using trusted definition contracts- ✅ Validation checks prevent many malicious patterns
- ✅ System definition contracts are protected
Verification:
- Test with malicious definition patterns
- Verify system rejects malicious patterns
- Test system definition contracts are valid
Related Tests:
test_SystemDefinitionContractsValidtestFuzz_MaliciousDefinitionPatternsRejected
- ID:
DEF-011 - Location:
IDefinition.sol(pure functions) - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Definition contract uses state variables instead of pure functions, allowing manipulation.
Attack Scenario:
// Malicious definition with state
contract MaliciousDefinitions {
EngineBlox.FunctionSchema[] private schemas;
function getFunctionSchemas() public returns (EngineBlox.FunctionSchema[] memory) {
// Can modify schemas after deployment
schemas[0].isProtected = false; // Change protection
return schemas;
}
}Current Protection:
- ✅ Interface requires
purefunctions (compile-time check) - ✅ Pure functions cannot access state
- ✅ Definition contracts should be libraries (no state)
Verification:
- Verify only pure definition contracts are used
- Test that state-based definitions are rejected
Related Tests:
testFuzz_DefinitionMustUsePureFunctions
- ID:
DEF-012 - Location:
EngineBlox.sol:2144-2166 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Definition contract bytecode is modified after deployment, but the protection check only runs during schema creation.
Attack Scenario:
// Definition contract upgraded/changed after initial use
// New version has different function selectors
// Protection validation only runs during _loadDefinitionsCurrent Protection:
- ✅ Protection check runs during
createFunctionSchema - ✅
selectorExistsInContractvalidates bytecode at creation time - ✅ System definitions are immutable libraries
Verification:
- Verify protection validation catches bytecode changes
- Test with upgraded definition contracts
Related Tests:
test_SystemDefinitionsProtectSystemFunctions
- ID:
DEF-013 - Location:
BaseStateMachine.sol:761-782 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Definition provides permissions before corresponding schemas are registered, causing initialization failure.
Attack Scenario:
// Definition with wrong order (if possible)
// Permissions reference schemas that aren't registered yetCurrent Protection:
- ✅
_loadDefinitionsenforces schema-first order - ✅ Schemas loaded before permissions
- ✅
ResourceNotFounderror if permission references non-existent schema
Verification:
- Test initialization order is enforced
- Verify schemas must be registered before permissions
Related Tests:
testFuzz_SchemaRegistrationOrderEnforced
- ID:
DEF-014 - Location:
BaseStateMachine.sol:756-783 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Attempting to load definitions multiple times or from multiple sources causes conflicts.
Attack Scenario:
// Load definitions from multiple sources
_loadDefinitions(definitions1.getFunctionSchemas(), ...);
_loadDefinitions(definitions2.getFunctionSchemas(), ...); // Conflicts?Current Protection:
- ✅ Duplicate schema check prevents re-registration
- ✅
ResourceAlreadyExistserror for duplicates - ✅ Multiple definitions with different selectors allowed
Verification:
- Test multiple definition loading
- Verify conflicts are handled correctly
Related Tests:
testFuzz_MultipleDefinitionLoadingHandled
- ID:
BITMAP-001 - Location:
EngineBlox.sol:1806-1831 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Bitmap operations use uint16 with bit shifts. If TxAction enum exceeds 15 values, bit shifts could overflow or cause undefined behavior.
Attack Scenario:
// If TxAction enum has 16+ values
TxAction action = TxAction(16); // Out of uint16 bitmap range
uint16 bitmap = 1 << uint8(action); // Potential overflowCurrent Protection:
- ✅ Bitmap is
uint16(max 16 bits) - ✅ TxAction enum currently has 9 values (0-8)
- ✅ Solidity enum conversion prevents invalid values
- ✅ Bitmap operations are bounded by enum range
Verification:
- Test bitmap operations with action values 0-15
- Verify enum conversion rejects invalid values
- Test bitmap creation and checking
Related Tests:
testFuzz_BitmapOverflowPreventedtestFuzz_InvalidActionEnumValuesRejected
- ID:
BITMAP-002 - Location:
EngineBlox.sol:1825-1831 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Invalid action enum values (beyond enum range) are properly rejected when creating bitmaps or checking permissions.
Attack Scenario:
// Definition with invalid action in array
TxAction[] memory actions = new TxAction[](1);
actions[0] = TxAction(255); // Invalid enum value
uint16 bitmap = createBitmapFromActions(actions);
// Does this create valid bitmap or cause issues?Current Protection:
- ✅ Solidity enum conversion prevents invalid enum values
- ✅ Enum values must be in valid range (0-8 for current TxAction)
- ✅ Invalid enum values cause revert at conversion
Verification:
- Test with out-of-range action values
- Verify enum conversion rejects invalid values
- Test bitmap operations with edge cases
Related Tests:
testFuzz_InvalidActionEnumValuesRejected
- ID:
HOOK-005 - Location:
HookManager.sol:98-204 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Multiple hooks execute in EnumerableSet order. If hooks have dependencies or conflicts, order matters and could be exploited.
Attack Scenario:
// Hook1 depends on Hook2 executing first
// But EnumerableSet order might be Hook2, Hook1
// Or attacker adds Hook3 that interferes with Hook1
setHook(selector, hook1);
setHook(selector, hook2); // Order matters!Current Protection:
- ✅ Hooks are best-effort and isolated
- ✅ Hook execution order is deterministic (EnumerableSet iteration order)
- ✅ Hook failures don't affect core state
⚠️ No explicit ordering guarantees (documented behavior)
Verification:
- Test hook execution order consistency
- Test multiple hooks with dependencies
- Verify hook ordering doesn't create vulnerabilities
Related Tests:
testFuzz_HookExecutionOrderConsistent
- ID:
HOOK-006 - Location:
HookManager.sol:109, 127, 145, etc. - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
If hook contract doesn't implement IOnActionHook correctly, the external call will revert. Need to verify this doesn't affect core state.
Attack Scenario:
// Malicious hook with wrong function signature
contract BadHook {
function onRequest(uint256 wrong) external {} // Wrong signature
}
// Hook call reverts - does this affect transaction?Current Protection:
- ✅ Hook calls should be wrapped in try-catch (best-effort execution)
- ✅ Hook failures don't affect core state
- ✅ Hooks execute after core state transitions
⚠️ Need to verify actual try-catch implementation
Verification:
- Test with non-compliant hook contracts
- Verify hook failures don't affect state
- Test hook execution isolation
Related Tests:
testFuzz_HookInterfaceNonComplianceHandled
- ID:
HOOK-007 - Location:
HookManager.sol:98-204 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Attacker sets multiple gas-intensive hooks, causing transaction to run out of gas during hook execution.
Attack Scenario:
// Attacker sets 10 hooks, each consuming 100k gas
for (uint i = 0; i < 10; i++) {
setHook(selector, gasIntensiveHook);
}
// Total hook execution: 1M gas
// Transaction might run out of gasCurrent Protection:
- ✅ Hooks are best-effort (shouldn't affect core state)
- ✅ Hook failures don't affect transaction
⚠️ No limit on number of hooks per selector⚠️ No gas limit per hook execution
Verification:
- Test with maximum number of hooks
- Test with gas-intensive hooks
- Verify transaction completes even with many hooks
Related Tests:
testFuzz_MultipleHooksGasExhaustionPrevented
- ID:
HOOK-008 - Location:
HookManager.sol:212-318 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Hooks could attempt to reenter through state machine functions, but ReentrancyGuard should prevent this.
Attack Scenario:
// Malicious hook reenters state machine
contract MaliciousHook {
function onApprove(...) external {
stateMachine.approveTimeLockExecution(txId);
}
}Current Protection:
- ✅
nonReentrantmodifier on all hook override functions - ✅ ReentrancyGuard from OpenZeppelin
- ✅ Hook execution happens after core state transitions
- ✅ Reentrant calls would see non-PENDING status
Verification:
- Test hook reentrancy attempts
- Verify ReentrancyGuard prevents all reentry paths
- Test multiple reentrant hook calls
Related Tests:
testFuzz_HookReentrancyPrevented
- ID:
PAY-006 - Location:
EngineBlox.sol:705-727,EngineBlox.sol:554-594 - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Payment updates are only allowed during PENDING status, but there's a window between approval and payment execution where status changes.
Attack Scenario:
// Transaction is PENDING
updatePayment(txId, payment1);
// Attacker attempts to update during execution
approveTransaction(txId); // Status changes to EXECUTING
updatePayment(txId, payment2); // Should fail - status not PENDINGCurrent Protection:
- ✅
updatePaymentForTransactionchecksTxStatus.PENDING - ✅ Status changes to EXECUTING before payment
- ✅ Status transitions are atomic
- ✅ Payment updates blocked once status changes
Verification:
- Test payment update attempts during EXECUTING status
- Test concurrent payment update and approval
- Verify atomicity of status transitions
Related Tests:
testFuzz_PaymentUpdateRaceConditionPrevented
- ID:
PAY-007 - Location:
EngineBlox.sol:705-727 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
MEV bots could front-run payment updates to redirect funds to attacker addresses.
Attack Scenario:
// Legitimate user updates payment
updatePayment(txId, PaymentDetails({recipient: legitimateAddress, ...}));
// MEV bot front-runs and updates to attacker address
updatePayment(txId, PaymentDetails({recipient: attackerAddress, ...}));Current Protection:
- ✅ Payment update uses same permissions as request (execution + handler selector)
- ✅ Only authorized users can update payments
⚠️ No rate limiting or cooldown period⚠️ No event emission for payment updates (harder to detect)
Verification:
- Test unauthorized payment update attempts
- Verify permission requirements
- Test front-running scenarios
Related Tests:
testFuzz_FrontRunningPaymentUpdateHandled
- ID:
AC-010 - Location:
EngineBlox.sol:1974-2011 - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Handler selector validation might allow permission escalation if bitmap validation is bypassed.
Attack Scenario:
// Attacker creates permission with handler pointing to protected function
// But bitmap doesn't include required action
FunctionPermission({
functionSelector: handlerSelector,
grantedActionsBitmap: 0, // Empty bitmap
handlerForSelectors: [protectedFunctionSelector]
});
// Does validation catch this?Current Protection:
- ✅ Handler validation exists
- ✅ Empty bitmap check exists (
NotSupportederror) - ✅ Handler + bitmap combination validation
- ✅ Handler selectors must exist in schema's
handlerForSelectorsarray
Verification:
- Test handler selector + bitmap combinations
- Verify empty bitmap with valid handlers is rejected
- Test complete attack chain
Related Tests:
testFuzz_HandlerBitmapCombinationValidation
- ID:
COMP-001 - Location: Multiple
- Severity: HIGH
- Status: ✅ PROTECTED
Description:
Combining payment update with malicious hook to create composite attack.
Attack Scenario:
// 1. Attacker sets malicious hook
setHook(selector, maliciousHook);
// 2. Legitimate user requests transaction with payment
requestTransaction(..., paymentDetails);
// 3. Attacker updates payment recipient
updatePayment(txId, PaymentDetails({recipient: attacker, ...}));
// 4. Hook executes and performs additional malicious actionsCurrent Protection:
- ✅ Each component has individual protections
- ✅ Payment update requires permissions
- ✅ Hook execution is best-effort and isolated
- ✅ Core state transitions happen before hooks
Verification:
- Test payment update + hook combinations
- Test multiple attack vectors simultaneously
- Verify composite attack scenarios
Related Tests:
testFuzz_CompositePaymentHookAttackPrevented
The system has immutable safety limits defined as public constants in EngineBlox.sol to prevent gas exhaustion attacks:
MAX_BATCH_SIZE = 200 // Max items in batch operations
MAX_ROLES = 1000 // Max total roles in system
MAX_HOOKS_PER_SELECTOR = 100 // Max hooks per function selector
MAX_FUNCTIONS = 2000 // Max total functions in systemRationale: These limits maintain gas safety while providing scalability. All operations remain within the Ethereum block gas limit (60M gas) with appropriate safety margins.
- ID:
GAS-001 - Location:
EngineBlox.sol:hasActionPermission(),EngineBlox.sol:hasAnyRole() - Severity: CRITICAL
- Status: ✅ PROTECTED
Description:
Unbounded loops in permission checks could cause gas exhaustion when many roles exist.
Current Protection:
- ✅ Reverse index optimization:
hasAnyRole()is O(1),hasActionPermission()is O(k) where k = wallet's role count - ✅
MAX_ROLES = 1000prevents unbounded role growth - ✅ Wallet-to-role indexing (
walletRolesmapping) enables efficient permission checks
Related Tests:
testFuzz_PermissionCheckGasConsumptionWithManyRolestestFuzz_HasAnyRoleGasConsumptionWithManyRolestestFuzz_PermissionCheckOptimizationBenefit
- ID:
GAS-004 - Location:
RuntimeRBAC.sol:_executeRoleConfigBatch(),GuardController.sol:_executeGuardConfigBatch() - Severity: HIGH
- Status: ✅ PROTECTED
Description:
Large batch operations could exceed block gas limits.
Current Protection:
- ✅
MAX_BATCH_SIZE = 200prevents oversized batches - ✅ Batch size validation in
SharedValidation.validateBatchSize() - ✅ Operations remain within safe gas budgets (< 30M gas for 200 items)
Related Tests:
testFuzz_BatchRoleCreationGasConsumptiontestFuzz_BatchSizeLimitEnforcedtestFuzz_BatchFunctionRegistrationGasConsumption
- ID:
GAS-011 - Location:
EngineBlox.sol:getSupportedRolesList(),EngineBlox.sol:getSupportedFunctionsList() - Severity: HIGH
- Status: ✅ PROTECTED
Description:
View functions returning all roles/functions could consume excessive gas.
Current Protection:
- ✅
MAX_ROLES = 1000andMAX_FUNCTIONS = 2000cap resource growth - ✅ View functions complete within reasonable gas (< 40M gas at limits)
⚠️ Consider pagination for very large datasets in production
Related Tests:
testFuzz_ViewFunctionGasConsumptionWithManyRolestestFuzz_ViewFunctionGasConsumptionWithManyFunctions
- ID:
GAS-007 - Location:
HookManager.sol(experimental) - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Multiple hooks per selector could cause gas exhaustion.
Current Protection:
- ✅
MAX_HOOKS_PER_SELECTOR = 100prevents excessive hooks - ✅ Hook execution is best-effort and isolated
- ✅ Hook failures don't affect core transaction state
Related Tests:
testFuzz_HookExecutionGasConsumptionWithManyHookstestFuzz_HookCountLimitEnforced
- Test:
testFuzz_RoleCountLimitEnforced - Limit:
MAX_ROLES = 1000 - Status: ✅ Enforced via
SharedValidation.validateRoleCount() - Gas Impact: ~908M gas to create 1000 roles (acceptable for limit test)
- Test:
testFuzz_FunctionCountLimitEnforced - Limit:
MAX_FUNCTIONS = 2000 - Status: ✅ Enforced via
SharedValidation.validateFunctionCount() - Gas Impact: ~107k gas (efficient)
- Test:
testFuzz_BatchSizeLimitEnforced - Limit:
MAX_BATCH_SIZE = 200 - Status: ✅ Enforced via
SharedValidation.validateBatchSize() - Gas Impact: ~79M gas average (within limits)
- Test:
testFuzz_HookCountLimitEnforced - Limit:
MAX_HOOKS_PER_SELECTOR = 100 - Status: ✅ Enforced via
SharedValidation.validateHookCount() - Gas Impact: ~1k gas average (very efficient)
-
Reverse Index Optimization: Permission checks are now O(1) for
hasAnyRole()and O(k) forhasActionPermission()where k = wallet's role count, independent of total roles. -
Gas Safety Maintained: All operations remain within safe gas budgets even at maximum limits.
-
Scalability Improved: Limits doubled from initial conservative values while maintaining safety margins.
Test File: test/foundry/fuzz/ComprehensiveGasExhaustionFuzz.t.sol (17 tests)
This section consolidates attack vectors derived from the Protocol Vulnerabilities Index (~10,600 DeFi findings) and mapped to Bloxchain. Each vector is tracked with Status (✅ Covered, ✅ Partial,
Coverage summary (as of consolidation): 19 covered or partial, 4 N/A (conditional on proxy/upgrade or absent patterns). No open gaps.
| # | Vector | Source category | Status | Test / notes |
|---|---|---|---|---|
| 1 | Domain separator staleness after upgrade | Cross-Chain / Bridge | ✅ Covered | testFuzz_DomainSeparatorDeterministic (ComprehensiveEIP712AndViewFuzz.t.sol) |
| 2 | Nonce burn on failed execution (griefing) | Cross-Chain | ✅ Covered | testFuzz_NonceConsumedEvenOnExecutionFailure (ComprehensiveMetaTransactionFuzz.t.sol) |
| 3 | Hard fork / same-chain replay | Beanstalk-style | ✅ Covered | testFuzz_ChainIdInDomainSeparator (ComprehensiveMetaTransactionFuzz.t.sol) |
| 4 | EIP-712 struct hash collision (abi.encodePacked) | Cross-Chain | ✅ Covered | testFuzz_StructHashCollisionResistance (ComprehensiveMetaTransactionFuzz.t.sol) |
| # | Vector | Source category | Status | Test / notes |
|---|---|---|---|---|
| 5 | EIP-150 63/64 try/catch abuse | Launchpad (Nouns Builder, Holograph) | ✅ Covered | testFuzz_CatchBlockNotTriggeredByDeliberateOOG (ComprehensiveStateMachineFuzz.t.sol) |
| 6 | User-controlled gas limit bounds | Bridge / Launchpad | ✅ Partial | testFuzz_GasLimitManipulationHandled (StateMachine); OOG behavior documented |
| 7 | Unbounded loops over dynamic data | Bridge / Indexes | ✅ Covered | ComprehensiveGasExhaustionFuzz.t.sol (RoleCountLimitEnforced, BatchSizeLimitEnforced, HookCountLimitEnforced, etc.) |
| # | Vector | Source category | Status | Test / notes |
|---|---|---|---|---|
| 8 | State consistent after removal (swap-and-pop) | Cross-Chain (Union, Stakehouse) | ✅ Covered | testFuzz_StateConsistentAfterRemoval (ComprehensiveAccessControlFuzz.t.sol) |
| 9 | No partial state on revert | Cross-Chain / Lending | ✅ Covered | testFuzz_NoPartialStateOnRevert (ComprehensiveStateMachineFuzz.t.sol) |
| 10 | View reflects latest state (stale cache desync) | Yield Aggregator | ✅ Covered | testFuzz_ViewReflectsLatestState (ComprehensiveEIP712AndViewFuzz.t.sol) |
| # | Vector | Source category | Status | Test / notes |
|---|---|---|---|---|
| 11 | Unchecked return values (low-level call / ERC20) | Bridge | ✅ Partial | testFuzz_TargetContractRevertHandled + testFuzz_NoPartialStateOnRevert; SafeERC20 in use |
| 12 | Fee-on-transfer / non-standard ERC20 in payments | Lending, DEXes, Insurance | ✅ Covered | testFuzz_FeeOnTransferTokenHandling (ComprehensivePaymentSecurityFuzz.t.sol) |
| 13 | Delegatecall to user-controlled target | Bridge (Biconomy, Fractional) | ✅ Covered | testFuzz_NoDelegatecallToUserControlledTarget (ComprehensiveStateMachineFuzz.t.sol); EngineBlox uses .call() |
| 14 | Token approval to arbitrary address before call | Bridge (LI.FI) | No approve-before-call pattern in EngineBlox payment flow |
| # | Vector | Source category | Status | Test / notes |
|---|---|---|---|---|
| 15 | Release time anchored to request time | Gaming (Forgeries) | ✅ Covered | testFuzz_ReleaseTimeAnchoredToRequestTime (ComprehensiveStateMachineFuzz.t.sol) |
| 16 | Pending tx uses request-time params (no retroactive change) | Gaming (Infinity NFT) | ✅ Covered | Same as #15; releaseTime stored per tx at request |
| # | Vector | Source category | Status | Test / notes |
|---|---|---|---|---|
| 17 | Storage layout collision / __gap | Bridge, Yield Aggregator | Add if proxy/upgrade pattern adopted | |
| 18 | Implementation initialization on implementation contract | The Graph, Juicebox | Add if proxy pattern adopted |
| # | Vector | Source category | Status | Test / notes |
|---|---|---|---|---|
| 19 | Excess msg.value not refunded | NFT Marketplace, Gaming | ✅ Covered | testFuzz_ExcessMsgValueRefunded (ComprehensiveEIP712AndViewFuzz.t.sol); receive() credits full value |
| 20 | MEV / broadcaster ordering vs timelock/deadline | DEXes, Indexes | ✅ Covered | testFuzz_PrematureApprovalPrevented (StateMachine); ordering cannot bypass timelock |
| 21 | EIP-712 typehash/struct match (signature verification) | Launchpad, Derivatives | ✅ Covered | testFuzz_EIP712RecoversCorrectSigner (ComprehensiveEIP712AndViewFuzz.t.sol) |
References: Protocol Vulnerabilities Index, Test Execution Guide, Final Coverage Report.
Vectors derived from the AgentArena multi-agent audit (37 findings, commit 8645f1e2). Each entry tracks the original finding number, the implemented mitigation, and the fuzz test that verifies the fix. Source: research/audit/agent arena/AUDIT_FINDINGS.md, AUDIT_RESOLUTION.md.
Test file: test/foundry/fuzz/AuditDerivedAttackVectorsFuzz.t.sol (17 tests)
- ID:
AUDIT-001 - Finding: AgentArena #1. Same underlying issue as MT-008 (§2.1).
- Location:
EngineBlox.sol:verifySignature,BaseStateMachine.sol:_validateMetaTxHandlerBinding,SharedValidation.sol - Severity: HIGH
- Status: ✅ PROTECTED
Description:
A signed meta-tx targeting handler A (e.g. roleConfigBatchRequestAndApprove) could be submitted through sibling wrapper B (e.g. guardConfigBatchRequestAndApprove), bypassing wrapper-specific checks.
Current Protection:
- ✅
BaseStateMachine._validateMetaTxHandlerBindingcheckshandlerSelector == msg.sigat each wrapper entry - ✅
EngineBlox.verifySignaturecheckshandlerContract == address(this)in the library - ✅
EngineBlox.generateMetaTransactionfail-fast onhandlerContractmismatch - ✅ Custom errors:
MetaTxHandlerSelectorMismatch,MetaTxHandlerContractMismatch
Related Tests:
testFuzz_Finding1_HandlerSelectorMismatchRejectedtestFuzz_Finding1_HandlerMismatch_GuardSignedRoleSubmittedtestFuzz_Finding1_HandlerContractMismatchRejected
- ID:
AUDIT-001b - Finding: AgentArena #1 (contract binding)
- Location:
EngineBlox.sol:verifySignature,SharedValidation.sol:validateMetaTxHandlerContractBinding - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
handlerContract in signed params must match address(this) (the verifying EIP-712 domain contract). Prevents cross-contract signature replay.
Related Tests:
testFuzz_Finding1_HandlerContractMismatchRejected
- ID:
AUDIT-003 - Finding: AgentArena #3
- Location:
RuntimeRBAC.sol:roleConfigBatchRequestAndApprove,GuardController.sol:guardConfigBatchRequestAndApprove - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Config batch meta-tx paths could carry non-zero payment fields and drain funds from the contract without executing any actual configuration actions (empty batch + large payment).
Current Protection:
- ✅
SharedValidation.validateEmptyPaymentenforced before forwarding to engine on both RBAC and Guard batch paths - ✅ Reverts with
InvalidPaymentif any payment field is non-zero
Related Tests:
testFuzz_Finding3_RBACBatchRejectsNonZeroPaymenttestFuzz_Finding3_GuardBatchRejectsNonZeroPaymenttestFuzz_Finding3_RBACBatchRejectsNativeOnlyNonZeroPayment
- ID:
AUDIT-005 - Finding: AgentArena #5
- Location:
EngineBlox.sol:executeTransaction,EngineBlox.sol:_callWithBoundedReturndata - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
A malicious whitelisted target returning very large returndata could blow up memory/gas during _completeTransaction, preventing finalization.
Current Protection:
- ✅
_callWithBoundedReturndatawith low-levelcallandreturndatacopycapped atMAX_RESULT_PREVIEW_BYTES(32 KiB) - ✅ Only the bounded preview is stored in
TxRecord.result
Related Tests:
testFuzz_Finding5_MaxResultPreviewBytesIs32KiB
- ID:
AUDIT-006 - Finding: AgentArena #6
- Location:
EngineBlox.sol:_validateAttachedPaymentPolicy,executeAttachedPayment - Severity: MEDIUM
- Status: ✅ PROTECTED
Description:
Attached payments could route native ETH or ERC20 tokens to addresses not covered by the primary execution target whitelist.
Current Protection:
- ✅ Dedicated
ATTACHED_PAYMENT_RECIPIENT_SELECTORwhitelist forpayment.recipient - ✅ Dedicated
ERC20_TRANSFER_SELECTORwhitelist forpayment.erc20TokenAddress - ✅
_validateAttachedPaymentPolicyat request time and execution time - ✅ Unregistered policy selectors revert
ResourceNotFound
Related Tests:
testFuzz_Finding6_NonWhitelistedRecipientRejectedtestFuzz_Finding6_NonWhitelistedERC20Rejected
- ID:
AUDIT-007 - Finding: AgentArena #7
- Location:
SecureOwnable.sol:transferOwnershipRequest,executeTransferOwnership - Severity: MEDIUM
- Status:
⚠️ INTENTIONAL BEHAVIOR (documented)
Description:
transferOwnershipRequest snapshots getRecovery() into executionParams at request time. If recovery rotates before approval, the pending transfer still targets the old recovery address.
Current Behavior:
- ✅ Snapshot-at-request semantics are intentional and documented
- ✅ Approvers use current owner/recovery; beneficiary is stored address
- ✅ NatSpec and
secure-ownable.mddocument the asymmetry
Related Tests:
testFuzz_Finding7_OwnershipTransferSnapshotsCurrentRecovery
- ID:
AUDIT-008 - Finding: AgentArena #8
- Location:
SecureOwnable.sol:updateRecoveryRequestAndApprove - Severity: MEDIUM
- Status:
⚠️ INTENTIONAL BEHAVIOR (documented)
Description:
updateRecoveryRequestAndApprove has no _requireNoPendingRequest(OWNERSHIP_TRANSFER) check. Owner + broadcaster can rotate recovery while an ownership transfer is pending.
Current Behavior:
- ✅ Intentional fast recovery lane; documented threat model
- ✅
updateBroadcasterRequestdoes block during pending ownership (asymmetric by design)
Related Tests:
testFuzz_Finding8_RecoveryUpdateNotBlockedByPendingOwnership
- ID:
AUDIT-011 - Finding: AgentArena #11
- Location:
EngineBlox.sol:_validateTargetWhitelist - Severity: LOW
- Status: ✅ PROTECTED
Description:
Previously, an unregistered function selector could bypass whitelist validation. Now _validateTargetWhitelist reverts ResourceNotFound when the selector is not in supportedFunctionsSet.
Related Tests:
testFuzz_Finding11_UnregisteredSelectorRevertsResourceNotFound
- ID:
AUDIT-022 - Finding: AgentArena #22
- Location:
BaseStateMachine.sol:getTransactionHistory - Severity: LOW
- Status: ✅ PROTECTED
Description:
Previously reverted on empty history or non-overlapping clamped range. Now returns [].
Related Tests:
testFuzz_Finding22_EmptyTransactionHistoryReturnsEmptyArraytestFuzz_Finding22_NonOverlappingRangeReturnsEmpty
- ID:
AUDIT-024 - Finding: AgentArena #24
- Location:
EngineBlox.sol:txCounter,requestAndApprove - Severity: LOW
- Status:
⚠️ INTENTIONAL BEHAVIOR (documented)
Description:
txId is txCounter + 1 and observable on-chain. Griefing party can front-run to invalidate signatures committed to a specific txId.
Current Behavior:
- ✅ Same sequential-counter model as per-signer nonce — intentional replay control
- ✅ Mitigation: observe counter + short deadlines
Related Tests:
testFuzz_Finding24_TxIdIsSequentialAndPredictable
- ID:
AUDIT-029 - Finding: AgentArena #29
- Location:
EngineBlox.sol:executeTransaction - Severity: LOW
- Status:
⚠️ INTENTIONAL BEHAVIOR (documented)
Description:
gasLimit == 0 is treated as "forward all remaining gas" (gas = gasleft()).
Related Tests:
testFuzz_Finding29_ZeroGasLimitAcceptedInRequest
- ID:
AUDIT-031 - Finding: AgentArena #31
- Location:
SharedValidation.sol:validateTimeLockPeriod,SecureOwnable - Severity: LOW
- Status:
⚠️ INTENTIONAL BEHAVIOR (documented)
Description:
No on-chain maximum for the timelock period. Extremely large values make delayed operations unexecutable.
Current Behavior:
- ✅
validateTimeLockPeriodenforces> 0but no maximum - ✅ Operators validate range in deployment scripts
Related Tests:
testFuzz_Finding31_LargeTimelockAccepted
| # | Finding | Severity | Vector ID | Status | Test |
|---|---|---|---|---|---|
| 1 | Meta-tx handler spoofing | High | AUDIT-001 / MT-008 | ✅ Protected | testFuzz_Finding1_HandlerSelectorMismatchRejected, testFuzz_Finding1_HandlerMismatch_GuardSignedRoleSubmitted, testFuzz_Finding1_HandlerContractMismatchRejected |
| 3 | Config batch payment rail | Medium | AUDIT-003 | ✅ Protected | testFuzz_Finding3_RBACBatchRejectsNonZeroPayment, testFuzz_Finding3_GuardBatchRejectsNonZeroPayment, testFuzz_Finding3_RBACBatchRejectsNativeOnlyNonZeroPayment |
| 5 | Unbounded returndata DoS | Medium | AUDIT-005 | ✅ Protected | testFuzz_Finding5_MaxResultPreviewBytesIs32KiB |
| 6 | Whitelist bypass via payments | Medium | AUDIT-006 | ✅ Protected | testFuzz_Finding6_NonWhitelistedRecipientRejected, testFuzz_Finding6_NonWhitelistedERC20Rejected |
| 7 | Stale recovery snapshot | Medium | AUDIT-007 | testFuzz_Finding7_OwnershipTransferSnapshotsCurrentRecovery |
|
| 8 | Recovery update during pending ownership | Medium | AUDIT-008 | testFuzz_Finding8_RecoveryUpdateNotBlockedByPendingOwnership |
|
| 11 | Unregistered selector whitelist skip | Low | AUDIT-011 | ✅ Protected | testFuzz_Finding11_UnregisteredSelectorRevertsResourceNotFound |
| 22 | getTransactionHistory empty revert | Low | AUDIT-022 | ✅ Protected | testFuzz_Finding22_EmptyTransactionHistoryReturnsEmptyArray, testFuzz_Finding22_NonOverlappingRangeReturnsEmpty |
| 24 | Predictable txId DoS | Low | AUDIT-024 | testFuzz_Finding24_TxIdIsSequentialAndPredictable |
|
| 29 | Gas limit zero convention | Low | AUDIT-029 | testFuzz_Finding29_ZeroGasLimitAcceptedInRequest |
|
| 31 | No timelock upper bound | Low | AUDIT-031 | testFuzz_Finding31_LargeTimelockAccepted |
References: AUDIT_FINDINGS.md, AUDIT_RESOLUTION.md, AUDIT_OVERVIEW.md.
When documenting a new attack vector:
- Assign ID: Use category prefix (AC, MT, SM, RE, IV, PAY, COMP, WL, FS, INIT, HOOK, EVENT, TIME, RM, BITMAP, etc.) + sequential number
- Include:
- Description with attack scenario (code examples)
- Code locations affected (file:line numbers)
- Current protections (if any) with status (PROTECTED, VULNERABLE, REQUIRES VERIFICATION, INTENTIONAL)
- Severity classification (CRITICAL, HIGH, MEDIUM, LOW)
- Verification requirements
- Link Tests: Reference related test functions from Test Documentation
- Update Index: Add to appropriate category section
- Maintain Consistency: Follow existing format and structure
- After Security Audits: Update codex with new findings
- After Code Changes: Verify protections still apply
- After New Features: Assess new attack vectors
- After Test Additions: Link new tests to attack vectors
- PROTECTED: Protection exists and is verified
- VULNERABLE: Known vulnerability requiring fix
- REQUIRES VERIFICATION: Needs review/verification
- INTENTIONAL: Behavior is intentional design choice
- Keep documentation synchronized with code
- Document changes in commit messages
- Maintain changelog for significant updates
- Test Documentation - Maps tests to attack vectors
- Final Coverage Report - Fuzz coverage summary and test counts
- Critical Findings & Recommendations - Actionable security items
- Documentation README - Documentation overview and navigation
- AgentArena Audit Findings - Source audit findings
- AgentArena Audit Resolution - Detailed mitigations
Note: This codex is a living document. It should be updated as new threats are discovered, new protections are implemented, and new tests are added. Always link attack vectors to their test coverage in the Test Documentation.