ERC-7746: Composable Security Middleware
ERC-7746 standardises stackable security middleware that can be inserted before / after any external method call. Each middleware gets the call data, can inspect / mutate it, and can short-circuit the call. Used for:
- Pause guards that halt all calls during incidents.
- Per-method rate limits (e.g. "max 10 transfers per block per account").
- Anti-MEV protection that delays / reorders calls.
- Compliance enforcement that injects KYC checks across the contract.
Required Pattern
solidity
interface IMiddleware {
function before(address caller, bytes4 selector, bytes calldata data) external;
function afterCall(address caller, bytes4 selector, bytes calldata data, bytes calldata result) external;
}
contract Guarded {
IMiddleware[] public middleware;
fallback() external {
for (uint256 i = 0; i < middleware.length; ++i) {
middleware[i].before(msg.sender, msg.sig, msg.data);
}
// ... dispatch + collect result ...
for (uint256 i = 0; i < middleware.length; ++i) {
middleware[i].afterCall(msg.sender, msg.sig, msg.data, result);
}
}
}Neo Equivalent: Pre/Post Hook Chain on External Methods
csharp
public static void GuardedOp(BigInteger amount)
{
RunBeforeHooks("guardedOp", new object[] { amount });
// ... base method body ...
RunAfterHooks("guardedOp", new object[] { amount }, /* result */ null);
}
private static void RunBeforeHooks(string method, object[] args)
{
var hooks = GetHooks();
for (var i = 0; i < hooks.Length; i++)
{
Contract.Call(hooks[i], "before", CallFlags.All,
new object[] { Runtime.CallingScriptHash, method, args });
}
}| ERC-7746 (Ethereum) | Neo Equivalent | Notes |
|---|---|---|
before(caller, selector, data) | Before(caller, methodName, args) cross-contract call | |
after(caller, selector, data, result) | After(caller, methodName, args, result) | |
| Middleware revert short-circuits | Cross-contract throw aborts the parent tx | Same atomicity |
| Stackable middleware list | hooks[] storage; iterated in order | Direct port |
Migration Notes
For Solidity protocols using middleware:
- Each contract that opts in maintains a
hooks[]storage (admin-managed). - External methods call
RunBeforeHooks/RunAfterHookswrapping the body. - Middleware contracts implement
Before/Afterviews/methods that may revert to halt the call.
For pause-guard / rate-limit patterns specifically, this is the right shape. For one-off compliance checks, a simpler dedicated validator (per the ERC-7144 mirror) is usually enough.
