Custom Protector

Overview

This policy allows you to implement custom logic that checks and maintains the integrity of your smart contract's data by integrating invariants testing tailored to your business requirements.

This works by registering an additional Invariants Logic Contract with the policy, which will receive all the data it needs to identify if a malicious state has taken place.

IMPORTANT: To use this policy, your Firewall Consumer must be using the invariantProtected() modifier for functions you want to protect with this policy

Protected Attack Vector

This policy protects against malicious changes to the state of your smart contracts in a way that violates your business rules.

How It Works

  1. A malicious transaction is sent to your contract.

  2. The policy saves a snapshot of the configured private variables of your smart contract before the transaction is executed.

  3. The transaction is then allowed to start executing it's calls to your smart contracts.

  4. Before the transaction is committed, the policy takes a second snapshot of the private variables, and sends both versions ("before" and "after") to the Invariants Logic Contract.

  5. The Invariants Logic Contract contract inspects the state change.

  6. If the transaction change the state in a way that breaks the protocol's business rules, the transaction will be reverted.

  7. Otherwise, it is allowed to go through and is committed to the blockchain.

Setup Instructions

  1. Deploy your own version of this policy (see Source Code).

  2. Call the setInvariantLogicContract() method to set the address of the Invariants Logic Contract.

  3. Call the setSighashInvariantStorageSlots() method to set the storage slots for the invariants per function.

  4. Add the newly deployed policy to the Firewall (you can do this Globally or Per-Method, see Policy Administration).

  5. That's it!

Properties

Name
Type
Description

invariantLogicContract

address

the address of a smart contract that will inspect the states before / after a transaction is executed

sighashInvariantStorageSlots

mapping

(address => mapping

(bytes4 => bytes32[])

)

Methods

setSighashInvariantStorageSlots()

function setSighashInvariantStorageSlots(address consumer, bytes4 sighash, bytes32[] calldata storageSlots)

Callable only by the policy owner. Sets the memory slots where state is kept (per function signature hash) for the Firewall Consumer's contract.

Parameter Name
Type
Description

consumer

address

the consumer address

sigHash

bytes4

the method signature

storageSlots

bool

the status of the approval

setInvariantLogicContract()

function setInvariantLogicContract(address _invariantLogicContract)

Callable only by the policy owner. Sets the a new address for the Invariants Logic Contract contract.

Parameter Name
Type
Description

_invariantLogicContract

address

the new address to set

Security Lifecycle

This policy runs during both the Firewall's Pre Execution and the Post Execution hooks.

Source Code

On our GitHub repository: SamplePrivateInvariantsPolicy.sol

Last updated