Skip to content

Commit

Permalink
Merge pull request #3 from openfort-xyz/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
eloi010 committed May 31, 2023
2 parents cb0f56e + 788fd33 commit fc83e8c
Show file tree
Hide file tree
Showing 33 changed files with 1,490 additions and 133 deletions.
20 changes: 3 additions & 17 deletions contracts/core/BaseOpenfortAccount.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
Expand All @@ -16,7 +16,7 @@ import "account-abstraction/core/Helpers.sol" as Helpers;
* @notice Minimal smart contract wallet with session keys following the ERC-4337 standard.
* It inherits from:
* - BaseAccount to comply with ERC-4337
* - Initializable because StaticOpenfortAccounts are meant to be created using StaticOpenfortFactory
* - Initializable because accounts are meant to be created using Factories
* - Ownable2StepUpgradeable to have permissions
* - IERC1271Upgradeable for Signature Validation
* - TokenCallbackHandler to support ERC777, ERC721 and ERC1155
Expand All @@ -38,8 +38,6 @@ abstract contract BaseOpenfortAccount is
bytes4 internal constant EXECUTEBATCH_SELECTOR = 0x47e1da2a;
uint48 internal constant DEFAULT_LIMIT = 100;

address internal entrypointContract;

/**
* Struct like ValidationData (from the EIP-4337) - alpha solution - to keep track of session keys' data
* @param validAfter this sessionKey is valid only after this timestamp.
Expand Down Expand Up @@ -78,18 +76,6 @@ abstract contract BaseOpenfortAccount is
_disableInitializers();
}

/*
* @notice Initialize the smart contract wallet.
*/
function initialize(address _defaultAdmin, address _entrypoint, bytes calldata) public virtual;

/**
* @inheritdoc BaseAccount
*/
function entryPoint() public view override returns (IEntryPoint) {
return IEntryPoint(entrypointContract);
}

/**
* Require the function call went through EntryPoint or owner
*/
Expand Down
19 changes: 13 additions & 6 deletions contracts/core/managed/ManagedOpenfortAccount.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

// Base account contract to inherit from
import {BaseOpenfortAccount} from "../BaseOpenfortAccount.sol";
import {BaseOpenfortAccount, IEntryPoint} from "../BaseOpenfortAccount.sol";

