Skip to main content

Caveat enforcers

Caveat enforcers are used to apply specific conditions or restrictions (caveats) to a delegation, ensuring that delegated executions are only performed under predefined circumstances. When creating a delegation, users can include caveats to enforce custom rules, such as spending limits, time constraints, or authorized recipient addresses.

Important
  • Without caveat enforcers, a delegation has infinite and unbounded permissions to make any execution the original account can make. We strongly recommend using caveat enforcers.
  • Enforcers safeguard the execution process but do not guarantee a final state post-redemption.

Caveat enforcers are solidity contracts that extend the ICaveatEnforcer.sol interface. You can restrict a delegation using caveat enforcers that the MetaMask Delegation Toolkit provides out-of-the-box. For more granular or custom control, you can also create custom caveat enforcers.

Out-of-the-box caveat enforcers

The MetaMask Delegation Toolkit provides the following caveat enforcers out-of-the-box:

  • AllowedCalldataEnforcer.sol - Limits the calldata that is executed.

  • AllowedMethodsEnforcer.sol - Limits what methods the delegate can call.

  • AllowedTargetsEnforcer.sol - Limits what addresses the delegate can call.

  • BlockNumberEnforcer.sol - Specifies a range of blocks through which the delegation will be valid.

  • DeployedEnforcer.sol - Ensures a contract is deployed, and if not, deploys the contract.

  • ERC20TransferAmountEnforcer.sol - Limits the transfer of ERC-20 tokens.

  • ERC20BalanceGteEnforcer.sol - Ensures the delegator's ERC-20 balance has increased by at least a specified amount after the execution has been performed, regardless of what the execution is.

  • NonceEnforcer.sol - Adds a nonce to a delegation, and revokes previous delegations by incrementing the current nonce.

  • LimitedCallsEnforcer.sol - Limits the number of times the delegate can perform executions on the delegator's behalf.

  • IdEnforcer.sol - Specifies an ID for multiple delegations. Once one of them is redeemed, the other delegations with the same ID are revoked.

  • TimestampEnforcer.sol - Specifies a range of timestamps through which the delegation will be valid.

  • ValueLteEnforcer.sol - Limits the value of native tokens that the delegate can spend.

  • ArgsEqualityCheckEnforcer.sol - Ensures the arguments provided during delegation match the expected terms set by the delegator.

  • NativeTokenPaymentEnforcer.sol - Enforces a payment before permitting an action to proceed. The redeemer supplies a secondary delegation with an allowance, which the enforcer redeems to process the payment. This redemption impacts the state of other contracts by, for example, decreasing the allowance provider's balance and increasing the recipient's balance. These changes can influence other enforcers that rely on balance validations, depending on their order in the caveats array.

    Example

    For example, if the delegation includes both the NativeBalanceGteEnforcer to ensure Bob's balance has increased, and the NativeTokenPaymentEnforcer to deduct from Bob's balance, the sequence is crucial. Executing the NativeTokenPaymentEnforcer first might cause the NativeBalanceGteEnforcer to fail its validation. Since the NativeTokenPaymentEnforcer modifies external contract states, careful ordering of enforcers is essential to prevent conflicts.

  • NativeBalanceGteEnforcer.sol - Enforces that a recipient's native token balance has increased by at least the specified amount after the execution has been performed, measured between the beforeHook and afterHook calls, regardless of what the execution is. This contract does not enforce how the balance increases. It is intended to be used in conjunction with additional enforcers to create granular permissions.

  • NativeTokenTransferAmountEnforcer.sol - Enforces an allowance of native currency (for example, ETH) for a specific delegation.

  • RedeemerEnforcer.sol - Limits the addresses that can redeem delegations. This caveat enforcer is designed for smart contracts or EOAs lacking delegation support. Delegator accounts with delegation functionalities can bypass these restrictions by delegating to other addresses.