BitmaskVerifier
Purpose
The BitmaskVerifier
is a customizable, low-level verifier module that enables selective call authorization using bitmask-based hashing. It allows a contract to validate whether a function call (defined by who
, where
, value
, and data
) conforms to a pre-authorized pattern.
It supports:
Partial matching of calldata
Exact or wildcard matching on sender, target, or ETH value
Highly gas-efficient verification with minimal storage
Core Concept: Bitmask-Based Hashing
The BitmaskVerifier
computes a hash over masked components of a transaction and compares it to a stored or expected hash.
The verification succeeds if:
calculateHash(bitmask, who, where, value, data) == expectedHash
Bitmask Format
The bitmask is a byte array with the following structure:
[0:32]
32 bytes
who
Mask for the caller address (left-padded to 32 bytes)
[32:64]
32 bytes
where
Mask for the target contract address (left-padded to 32 bytes)
[64:96]
32 bytes
value
Mask for ETH value (uint256)
[96:]
data.length
data
One byte per calldata byte; used to mask calldata selectively
This structure allows the verifier to:
Fully match addresses and value
Partially match calldata (e.g. permit
approve(x, anyAmount)
)
Function: calculateHash
calculateHash
function calculateHash(
bytes calldata bitmask,
address who,
address where,
uint256 value,
bytes calldata data
) public pure returns (bytes32)
Logic
This function computes a keccak256
hash over the masked versions of each input field:
who
, masked bybitmask[0:32]
where
, masked bybitmask[32:64]
value
, masked bybitmask[64:96]
Each
data[i]
masked bybitmask[96+i]
Example Use
If a bitmask has 0xff
for a given byte, that byte is strictly matched. If 0x00
, the byte is ignored (wildcarded). Mixed values allow partial matching.
Function: verifyCall
verifyCall
function verifyCall(
address who,
address where,
uint256 value,
bytes calldata data,
bytes calldata verificationData
) public pure returns (bool)
Input: verificationData
verificationData
This input must be ABI-encoded as:
abi.encode(bytes32 expectedHash, bytes bitmask)
Logic
Parses
expectedHash
andbitmask
from the calldataVerifies that the bitmask length matches
96 + data.length
32 for
who
, 32 forwhere
, 32 forvalue
, and one byte per calldata byte
Calls
calculateHash()
and compares it toexpectedHash
Returns:
true
if the masked call hash matches the expected hashfalse
otherwise
Use Cases
This verifier enables granular control over contract interactions, for example:
Approvals to a specific contract:
Allow
approve(farmContract, anyAmount)
but block other approvals.Partial calldata authorization:
Authorize only the first 4 bytes (function selector) of a call.
Curated access for specific addresses:
Allow only specific curators to call
delegate(address)
with known targets.Value-bound actions:
Authorize only zero-ETH transactions or enforce a cap on
value
.
Last updated