Skip to content

Commit

Permalink
🚧 create3
Browse files Browse the repository at this point in the history
  • Loading branch information
cruzdanilo committed Dec 31, 2024
1 parent 846642a commit 4fa70ce
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 34 deletions.
9 changes: 5 additions & 4 deletions contracts/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
ExaAccountFactoryTest:testFuzz_createAccount_EOAOwners(uint256,address[63]) (runs: 256, μ: 3621366, ~: 3460632)
ExaPluginTest:testFork_crossRepay_repays() (gas: 19686996)
ExaPluginTest:testFork_debitCollateral_collects() (gas: 19776574)
ExaPluginTest:testFork_swap_swaps() (gas: 16929512)
ExaAccountFactoryTest:testFuzz_createAccount_EOAOwners(uint256,address[63]) (runs: 256, μ: 3627424, ~: 3505072)
ExaAccountFactoryTest:test_deploy_deploysToSameAddress() (gas: 26321134)
ExaPluginTest:testFork_crossRepay_repays() (gas: 15277977)
ExaPluginTest:testFork_debitCollateral_collects() (gas: 15367555)
ExaPluginTest:testFork_swap_swaps() (gas: 12543711)
ExaPluginTest:test_borrowAtMaturity_reverts_withUnauthorized_whenReceiverNotCollector() (gas: 408975)
ExaPluginTest:test_borrow_reverts_withUnauthorized_whenReceiverNotCollector() (gas: 408553)
ExaPluginTest:test_collectCredit_collects() (gas: 921083)
Expand Down
22 changes: 16 additions & 6 deletions contracts/script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,22 @@ contract DeployScript is BaseScript {
acct("keeper")
);