/**
* @title ManagedOpenfortAccount (Upgradeable via Beacon)
Expand All @@ -12,14 +12,21 @@ import {BaseOpenfortAccount} from "../BaseOpenfortAccount.sol";
* - BaseOpenfortAccount
*/
contract ManagedOpenfortAccount is BaseOpenfortAccount {
address constant private ENTRYPOINTCONTRACT = 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789;
/*
* @notice Initialize the smart contract wallet.
*/
function initialize(address _defaultAdmin, address _entrypoint, bytes calldata) public override initializer {
if (_defaultAdmin == address(0) || _entrypoint == address(0)) {
function initialize(address _defaultAdmin, bytes calldata) public initializer {
if (_defaultAdmin == address(0)) {
revert ZeroAddressNotAllowed();
}
_transferOwnership(_defaultAdmin);
entrypointContract = _entrypoint;
}

/**
* Return the current EntryPoint
*/
function entryPoint() public pure override returns (IEntryPoint) {
return IEntryPoint(ENTRYPOINTCONTRACT);
}
}
35 changes: 17 additions & 18 deletions contracts/core/managed/ManagedOpenfortFactory.sol
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {BeaconProxy} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
// Smart wallet implementation to use
import {ManagedOpenfortAccount} from "./ManagedOpenfortAccount.sol";
import {OpenfortBeacon} from "./OpenfortBeacon.sol";
import {OpenfortBeaconProxy} from "./OpenfortBeaconProxy.sol";

// Interfaces
import {IBaseOpenfortFactory} from "../../interfaces/IBaseOpenfortFactory.sol";

/**
* @title ManagedOpenfortFactory (Non-upgradeable)
* @author Eloi<[email protected]>
* @notice Contract to create an on-chain factory to deploy new ManagedOpenfortAccounts.
* It uses OpenZeppelin's Create2 and BeaconProxy libraries.
* It uses OpenZeppelin's Create2 and OpenfortBeaconProxy libraries.
* It inherits from:
* - IBaseOpenfortFactory
*/
contract ManagedOpenfortFactory is IBaseOpenfortFactory {
address public immutable entrypointContract;
address public immutable openfortBeacon;

constructor(address _entrypoint, address _openfortBeacon) {
if (_entrypoint == address(0) || _openfortBeacon == address(0)) {
constructor(address _openfortBeacon) {
if ( _openfortBeacon == address(0)) {
revert ZeroAddressNotAllowed();
}
entrypointContract = _entrypoint;
openfortBeacon = _openfortBeacon;
}

Expand All @@ -42,9 +41,9 @@ contract ManagedOpenfortFactory is IBaseOpenfortFactory {

emit AccountCreated(account, _admin);
account = address(
new BeaconProxy{salt: salt}(
new OpenfortBeaconProxy{salt: salt}(
openfortBeacon,
abi.encodeCall(ManagedOpenfortAccount.initialize, (_admin, entrypointContract, _data))
abi.encodeCall(ManagedOpenfortAccount.initialize, (_admin, _data))
)
);
}
Expand All @@ -65,9 +64,9 @@ contract ManagedOpenfortFactory is IBaseOpenfortFactory {

emit AccountCreated(account, _admin);
account = address(
new BeaconProxy{salt: salt}(
new OpenfortBeaconProxy{salt: salt}(
openfortBeacon,
abi.encodeCall(ManagedOpenfortAccount.initialize, (_admin, entrypointContract, _data))
abi.encodeCall(ManagedOpenfortAccount.initialize, (_admin, _data))
)
);
}
Expand All @@ -78,13 +77,13 @@ contract ManagedOpenfortFactory is IBaseOpenfortFactory {
function getAddress(address _admin) public view returns (address) {
bytes32 salt = keccak256(abi.encode(_admin));
return Create2.computeAddress(
bytes32(salt),
salt,
keccak256(
abi.encodePacked(
type(BeaconProxy).creationCode,
type(OpenfortBeaconProxy).creationCode,
abi.encode(
openfortBeacon,
abi.encodeCall(ManagedOpenfortAccount.initialize, (_admin, entrypointContract, ""))
abi.encodeCall(ManagedOpenfortAccount.initialize, (_admin, ""))
)
)
)
Expand All @@ -97,13 +96,13 @@ contract ManagedOpenfortFactory is IBaseOpenfortFactory {
function getAddressWithNonce(address _admin, uint256 nonce) public view returns (address) {
bytes32 salt = keccak256(abi.encode(_admin, nonce));
return Create2.computeAddress(
bytes32(salt),
salt,
keccak256(
abi.encodePacked(
type(BeaconProxy).creationCode,
type(OpenfortBeaconProxy).creationCode,
abi.encode(
openfortBeacon,
abi.encodeCall(ManagedOpenfortAccount.initialize, (_admin, entrypointContract, ""))
abi.encodeCall(ManagedOpenfortAccount.initialize, (_admin, ""))
)
)
)
Expand Down
4 changes: 2 additions & 2 deletions contracts/core/managed/OpenfortBeacon.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";

Expand Down
15 changes: 15 additions & 0 deletions contracts/core/managed/OpenfortBeaconProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {BeaconProxy} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";

/**
* @title OpenfortBeaconProxy (Non-upgradeable)
* @author Eloi<[email protected]>
* @notice Contract to create the Beacon to determine implementation contract, which is where they will delegate all function calls.
* It inherits from:
* - BeaconProxy
*/
contract OpenfortBeaconProxy is BeaconProxy {
constructor(address beacon, bytes memory data) BeaconProxy(beacon, data) {}
}
17 changes: 13 additions & 4 deletions contracts/core/static/StaticOpenfortAccount.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

// Base account contract to inherit from
import {BaseOpenfortAccount} from "../BaseOpenfortAccount.sol";
import {BaseOpenfortAccount, IEntryPoint} from "../BaseOpenfortAccount.sol";

/**
* @title StaticOpenfortAccount (Non-upgradeable)
Expand All @@ -13,12 +13,14 @@ import {BaseOpenfortAccount} from "../BaseOpenfortAccount.sol";
* - BaseOpenfortAccount
*/
contract StaticOpenfortAccount is BaseOpenfortAccount {
address internal entrypointContract;

event EntryPointUpdated(address oldEntryPoint, address newEntryPoint);

/*
* @notice Initialize the smart contract wallet.
*/
function initialize(address _defaultAdmin, address _entrypoint, bytes calldata) public override initializer {
function initialize(address _defaultAdmin, address _entrypoint, bytes calldata) public initializer {
if (_defaultAdmin == address(0) || _entrypoint == address(0)) {
revert ZeroAddressNotAllowed();
}
Expand All @@ -27,6 +29,13 @@ contract StaticOpenfortAccount is BaseOpenfortAccount {
entrypointContract = _entrypoint;
}

/**
* Return the current EntryPoint
*/
function entryPoint() public view override returns (IEntryPoint) {
return IEntryPoint(entrypointContract);
}

/**
* Update the EntryPoint address
*/
Expand Down
4 changes: 2 additions & 2 deletions contracts/core/static/StaticOpenfortFactory.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
// Smart wallet implementation to use
Expand Down
15 changes: 15 additions & 0 deletions contracts/core/upgradeable/OpenfortUpgradeableProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

/**
* @title OpenfortUpgradeableProxy (Non-upgradeable)
* @author Eloi<[email protected]>
* @notice Contract to create the proxies
* It inherits from:
* - ERC1967Proxy
*/
contract OpenfortUpgradeableProxy is ERC1967Proxy {
constructor(address _logic, bytes memory _data) ERC1967Proxy(_logic, _data) {}
}
31 changes: 27 additions & 4 deletions contracts/core/upgradeable/UpgradeableOpenfortAccount.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

// Base account contract to inherit from
import {BaseOpenfortAccount} from "../BaseOpenfortAccount.sol";
import {BaseOpenfortAccount, IEntryPoint} from "../BaseOpenfortAccount.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

/**
Expand All @@ -14,16 +14,39 @@ import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/U
* - UUPSUpgradeable
*/
contract UpgradeableOpenfortAccount is BaseOpenfortAccount, UUPSUpgradeable {
address internal entrypointContract;

event EntryPointUpdated(address oldEntryPoint, address newEntryPoint);

/*
* @notice Initialize the smart contract wallet.
*/
function initialize(address _defaultAdmin, address _entrypoint, bytes calldata) public override initializer {
function initialize(address _defaultAdmin, address _entrypoint, bytes calldata) public initializer {
if (_defaultAdmin == address(0) || _entrypoint == address(0)) {
revert ZeroAddressNotAllowed();
}
emit EntryPointUpdated(entrypointContract, _entrypoint);
_transferOwnership(_defaultAdmin);
entrypointContract = _entrypoint;
}

function _authorizeUpgrade(address) internal override onlyOwner {}

/**
* Return the current EntryPoint
*/
function entryPoint() public view override returns (IEntryPoint) {
return IEntryPoint(entrypointContract);
}

/**
* Update the EntryPoint address
*/
function updateEntryPoint(address _newEntrypoint) external onlyOwner {
if (_newEntrypoint == address(0)) {
revert ZeroAddressNotAllowed();
}
emit EntryPointUpdated(entrypointContract, _newEntrypoint);
entrypointContract = _newEntrypoint;
}
}
24 changes: 12 additions & 12 deletions contracts/core/upgradeable/UpgradeableOpenfortFactory.sol
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
// Smart wallet implementation to use
import {UpgradeableOpenfortAccount} from "./UpgradeableOpenfortAccount.sol";
import {OpenfortUpgradeableProxy} from "./OpenfortUpgradeableProxy.sol";
// Interfaces
import {IBaseOpenfortFactory} from "../../interfaces/IBaseOpenfortFactory.sol";

/**
* @title UpgradeableOpenfortFactory (Non-upgradeable)
* @author Eloi<[email protected]>
* @notice Contract to create an on-chain factory to deploy new UpgradeableOpenfortAccounts.
* It uses OpenZeppelin's Create2 and ERC1967Proxy libraries.
* It uses OpenZeppelin's Create2 and OpenfortUpgradeableProxy libraries.
* It inherits from:
* - IBaseOpenfortFactory
*/
Expand Down Expand Up @@ -41,7 +41,7 @@ contract UpgradeableOpenfortFactory is IBaseOpenfortFactory {

emit AccountCreated(account, _admin);
account = address(
new ERC1967Proxy{salt: salt}(
new OpenfortUpgradeableProxy{salt: salt}(
accountImplementation,
abi.encodeCall(UpgradeableOpenfortAccount.initialize, (_admin, entrypointContract, _data))
)
Expand All @@ -64,7 +64,7 @@ contract UpgradeableOpenfortFactory is IBaseOpenfortFactory {

emit AccountCreated(account, _admin);
account = address(
new ERC1967Proxy{salt: salt}(
new OpenfortUpgradeableProxy{salt: salt}(
accountImplementation,
abi.encodeCall(UpgradeableOpenfortAccount.initialize, (_admin, entrypointContract, _data))
)
Expand All @@ -77,12 +77,12 @@ contract UpgradeableOpenfortFactory is IBaseOpenfortFactory {
function getAddress(address _admin) public view returns (address) {
bytes32 salt = keccak256(abi.encode(_admin));
return Create2.computeAddress(
bytes32(salt),
salt,
keccak256(
abi.encodePacked(
type(ERC1967Proxy).creationCode,
type(OpenfortUpgradeableProxy).creationCode,
abi.encode(
address(accountImplementation),
accountImplementation,
abi.encodeCall(UpgradeableOpenfortAccount.initialize, (_admin, entrypointContract, ""))
)
)
Expand All @@ -96,12 +96,12 @@ contract UpgradeableOpenfortFactory is IBaseOpenfortFactory {
function getAddressWithNonce(address _admin, uint256 nonce) public view returns (address) {
bytes32 salt = keccak256(abi.encode(_admin, nonce));
return Create2.computeAddress(
bytes32(salt),
salt,
keccak256(
abi.encodePacked(
type(ERC1967Proxy).creationCode,
type(OpenfortUpgradeableProxy).creationCode,
abi.encode(
address(accountImplementation),
accountImplementation,
abi.encodeCall(UpgradeableOpenfortAccount.initialize, (_admin, entrypointContract, ""))
)
)
Expand Down
Loading

0 comments on commit fc83e8c

Please sign in to comment.