Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check non-view non-multicall functions are protected #461

Merged
merged 7 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/certora.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Certora

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

jobs:
verify:
runs-on: ubuntu-latest

strategy:
fail-fast: false

matrix:
conf:
- AaveV2MigrationBundlerV2
- AaveV3MigrationBundlerV2
- AaveV3OptimizerMigrationBundlerV2
- ChainAgnosticBundlerV2
- CompoundV2MigrationBundlerV2
- CompoundV3MigrationBundlerV2
- EthereumBundlerV2

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install python
uses: actions/setup-python@v5
with:
python-version: ">=3.11"

- name: Install certora
run: pip install certora-cli

- name: Install solc (0.8.24)
run: |
wget https://github.com/ethereum/solidity/releases/download/v0.8.24/solc-static-linux
chmod +x solc-static-linux
sudo mv solc-static-linux /usr/local/bin/solc

- name: Verify ${{ matrix.conf }} specification
run: certoraRun certora/confs/${{ matrix.conf }}.conf
env:
CERTORAKEY: ${{ secrets.CERTORAKEY }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ node_modules/
/artifacts

*.log

# Certora
.certora_internal
35 changes: 35 additions & 0 deletions certora/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Bundlers Formal Verification
adhusson marked this conversation as resolved.
Show resolved Hide resolved

This folder contains the [CVL](https://docs.certora.com/en/latest/docs/cvl/index.html) specification and verification setup for the following bundler contracts:

- [AaveV2MigrationBundlerV2](../src/migration/AaveV2MigrationBundlerV2.sol)
- [AaveV3MigrationBundlerV2](../src/migration/AaveV3MigrationBundlerV2.sol)
- [AaveV3OptimizerMigrationBundlerV2](../src/migration/AaveV3OptimizerMigrationBundlerV2.sol)
- [ChainAgnosticBundlerV2](../src/chain-agnostic/ChainAgnosticBundlerV2.sol)
- [CompoundV2MigrationBundlerV2](../src/migration/CompoundV2MigrationBundlerV2.sol)
- [CompoundV3MigrationBundlerV2](../src/migration/CompoundV3MigrationBundlerV2.sol)
- [EthereumBundlerV2](../src/ethereum/EthereumBundlerV2.sol)

## Getting Started

To verify a specification, run the command `certoraRun Spec.conf` where `Spec.conf` is one of the configuration files in [`certora/confs`](confs).

You must have set the `CERTORAKEY` environment variable to a valid Certora key.

## Overview

Bundler methods used during a bundle execution have the `protected` modifier. This modifier ensures that:
- An initiator has been set, and
- the caller is the bundle initiator or the Morpho contract.
adhusson marked this conversation as resolved.
Show resolved Hide resolved

The `Protected.spec` file checks that all bundler functions, except noted exceptions, respect the requirements of the `protected` modifier when an initiator has been set.

## Verification architecture
adhusson marked this conversation as resolved.
Show resolved Hide resolved

### Folders and file structure

The [`certora/specs`](specs) folder contains the following files:

- [`Protected.spec`](specs/Protected.spec) checks that all methods except noted exceptions respect the `protected` modifier when an initiator has been set.

The [`certora/confs`](confs) folder contains a configuration file for each deployed bundler.
10 changes: 10 additions & 0 deletions certora/confs/AaveV2MigrationBundlerV2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"files": [
"src/migration/AaveV2MigrationBundlerV2.sol",
"certora/harness/Constants.sol"
],
"verify": "AaveV2MigrationBundlerV2:certora/specs/Protected.spec",
"rule_sanity": "basic",
"server": "production",
"msg": "Aave V2 Migration Bundler V2 protected functions"
}
10 changes: 10 additions & 0 deletions certora/confs/AaveV3MigrationBundlerV2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"files": [
"src/migration/AaveV3MigrationBundlerV2.sol",
"certora/harness/Constants.sol"
],
adhusson marked this conversation as resolved.
Show resolved Hide resolved
"verify": "AaveV3MigrationBundlerV2:certora/specs/Protected.spec",
"rule_sanity": "basic",
"server": "production",
"msg": "Aave V3 Migration Bundler V2 protected functions"
}
10 changes: 10 additions & 0 deletions certora/confs/AaveV3OptimizerMigrationBundlerV2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"files": [
"src/migration/AaveV3OptimizerMigrationBundlerV2.sol",
"certora/harness/Constants.sol"
],
"verify": "AaveV3OptimizerMigrationBundlerV2:certora/specs/Protected.spec",
"rule_sanity": "basic",
"server": "production",
"msg": "Aave V3 Optimizer Migration Bundler V2 protected functions"
}
10 changes: 10 additions & 0 deletions certora/confs/ChainAgnosticBundlerV2.conf
QGarchery marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"files": [
"src/chain-agnostic/ChainAgnosticBundlerV2.sol",
"certora/harness/Constants.sol"
],
"verify": "ChainAgnosticBundlerV2:certora/specs/Protected.spec",
"rule_sanity": "basic",
"server": "production",
"msg": "Chain Agnostic Bundler V2 protected functions"
}
10 changes: 10 additions & 0 deletions certora/confs/CompoundV2MigrationBundlerV2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"files": [
"src/migration/CompoundV2MigrationBundlerV2.sol",
"certora/harness/Constants.sol"
],
"verify": "CompoundV2MigrationBundlerV2:certora/specs/Protected.spec",
"rule_sanity": "basic",
"server": "production",
"msg": "Compound V2 Migration Bundler V2 protected functions"
}
10 changes: 10 additions & 0 deletions certora/confs/CompoundV3MigrationBundlerV2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"files": [
"src/migration/CompoundV3MigrationBundlerV2.sol",
"certora/harness/Constants.sol"
],
"verify": "CompoundV3MigrationBundlerV2:certora/specs/Protected.spec",
"rule_sanity": "basic",
"server": "production",
"msg": "Compound V3 Migration Bundler V2 protected functions"
}
10 changes: 10 additions & 0 deletions certora/confs/EthereumBundlerV2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
"files": [
"src/ethereum/EthereumBundlerV2.sol",
"certora/harness/Constants.sol"
],
"verify": "EthereumBundlerV2:certora/specs/Protected.spec",
"rule_sanity": "basic",
"server": "production",
"msg": "Ethereum Bundler V2 protected functions"
}
8 changes: 8 additions & 0 deletions certora/harness/Constants.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity 0.8.24;

import "../../src/libraries/ConstantsLib.sol" as ConstantsLib;

contract Constants {
address public constant UNSET_INITIATOR = ConstantsLib.UNSET_INITIATOR;
}
24 changes: 24 additions & 0 deletions certora/specs/Protected.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-2.0-or-later
using Constants as constants;

methods {
function initiator() external returns(address) envfree;
function MORPHO() external returns(address) envfree;
adhusson marked this conversation as resolved.
Show resolved Hide resolved
function constants.UNSET_INITIATOR() external returns(address) envfree;
}


// Check that all methods except those noted below comply with the `protected` modifier when an initiator has been set.
rule protectedWithSetInitiator(method f, env e, calldataarg data) filtered {
// Do not check view functions.
// Do not check the fallback function.
// Do not check multicall, which is used to start a new bundle.
f -> !f.isView && !f.isFallback && f.selector != sig:multicall(bytes[]).selector
}
{
require e.msg.sender != constants.UNSET_INITIATOR();
adhusson marked this conversation as resolved.
Show resolved Hide resolved
require e.msg.sender != initiator();
require e.msg.sender != MORPHO();
adhusson marked this conversation as resolved.
Show resolved Hide resolved
f@withrevert(e,data);
assert lastReverted;
}
Loading