Skip to content

Commit

Permalink
chore: update deploy scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
jaypaik committed Apr 26, 2024
1 parent 0a94800 commit 79253aa
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ RPC_URL_MAINNET=
RPC_URL_GOERLI=

ETHERSCAN_API_KEY=

ENTRYPOINT=0x0000000071727De22E5E9d8BAf0edAc6f37da032 # EntryPoint v0.7
OWNER=0xDdF32240B4ca3184De7EC8f0D5Aba27dEc8B7A5C
REQUIRED_STAKE_AMOUNT=100000000000000000 # 0.1 ETH
UNSTAKE_DELAY_SEC=86400 # 1 day
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ cache/
.env

broadcast/**/run-latest.json
broadcast/**/dry-run/**/*
broadcast/**/dry-run/**/*

.DS_Store
57 changes: 36 additions & 21 deletions script/Deploy_LightAccountFactory.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,53 +7,68 @@ import {IEntryPoint} from "account-abstraction/interfaces/IEntryPoint.sol";

import {LightAccountFactory} from "../src/LightAccountFactory.sol";

// @notice Deploys LightAccountFactory to the address `0x00004EC70002a32400f8ae005A26081065620D20`
// @dev Note: Script uses EntryPoint at address 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
// @notice Deploys LightAccountFactory
// @dev To run: `forge script script/Deploy_LightAccountFactory.s.sol:Deploy_LightAccountFactory --broadcast --rpc-url ${RPC_URL} --verify -vvvv`
contract Deploy_LightAccountFactory is Script {
// Load entrypoint from env
address public entryPointAddr = vm.envAddress("ENTRYPOINT");
IEntryPoint public entryPoint = IEntryPoint(payable(entryPointAddr));

// Load factory owner from env
address public owner = vm.envAddress("OWNER");

error InitCodeHashMismatch(bytes32 initCodeHash);
error DeployedAddressMismatch(address deployed);

function run() public {
vm.startBroadcast();

// Using entryPoint: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
// Correct as of Jan 10 2024, from https://docs.alchemy.com/reference/eth-supportedentrypoints
IEntryPoint entryPoint = IEntryPoint(payable(0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789));

// Init code hash check
bytes32 initCodeHash = keccak256(
abi.encodePacked(type(LightAccountFactory).creationCode, bytes32(uint256(uint160(address(entryPoint)))))
);
bytes32 initCodeHash =
keccak256(abi.encodePacked(type(LightAccountFactory).creationCode, abi.encode(owner, entryPoint)));

if (initCodeHash != 0x23fb754854a6aa03057b1bae5d971963d92e534dc714fa59fff6c08a3617ba3e) {
if (initCodeHash != 0xfad339962af095db6ac3163c8504f102c28ae099db994101fbbca18ad0e3005c) {
revert InitCodeHashMismatch(initCodeHash);
}

console.log("********************************");
console.log("******** Deploy Inputs *********");
console.log("********************************");
console.log("Entrypoint Address is:");
console.logAddress(address(entryPoint));
console.log("Owner:", owner);
console.log("Entrypoint:", address(entryPoint));
console.log();
console.log("********************************");
console.log("******** Deploy ...... *********");
console.log("******** Deploying.... *********");
console.log("********************************");

// TODO: Use environment variable for factory owner.
LightAccountFactory factory = new LightAccountFactory{
salt: 0x4e59b44847b379578588920ca78fbf26c0b4956c5528f3e2f146000008fabf77
}(msg.sender, entryPoint);
salt: 0x00000000000000000000000000000000000000005f1ffd9d31306e056bcc959b
}(owner, entryPoint);

// Deployed address check
if (address(factory) != 0x00004EC70002a32400f8ae005A26081065620D20) {
if (address(factory) != 0x0000000000400CdFef5E2714E63d8040b700BC24) {
revert DeployedAddressMismatch(address(factory));
}

console.log("LightAccountFactory address:");
console.logAddress(address(factory));
_addStakeForFactory(address(factory));

console.log("LightAccountFactory:", address(factory));
console.log("LightAccount:", address(factory.ACCOUNT_IMPLEMENTATION()));
console.log();

console.log("Implementation address:");
console.logAddress(address(factory.ACCOUNT_IMPLEMENTATION()));
vm.stopBroadcast();
}

function _addStakeForFactory(address factoryAddr) internal {
uint32 unstakeDelaySec = uint32(vm.envOr("UNSTAKE_DELAY_SEC", uint32(86400)));
uint256 requiredStakeAmount = vm.envUint("REQUIRED_STAKE_AMOUNT");
uint256 currentStakedAmount = entryPoint.getDepositInfo(factoryAddr).stake;
uint256 stakeAmount = requiredStakeAmount - currentStakedAmount;
LightAccountFactory(payable(factoryAddr)).addStake{value: stakeAmount}(unstakeDelaySec, stakeAmount);
console.log("******** Add Stake Verify *********");
console.log("Staked factory: ", factoryAddr);
console.log("Stake amount: ", entryPoint.getDepositInfo(factoryAddr).stake);
console.log("Unstake delay: ", entryPoint.getDepositInfo(factoryAddr).unstakeDelaySec);
console.log("******** Stake Verify Done *********");
}
}
74 changes: 74 additions & 0 deletions script/Deploy_MultiOwnerLightAccountFactory.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

import "forge-std/Script.sol";

import {IEntryPoint} from "account-abstraction/interfaces/IEntryPoint.sol";

import {MultiOwnerLightAccountFactory} from "../src/MultiOwnerLightAccountFactory.sol";

// @notice Deploys MultiOwnerLightAccountFactory
// @dev To run: `forge script script/Deploy_MultiOwnerLightAccountFactory.s.sol:Deploy_MultiOwnerLightAccountFactory --broadcast --rpc-url ${RPC_URL} --verify -vvvv`
contract Deploy_MultiOwnerLightAccountFactory is Script {
// Load entrypoint from env
address public entryPointAddr = vm.envAddress("ENTRYPOINT");
IEntryPoint public entryPoint = IEntryPoint(payable(entryPointAddr));

// Load factory owner from env
address public owner = vm.envAddress("OWNER");

error InitCodeHashMismatch(bytes32 initCodeHash);
error DeployedAddressMismatch(address deployed);

function run() public {
vm.startBroadcast();

// Init code hash check
bytes32 initCodeHash =
keccak256(abi.encodePacked(type(MultiOwnerLightAccountFactory).creationCode, abi.encode(owner, entryPoint)));

if (initCodeHash != 0x69e0f4a2942425638860e9982bd32f08941a082681e53208de970099f18252cc) {
revert InitCodeHashMismatch(initCodeHash);
}

console.log("********************************");
console.log("******** Deploy Inputs *********");
console.log("********************************");
console.log("Owner:", owner);
console.log("Entrypoint:", address(entryPoint));
console.log();
console.log("********************************");
console.log("******** Deploying.... *********");
console.log("********************************");

MultiOwnerLightAccountFactory factory = new MultiOwnerLightAccountFactory{
salt: 0x0000000000000000000000000000000000000000bb3ab048b3f4ef2620ea0163
}(owner, entryPoint);

// Deployed address check
if (address(factory) != 0x000000000019d2Ee9F2729A65AfE20bb0020AefC) {
revert DeployedAddressMismatch(address(factory));
}

_addStakeForFactory(address(factory));

console.log("MultiOwnerLightAccountFactory:", address(factory));
console.log("MultiOwnerLightAccount:", address(factory.ACCOUNT_IMPLEMENTATION()));
console.log();

vm.stopBroadcast();
}

function _addStakeForFactory(address factoryAddr) internal {
uint32 unstakeDelaySec = uint32(vm.envOr("UNSTAKE_DELAY_SEC", uint32(86400)));
uint256 requiredStakeAmount = vm.envUint("REQUIRED_STAKE_AMOUNT");
uint256 currentStakedAmount = entryPoint.getDepositInfo(factoryAddr).stake;
uint256 stakeAmount = requiredStakeAmount - currentStakedAmount;
MultiOwnerLightAccountFactory(payable(factoryAddr)).addStake{value: stakeAmount}(unstakeDelaySec, stakeAmount);
console.log("******** Add Stake Verify *********");
console.log("Staked factory: ", factoryAddr);
console.log("Stake amount: ", entryPoint.getDepositInfo(factoryAddr).stake);
console.log("Unstake delay: ", entryPoint.getDepositInfo(factoryAddr).unstakeDelaySec);
console.log("******** Stake Verify Done *********");
}
}
42 changes: 42 additions & 0 deletions script/GetInitCodeHash.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;

import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/Test.sol";

import {IEntryPoint} from "account-abstraction/interfaces/IEntryPoint.sol";

import {LightAccountFactory} from "../src/LightAccountFactory.sol";
import {MultiOwnerLightAccountFactory} from "../src/MultiOwnerLightAccountFactory.sol";

contract GetInitCodeHash is Script {
// Load entrypoint from env
address public entryPointAddr = vm.envAddress("ENTRYPOINT");
IEntryPoint public entryPoint = IEntryPoint(payable(entryPointAddr));

// Load factory owner from env
address public owner = vm.envAddress("OWNER");

function run() public view {
console.log("******** Calculating Init Code Hashes *********");
console.log("Chain: ", block.chainid);
console.log("EP: ", entryPointAddr);
console.log("Factory owner: ", owner);

bytes memory lightAccountFactoryInitCode =
abi.encodePacked(type(LightAccountFactory).creationCode, abi.encode(owner, entryPoint));

bytes32 lightAccountFactoryInitCodeHash = keccak256(lightAccountFactoryInitCode);

console.log("LightAccountFactory init code hash:");
console.logBytes32(lightAccountFactoryInitCodeHash);

bytes memory multiOwnerLightAccountFactoryInitCode =
abi.encodePacked(type(MultiOwnerLightAccountFactory).creationCode, abi.encode(owner, entryPoint));

bytes32 multiOwnerLightAccountFactoryInitCodeHash = keccak256(multiOwnerLightAccountFactoryInitCode);

console.log("MultiOwnerLightAccountFactory init code hash:");
console.logBytes32(multiOwnerLightAccountFactoryInitCodeHash);
}
}
16 changes: 7 additions & 9 deletions test/LightAccount.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ contract LightAccountTest is Test {
uint256 public constant EOA_PRIVATE_KEY = 1;
address payable public constant BENEFICIARY = payable(address(0xbe9ef1c1a2ee));
bytes32 internal constant _MESSAGE_TYPEHASH = keccak256("LightAccountMessage(bytes message)");
address public factoryOwner = 0xDdF32240B4ca3184De7EC8f0D5Aba27dEc8B7A5C;
address public entryPointAddr = 0x0000000071727De22E5E9d8BAf0edAc6f37da032;
address public eoaAddress;
LightAccount public account;
EntryPoint public entryPoint;
Expand All @@ -35,8 +37,9 @@ contract LightAccountTest is Test {

function setUp() public {
eoaAddress = vm.addr(EOA_PRIVATE_KEY);
entryPoint = new EntryPoint();
LightAccountFactory factory = new LightAccountFactory(address(this), entryPoint);
vm.etch(entryPointAddr, address(new EntryPoint()).code);
entryPoint = EntryPoint(payable(entryPointAddr));
LightAccountFactory factory = new LightAccountFactory(factoryOwner, entryPoint);
account = factory.createAccount(eoaAddress, 1);
vm.deal(address(account), 1 << 128);
lightSwitch = new LightSwitch();
Expand Down Expand Up @@ -479,13 +482,8 @@ contract LightAccountTest is Test {

function testValidateInitCodeHash() external {
assertEq(
keccak256(
abi.encodePacked(
type(LightAccountFactory).creationCode,
bytes32(uint256(uint160(0x0000000071727De22E5E9d8BAf0edAc6f37da032)))
)
),
0x5ad3bccf602cb277e15f7bcac8cd88873618c6f038cbcd490610d91be26fcf34
keccak256(abi.encodePacked(type(LightAccountFactory).creationCode, abi.encode(factoryOwner, entryPoint))),
0xfad339962af095db6ac3163c8504f102c28ae099db994101fbbca18ad0e3005c
);
}

Expand Down
14 changes: 7 additions & 7 deletions test/MultiOwnerLightAccount.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ contract MultiOwnerLightAccountTest is Test {
uint256 public constant EOA_PRIVATE_KEY = 1;
address payable public constant BENEFICIARY = payable(address(0xbe9ef1c1a2ee));
bytes32 internal constant _MESSAGE_TYPEHASH = keccak256("LightAccountMessage(bytes message)");
address public factoryOwner = 0xDdF32240B4ca3184De7EC8f0D5Aba27dEc8B7A5C;
address public entryPointAddr = 0x0000000071727De22E5E9d8BAf0edAc6f37da032;
address public eoaAddress;
MultiOwnerLightAccount public account;
MultiOwnerLightAccount public contractOwnedAccount;
Expand All @@ -39,8 +41,9 @@ contract MultiOwnerLightAccountTest is Test {

function setUp() public {
eoaAddress = vm.addr(EOA_PRIVATE_KEY);
entryPoint = new EntryPoint();
MultiOwnerLightAccountFactory factory = new MultiOwnerLightAccountFactory(address(this), entryPoint);
vm.etch(entryPointAddr, address(new EntryPoint()).code);
entryPoint = EntryPoint(payable(entryPointAddr));
MultiOwnerLightAccountFactory factory = new MultiOwnerLightAccountFactory(factoryOwner, entryPoint);
account = factory.createAccountSingle(eoaAddress, 1);
vm.deal(address(account), 1 << 128);
lightSwitch = new LightSwitch();
Expand Down Expand Up @@ -625,12 +628,9 @@ contract MultiOwnerLightAccountTest is Test {
function testValidateInitCodeHash() external {
assertEq(
keccak256(
abi.encodePacked(
type(MultiOwnerLightAccountFactory).creationCode,
bytes32(uint256(uint160(0x0000000071727De22E5E9d8BAf0edAc6f37da032)))
)
abi.encodePacked(type(MultiOwnerLightAccountFactory).creationCode, abi.encode(factoryOwner, entryPoint))
),
0x80c58908b2149ff4b21996454a1ad577de59738d9f23637fe3f01506a8836767
0x69e0f4a2942425638860e9982bd32f08941a082681e53208de970099f18252cc
);
}

Expand Down

0 comments on commit 79253aa

Please sign in to comment.