# 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](/firewall/glossary.md#firewall-consumer) must be using the [invariantProtected()](/firewall/smart-contracts/firewallconsumer.sol.md#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.<br>
2. The policy saves a snapshot of the configured private variables of your smart contract before the transaction is executed.<br>
3. The transaction is then allowed to start executing it's calls to your smart contracts.<br>
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`.<br>
5. The `Invariants Logic Contract` contract inspects the state change.<br>
6. If the transaction change the state in a way that breaks the protocol's business rules, the transaction will be reverted.<br>
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*](#source-code)*)*.<br>
2. Call the [setInvariantLogicContract()](#setinvariantlogiccontract) method to set the address of the `Invariants Logic Contract`.<br>
3. Call the [setSighashInvariantStorageSlots()](#setsighashinvariantstorageslots) method to set the storage slots for the invariants per function.<br>
4. Add the newly deployed policy to the [Firewall](/firewall/glossary.md#firewall) *(you can do this* [*Globally*](/firewall/configuration/firewall-configuration.md#global-policies) *or* [*Per-Method*](/firewall/configuration/firewall-configuration.md#per-method-policies)*, see* [*Policy Administration*](/firewall/configuration/policy-administration.md)*)*.<br>
5. That's it!

## Properties

<table><thead><tr><th width="334">Name</th><th width="256.3333333333333">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>invariantLogicContract</code></td><td><code>address</code></td><td>the address of a smart contract that will inspect the states before / after a transaction is executed</td></tr><tr><td><code>sighashInvariantStorageSlots</code></td><td><p><code>mapping</code></p><p><code>(address => mapping</code></p><p> <code>(bytes4 => bytes32[])</code></p><p><code>)</code></p></td><td>a mapping between addresses of <a href="/pages/SytHKgKfwQDKzbldyqNt#firewall-consumer">Firewall Consumers</a> to a mapping of sig-hashes and memory addresses where state changes are stored</td></tr></tbody></table>

## 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](/firewall/glossary.md#firewall-consumer) contract.<br>

| 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.<br>

<table><thead><tr><th width="282.3333333333333">Parameter Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>_invariantLogicContract</code></td><td><code>address</code></td><td>the new address to set</td></tr></tbody></table>

<br>

## **Security Lifecycle**

This policy runs during both the Firewall's [Pre Execution](/firewall/glossary.md#pre-execution) and the [Post Execution](/firewall/glossary.md#post-execution) hooks.

## Source Code

On our GitHub repository: [SamplePrivateInvariantsPolicy.sol](https://github.com/ironblocks/onchain-firewall/blob/main/packages/onchain-firewall/contracts/samples/SamplePrivateInvariantsPolicy.sol)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ironblocks.com/firewall/policies/custom-protector.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
