Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,24 +95,35 @@ forge test

#### Deploying

0. Copy `.env.example` to `.env` and populate the variables you plan to use if you plan to deploy any contracts.
1. Copy `.env.example` to `.env` and populate the variables depending on the deployment scripts that you will execute.

```shell
source .env
```

1. Use [Anvil](https://book.getfoundry.sh/reference/anvil/) to run a local fork of a blockchain to develop in an isolated environment.
2. For local testing, use [Anvil](https://book.getfoundry.sh/reference/anvil/) to run a local fork of a blockchain to develop in an isolated environment. Or obtain the RPC url for the blockchain to deploy.

```shell
# Example of a forked local environment using anvil
anvil -f <your_rpc_url>
```

2. Deploy the necessary environment contracts.
3. Deploy the necessary contracts.

> NOTE: As this system matures, this step will no longer be required for public chains where the DeleGator is in use.

```shell
forge script script/DeployEnvironmentSetUp.s.sol --rpc-url <your_rpc_url> --private-key $PRIVATE_KEY --broadcast
# Deploys the Delegation Manager, Multisig and Hybrid DeleGator implementations
forge script script/DeployDelegationFramework.s.sol --rpc-url <your_rpc_url> --private-key $PRIVATE_KEY --broadcast

# Deploys all the caveat enforcers
forge script script/DeployCaveatEnforcers.s.sol --rpc-url <your_rpc_url> --private-key $PRIVATE_KEY --broadcast

# Deploys the EIP7702 Staless DeleGator
forge script script/DeployEIP7702StatelessDeleGator.s.sol --rpc-url <your_rpc_url> --private-key $PRIVATE_KEY --broadcast

# Deploys a MultisigDeleGator on a UUPS proxy
forge script script/DeployMultiSigDeleGator.s.sol --private-key $PRIVATE_KEY --broadcast
```

### Javascript
Expand Down Expand Up @@ -143,3 +154,5 @@ Currently in Gated Alpha phase. Sign up to be an early partner [here](https://ga
- [EIP-7201](https://eips.ethereum.org/EIPS/eip-7201)
- [EIP-7212](https://eips.ethereum.org/EIPS/eip-7212)
- [EIP-7579](https://eips.ethereum.org/EIPS/eip-7579)
- [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)
- [EIP-7821](https://eips.ethereum.org/EIPS/eip-7821)
23 changes: 23 additions & 0 deletions documents/EIP7702DeleGator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# EIP-7702 Smart Contracts

## Overview

This document provides an overview of the implemented EIP-7702-compatible contracts. These contracts use a different upgrade mechanism than the previous UUPS proxy-based architecture (as implemented in DeleGatorCore) and instead follow the EIP-7702 standard.

Under EIP-7702, an Externally Owned Account (EOA) can submit an authorization to map the contract code of an existing contract to that EOA. Unlike UUPS proxy-based contracts, this approach neither supports contract initialization nor relies on UUPS-related code.

## Contracts

### 1. EIP7702DeleGatorCore.sol

**EIP7702DeleGatorCore** serves as the foundational contract for EIP-7702-compatible delegator functionality with ERC-7710. It acts as the primary interface for interactions under EIP-7702 and implements the EIP-7821 interface, which provides a method to execute calls in different modes (e.g., single or batch). These methods can be invoked either through the privileged ERC-4337 EntryPoint or directly via the EOA address.

Future implementations may introduce additional features, such as signature validation, as outlined in EIP-7821.

This contract also integrates OpenZeppelin’s EIP712 functionality. The name and version used in the EIP712 constructor are limited to a maximum of 31 bytes. Exceeding this limit causes those variables to be stored in the contract state without namespace storage, leading to conflicts. Restricting the name and version size helps ensure that **EIP7702DeleGatorCore** remains stateless by avoiding additional storage.

### 2. EIP7702StatelessDeleGator.sol

**EIP7702StatelessDeleGator** does not maintain signer data within the contract state. Instead, control is granted to the EOA that shares the same address, in accordance with EIP-7702. The contract can be invoked either through the privileged ERC-4337 EntryPoint or directly via the EOA address. The signature is verified via the `isValidSignature()` function.

This stateless design offers a lightweight and secure approach to delegator functionality under the EIP-7702 standard.
50 changes: 50 additions & 0 deletions script/DeployEIP7702StatelessDeleGator.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-License-Identifier: MIT AND Apache-2.0
pragma solidity 0.8.23;

import "forge-std/Script.sol";
import { console2 } from "forge-std/console2.sol";
import { IEntryPoint } from "@account-abstraction/interfaces/IEntryPoint.sol";

import { EIP7702StatelessDeleGator } from "../src/EIP7702/EIP7702StatelessDeleGator.sol";
import { IDelegationManager } from "../src/interfaces/IDelegationManager.sol";

/**
* @title DeployEIP7702StatelessDeleGator.s.sol
* @notice Deploys the required contracts for the EIP7702 StatelessDeleGator to function.
* @dev These contracts are likely already deployed on a testnet or mainnet as many are singletons.
* @dev run the script with:
* forge script script/DeployEIP7702StatelessDeleGator.s.sol --rpc-url <your_rpc_url> --private-key $PRIVATE_KEY --broadcast
*/
contract DeployEIP7702StatelessDeleGator is Script {
bytes32 salt;
IEntryPoint entryPoint;
IDelegationManager delegationManager;
address deployer;

function setUp() public {
salt = bytes32(abi.encodePacked(vm.envString("SALT")));
entryPoint = IEntryPoint(vm.envAddress("ENTRYPOINT_ADDRESS"));
delegationManager = IDelegationManager(vm.envAddress("DELEGATION_MANAGER_ADDRESS"));
deployer = msg.sender;
console2.log("~~~");
console2.log("Deployer: %s", address(deployer));
console2.log("Entry Point: %s", address(entryPoint));
console2.log("Delegation Manager: %s", address(delegationManager));
console2.log("Salt:");
console2.logBytes32(salt);
}

function run() public {
console2.log("~~~");
vm.startBroadcast();

address deployedAddress;

// Deploy EIP7702StatelessDeleGator

deployedAddress = address(new EIP7702StatelessDeleGator{ salt: salt }(IDelegationManager(delegationManager), entryPoint));
console2.log("EIP7702StatelessDeleGatorImpl: %s", deployedAddress);

vm.stopBroadcast();
}
}
Loading