Everything you need to get started with Ironblocks' Firewall using Foundry.
Using Hardhat?
we're working on a hardhat version of this repo - stay tuned
Table Of Contents
This project serves as a Hello World example for getting started with Ironblocks' Firewall.
It includes 2 (very) simple contracts to demonstrate how the Firewall works:
-
HelloFirewall.sol- a simple counter-like smart contract -
HelloFirewallPolicy.sol- a security policy that limits counter increments to a set threshold
- This project uses Foundry, so make sure you have it installed before continuing.
-
Build the project by running:
forge build
-
Open a new terminal, and start a local development node with Anvil by running:
anvil
-
Open a second terminal, and run the
SetupEverythingSolidity Script:forge script \ --broadcast \ --rpc-url "http://127.0.0.1:8545" \ --private-key "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" \ script/SetupEverything.s.sol
-
You'll find a convenience helper script under
bin/anvil/setup-everything.shthat runs the above command. -
The private key belongs to the first account built into Anvil (i.e. the first test account).
Now that everything is deployed, if you try to call increment() on the HelloFirewall smart contract multiple times, you'll notice that only the first call works.
-
Run the
IncrementSolidity Script to increment the number stored by ourHelloFirewallexample contract:forge script \ --broadcast \ --rpc-url "http://127.0.0.1:8545" \ --private-key "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" \ script/hello-firewall/Increment.s.sol
-
Run the script again.
This time it, the call gets blocked by the Firewall.
The second transaction failed, because the HelloFirewallPolicy is preventing increments larger than a configured threshold. For simplicity, the default threshold is set to 1, so only the first increment call passes (i.e. we can't increment to a number larger than 1).
-
Run the
setIncrementThresholdSolidity Script, which is hardcoded to update the threshold to3:forge script \ --broadcast \ --rpc-url "http://127.0.0.1:8545" \ --private-key "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" \ script/hello-firewall-policy/SetIncrementThreshold.s.sol
-
Now that the policy's configuration was updated, we can send 2 additional
Incrementrequests by calling theIncrementSolidity Script two more times:forge script \ --broadcast \ --rpc-url "http://127.0.0.1:8545" \ --private-key "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" \ script/hello-firewall/Increment.s.sol
* run this twice
-
Last, if you try to call
Incrementfor a third time, it will again be prevented by theHelloFirewallPolicy.
If you examine the SetupEverything Solidity Script, you'll notice there are several steps required to protect a smart contract. Let's recap what contracts and configurations were set up.
For the purpose of simplicity, all the contracts that are deployed and used in this project are owned by the same account - the default first account provided by Anvil.
-
HelloFirewall.sol- this is our demo counter smart contract -
HelloFirewallPolicy.sol- this is our custom security policy, which prevents anyone from incrementing the counter above a configurable threshold -
Firewall.sol- this is the smart contract for the Firewall. It provides methods that allow a Firewall Consumer to subscribe or unsubscribe to security policies. It also allows the Firewall Owner to approve or disapprove what security policies will be available to Firewall ConsumersThe
Firewall Owneris the principal (person, people, or organization) that deployed the FirewallA
Firewall Consumeris a smart contract - such as ourHelloFirewall.sol- which inherits theFirewallConsumer.solcontract so that it can consume security services from the Firewall.
-
Every transaction sent to our
HelloFirewallcontract will be examined theFirewall. For this to work, we first need to tell it whatFirewallto use.
We do this by callingsetFirewall(FIREWALL_ADDRESS)on theHelloFirewallsmart contract. -
As an additional layer of security, only policies that have been approved by a
Firewall Ownerwill be available toFirewall Consumersfor them to subscribe to.
This is done by callingsetPolicyStatus(POLICY_ADDRESS, BOOLEAN)on theFirewall.The
Firewall Ownerin this demo is the same account that deploys theHelloFirewall.In real world scenarios, the
Firewall Ownermay be any principal (person, people, or organization), as governed or decentralized as needed (i.e. DAO etc.) -
Last, our
HelloFirewallsmart contract needs to tell theFirewallwhat security policies should be configured to protect it. In our case, we tell theFirewallthat we want theHelloFirewallPolicysecurity policy to protect all calls to our smart contract. We do this by callingaddGlobalPolicy(OUR_ADDRESS, POLICY_ADDRESS)on theFirewall.Note that within our
HelloFirewallexample contract, only functions that have thefirewallProtectedmodifier will be protected by theFirewallMore advanced modifiers and configuration options are also available, see the official documentation for more info (link below)
- Official Documentation
- Discord Channel
- Website