Skip to content

Commit 7eb34c4

Browse files
authored
Formal verification of Account (7702+7579) (#5872)
1 parent 94d9cc3 commit 7eb34c4

File tree

5 files changed

+618
-0
lines changed

5 files changed

+618
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--- account/extensions/draft-AccountERC7579.sol 2025-07-22 11:18:42.944504471 +0200
2+
+++ account/extensions/draft-AccountERC7579.sol 2025-07-22 13:57:03.670277084 +0200
3+
@@ -60,8 +60,8 @@
4+
using EnumerableSet for *;
5+
using Packing for bytes32;
6+
7+
- EnumerableSet.AddressSet private _validators;
8+
- EnumerableSet.AddressSet private _executors;
9+
+ EnumerableSet.AddressSet internal _validators; // private → internal for FV
10+
+ EnumerableSet.AddressSet internal _executors; // private → internal for FV
11+
mapping(bytes4 selector => address) private _fallbacks;
12+
13+
/// @dev The account's {fallback} was called with a selector that doesn't have an installed handler.
14+
@@ -308,8 +308,9 @@
15+
* the ERC-2771 format.
16+
*/
17+
function _fallback() internal virtual returns (bytes memory) {
18+
- address handler = _fallbackHandler(msg.sig);
19+
- require(handler != address(0), ERC7579MissingFallbackHandler(msg.sig));
20+
+ bytes4 selector = bytes4(msg.data[0:4]);
21+
+ address handler = _fallbackHandler(selector);
22+
+ require(handler != address(0), ERC7579MissingFallbackHandler(selector));
23+
24+
// From https://eips.ethereum.org/EIPS/eip-7579#fallback[ERC-7579 specifications]:
25+
// - MUST utilize ERC-2771 to add the original msg.sender to the calldata sent to the fallback handler

certora/harnesses/AccountHarness.sol

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.26;
3+
4+
import {AccountERC7702WithModulesMock} from "../patched/mocks/account/AccountMock.sol";
5+
import {EIP712} from "../patched/utils/cryptography/EIP712.sol";
6+
import {EnumerableSet} from "../patched/utils/structs/EnumerableSet.sol";
7+
8+
contract AccountHarness is AccountERC7702WithModulesMock {
9+
using EnumerableSet for EnumerableSet.AddressSet;
10+
11+
constructor(string memory name, string memory version) EIP712(name, version) {}
12+
13+
function getFallbackHandler(bytes4 selector) external view returns (address) {
14+
return _fallbackHandler(selector);
15+
}
16+
17+
function getDataSelector(bytes memory data) external pure returns (bytes4) {
18+
return bytes4(data);
19+
}
20+
21+
function _validatorContains(address module) external view returns (bool) {
22+
return _validators.contains(module);
23+
}
24+
25+
function _validatorLength() external view returns (uint256) {
26+
return _validators.length();
27+
}
28+
29+
function _validatorAt(uint256 index) external view returns (address) {
30+
return _validators.at(index);
31+
}
32+
33+
function _validatorAtFull(uint256 index) external view returns (bytes32) {
34+
return _validators._inner._values[index];
35+
}
36+
37+
function _validatorPositionOf(address module) external view returns (uint256) {
38+
return _validators._inner._positions[bytes32(uint256(uint160(module)))];
39+
}
40+
41+
function _executorContains(address module) external view returns (bool) {
42+
return _executors.contains(module);
43+
}
44+
45+
function _executorLength() external view returns (uint256) {
46+
return _executors.length();
47+
}
48+
49+
function _executorAt(uint256 index) external view returns (address) {
50+
return _executors.at(index);
51+
}
52+
53+
function _executorAtFull(uint256 index) external view returns (bytes32) {
54+
return _executors._inner._values[index];
55+
}
56+
57+
function _executorPositionOf(address module) external view returns (uint256) {
58+
return _executors._inner._positions[bytes32(uint256(uint160(module)))];
59+
}
60+
}

certora/specs/Account.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"files": [
3+
"certora/harnesses/AccountHarness.sol"
4+
],
5+
"optimistic_loop": true,
6+
"process": "emv",
7+
"url_visibility": "public",
8+
"verify": "AccountHarness:certora/specs/Account.spec"
9+
}

0 commit comments

Comments
 (0)