factory = new ExaAccountFactory(
acct("admin"),
WebauthnOwnerPlugin(dependency("webauthn-owner-plugin", "WebauthnOwnerPlugin", "Plugin", 0)),
exaPlugin,
ACCOUNT_IMPL,
ENTRYPOINT
factory = ExaAccountFactory(
payable(
CREATE3_FACTORY.deploy(
keccak256(abi.encode(exaPlugin.NAME(), exaPlugin.VERSION())),
abi.encodePacked(
vm.getCode("ExaAccountFactory.sol:ExaAccountFactory"),
abi.encode(
acct("admin"),
WebauthnOwnerPlugin(dependency("webauthn-owner-plugin", "WebauthnOwnerPlugin", "Plugin", 0)),
exaPlugin,
ACCOUNT_IMPL,
ENTRYPOINT
)
)
)
)
);

factory.donateStake{ value: 0.1 ether }();
Expand Down
67 changes: 43 additions & 24 deletions contracts/test/ExaAccountFactory.t.sol
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0; // solhint-disable-line one-contract-per-file

import { Test } from "forge-std/Test.sol";
import { ForkTest } from "./Fork.t.sol";

import { EntryPoint } from "account-abstraction/core/EntryPoint.sol";

import { UpgradeableModularAccount } from "modular-account/src/account/UpgradeableModularAccount.sol";
import { IEntryPoint } from "modular-account/src/interfaces/erc4337/IEntryPoint.sol";

import { ERC20 } from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import { ERC4626 } from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC4626.sol";

import { FixedPointMathLib } from "solady/utils/FixedPointMathLib.sol";

import { ACCOUNT_IMPL, ENTRYPOINT } from "webauthn-owner-plugin/../script/Factory.s.sol";
import { MAX_OWNERS } from "webauthn-owner-plugin/IWebauthnOwnerPlugin.sol";
import { OwnersLib } from "webauthn-owner-plugin/OwnersLib.sol";
import { WebauthnOwnerPlugin } from "webauthn-owner-plugin/WebauthnOwnerPlugin.sol";

import { DeployScript } from "../script/Deploy.s.sol";
import { ExaAccountFactory, ExaAccountInitialized } from "../src/ExaAccountFactory.sol";
import { ExaPlugin, IBalancerVault, IDebtManager, IInstallmentsRouter } from "../src/ExaPlugin.sol";
import { IAuditor, IMarket } from "../src/IExaAccount.sol";
import { IssuerChecker } from "../src/IssuerChecker.sol";
import { ExaPlugin } from "../src/ExaPlugin.sol";

contract ExaAccountFactoryTest is Test {
contract ExaAccountFactoryTest is ForkTest {
using FixedPointMathLib for uint256;
using OwnersLib for address[];

Expand All @@ -32,24 +31,30 @@ contract ExaAccountFactoryTest is Test {

function setUp() external {
ownerPlugin = new WebauthnOwnerPlugin();
exaPlugin = new ExaPlugin(
address(this),
IAuditor(address(0)),
IMarket(address(new MockERC4626(new MockERC20()))),
IMarket(address(new MockERC4626(new MockERC20()))),
IBalancerVault(address(this)),
IDebtManager(address(this)),
IInstallmentsRouter(address(this)),
IssuerChecker(address(this)),
address(this),
address(this),
address(this)
);

IEntryPoint entryPoint = IEntryPoint(address(new EntryPoint()));
factory = new ExaAccountFactory(
address(this), ownerPlugin, exaPlugin, address(new UpgradeableModularAccount(entryPoint)), entryPoint
);
vm.etch(address(ENTRYPOINT), address(new EntryPoint()).code);
vm.etch(ACCOUNT_IMPL, address(new UpgradeableModularAccount(ENTRYPOINT)).code);
vm.store(address(this), keccak256(abi.encode("deployer")), bytes32(uint256(uint160(address(this)))));

DeployScript d = new DeployScript();
set("Auditor", address(this));
set("MarketUSDC", address(new MockERC4626(new MockERC20())));
set("MarketWETH", address(new MockERC4626(new MockERC20())));
set("BalancerVault", address(this));
set("DebtManager", address(this));
set("InstallmentsRouter", address(this));
set("IssuerChecker", address(this));
set("WebauthnOwnerPlugin", address(ownerPlugin));
d.run();
unset("Auditor");
unset("MarketUSDC");
unset("MarketWETH");
unset("BalancerVault");
unset("DebtManager");
unset("InstallmentsRouter");
unset("IssuerChecker");
unset("WebauthnOwnerPlugin");
exaPlugin = d.exaPlugin();
factory = d.factory();
}

// solhint-disable func-name-mixedcase
Expand Down Expand Up @@ -88,6 +93,20 @@ contract ExaAccountFactoryTest is Test {
}
}

function test_deploy_deploysToSameAddress() external {
address[] memory owners = new address[](1);
owners[0] = address(this);
address account = factory.createAccount(0, owners.toPublicKeys());

vm.createSelectFork("optimism", 127_050_624);

DeployScript d = new DeployScript();
d.run();

assertEq(address(d.factory()), address(factory), "different factory address");
assertEq(factory.getAddress(0, owners.toPublicKeys()), account, "different account address");
}

// solhint-enable func-name-mixedcase

function _sorted(address[] memory owners) internal pure returns (address[] memory) {
Expand Down
40 changes: 40 additions & 0 deletions contracts/test/Fork.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,34 @@ import { Vm } from "forge-std/Vm.sol"; // solhint-disable-line no-unused-import
import { LibString } from "solady/utils/LibString.sol";

abstract contract ForkTest is Test {
using LibString for address;
using LibString for uint256;
using LibString for string;
using LibString for bytes;
using stdJson for string;

ICREATE3Factory internal immutable CREATE3_FACTORY;

constructor() {
CREATE3_FACTORY = ICREATE3Factory(
block.chainid == 11_155_420 // TODO remove after https://github.com/lifinance/create3-factory/issues/14
? 0xcc3f41204a1324DD91F1Dbfc46208535293A371e
: 0x93FEC2C00BfE902F733B57c5a6CeeD7CD1384AE1
);
vm.label(address(CREATE3_FACTORY), "CREATE3Factory");
if (block.chainid == getChain("anvil").chainId) {
bytes memory code =
hex"6080604052600436106100295760003560e01c806350f1c4641461002e578063cdcb760a14610077575b600080fd5b34801561003a57600080fd5b5061004e610049366004610489565b61008a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61004e6100853660046104fd565b6100ee565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084901b166020820152603481018290526000906054016040516020818303038152906040528051906020012091506100e78261014c565b9392505050565b6040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003360601b166020820152603481018390526000906054016040516020818303038152906040528051906020012092506100e78383346102b2565b604080518082018252601081527f67363d3d37363d34f03d5260086018f30000000000000000000000000000000060209182015290517fff00000000000000000000000000000000000000000000000000000000000000918101919091527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166021820152603581018290527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f60558201526000908190610228906075015b6040516020818303038152906040528051906020012090565b6040517fd69400000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201529091506100e79060370161020f565b6000806040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000858251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff811661037d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4445504c4f594d454e545f4641494c454400000000000000000000000000000060448201526064015b60405180910390fd5b6103868661014c565b925060008173ffffffffffffffffffffffffffffffffffffffff1685876040516103b091906105d6565b60006040518083038185875af1925050503d80600081146103ed576040519150601f19603f3d011682016040523d82523d6000602084013e6103f2565b606091505b50509050808015610419575073ffffffffffffffffffffffffffffffffffffffff84163b15155b61047f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f494e495449414c495a4154494f4e5f4641494c454400000000000000000000006044820152606401610374565b5050509392505050565b6000806040838503121561049c57600080fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146104c057600080fd5b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561051057600080fd5b82359150602083013567ffffffffffffffff8082111561052f57600080fd5b818501915085601f83011261054357600080fd5b813581811115610555576105556104ce565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561059b5761059b6104ce565b816040528281528860208487010111156105b457600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000825160005b818110156105f757602081860181015185830152016105dd565b50600092019182525091905056fea26469706673582212201ff95c2aafa102481fdd22c59ee7f98a92a9662a6566ab5e0498e8bb47a5f30c64736f6c63430008110033";
vm.etch(address(CREATE3_FACTORY), code);
try vm.activeFork() {
vm.rpc(
"anvil_setCode",
string.concat('["', address(CREATE3_FACTORY).toHexString(), '","', code.toHexString(), '"]') // solhint-disable-line quotes
);
} catch { } // solhint-disable-line no-empty-blocks
}
}

function set(string memory name, address addr) internal {
vm.store(address(this), keccak256(abi.encode(name)), bytes32(uint256(uint160(addr))));
}
Expand Down Expand Up @@ -87,3 +111,19 @@ abstract contract ForkTest is Test {
}
}
}

interface ICREATE3Factory {
/// @notice Deploys a contract using CREATE3
/// @dev The provided salt is hashed together with msg.sender to generate the final salt
/// @param salt The deployer-specific salt for determining the deployed contract's address
/// @param creationCode The creation code of the contract to deploy
/// @return deployed The address of the deployed contract
function deploy(bytes32 salt, bytes memory creationCode) external payable returns (address deployed);

/// @notice Predicts the address of a deployed contract
/// @dev The provided salt is hashed together with the deployer address to generate the final salt
/// @param deployer The deployer account that will call deploy()
/// @param salt The deployer-specific salt for determining the deployed contract's address
/// @return deployed The address of the contract that will be deployed
function getDeployed(address deployer, bytes32 salt) external view returns (address deployed);
}

0 comments on commit 4fa70ce

Please sign in to comment.