Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add allowlist deploy script & fix existing deploy script [2/2] #127

Merged
merged 4 commits into from
Aug 2, 2024
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
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ ENTRYPOINT=
# Create2 expected addresses of the contracts.
# When running for the first time, the error message will contain the expected addresses.
ACCOUNT_IMPL=
FACTORY=
SINGLE_SIGNER_VALIDATION=
FACTORY=

# Optional, defaults to bytes32(0)
ACCOUNT_IMPL_SALT=
Expand All @@ -18,3 +18,7 @@ SINGLE_SIGNER_VALIDATION_SALT=
# Optional, defaults to 0.1 ether and 1 day, respectively
STAKE_AMOUNT=
UNSTAKE_DELAY=

# Allowlist Module
ALLOWLIST_MODULE=
ALLOWLIST_MODULE_SALT=
21 changes: 21 additions & 0 deletions .solhint-script.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"extends": "solhint:recommended",
"rules": {
"func-name-mixedcase": "off",
"immutable-vars-naming": ["error"],
"no-unused-import": ["error"],
"compiler-version": ["error", ">=0.8.19"],
"custom-errors": "off",
"no-console": "off",
"func-visibility": ["error", { "ignoreConstructors": true }],
"max-line-length": ["error", 120],
"max-states-count": ["warn", 30],
"modifier-name-mixedcase": ["error"],
"private-vars-leading-underscore": ["error"],
"no-inline-assembly": "warn",
"avoid-low-level-calls": "off",
"one-contract-per-file": "off",
"no-empty-blocks": "off",
"reason-string": "off"
}
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
"solhint": "^3.6.2"
},
"scripts": {
"lint": "pnpm lint:src && pnpm lint:test",
"lint": "pnpm lint:src && pnpm lint:test && pnpm lint:script",
"lint:src": "solhint --max-warnings 0 -c .solhint-src.json './src/**/*.sol'",
"lint:test": "solhint --max-warnings 0 -c .solhint-test.json './test/**/*.sol'"
"lint:test": "solhint --max-warnings 0 -c .solhint-test.json './test/**/*.sol'",
"lint:script": "solhint --max-warnings 0 -c .solhint-script.json './script/**/*.sol'"
}
}
87 changes: 43 additions & 44 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
pragma solidity ^0.8.25;

import {IEntryPoint} from "@eth-infinitism/account-abstraction/interfaces/IEntryPoint.sol";
import {Script} from "forge-std/Script.sol";
import {console2} from "forge-std/Test.sol";
import {Script, console} from "forge-std/Script.sol";

import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";

Expand All @@ -28,10 +27,10 @@ contract DeployScript is Script {
uint256 public requiredUnstakeDelay = vm.envOr("UNSTAKE_DELAY", uint256(1 days));

function run() public {
console2.log("******** Deploying ERC-6900 Reference Implementation ********");
console2.log("Chain: ", block.chainid);
console2.log("EP: ", address(entryPoint));
console2.log("Factory owner: ", owner);
console.log("******** Deploying ERC-6900 Reference Implementation ********");
console.log("Chain: ", block.chainid);
console.log("EP: ", address(entryPoint));
console.log("Factory owner: ", owner);

vm.startBroadcast();
_deployAccountImpl(accountImplSalt, accountImpl);
Expand All @@ -42,69 +41,69 @@ contract DeployScript is Script {
}

function _deployAccountImpl(bytes32 salt, address expected) internal {
console2.log(string.concat("Deploying AccountImpl with salt: ", vm.toString(salt)));
console.log(string.concat("Deploying AccountImpl with salt: ", vm.toString(salt)));

address addr = Create2.computeAddress(
salt,
keccak256(abi.encodePacked(type(UpgradeableModularAccount).creationCode, abi.encode(entryPoint))),
CREATE2_FACTORY
);
if (addr != expected) {
console2.log("Expected address mismatch");
console2.log("Expected: ", expected);
console2.log("Actual: ", addr);
console.log("Expected address mismatch");
console.log("Expected: ", expected);
console.log("Actual: ", addr);
revert();
}

if (addr.code.length == 0) {
console2.log("No code found at expected address, deploying...");
console.log("No code found at expected address, deploying...");
UpgradeableModularAccount deployed = new UpgradeableModularAccount{salt: salt}(entryPoint);

if (address(deployed) != expected) {
console2.log("Deployed address mismatch");
console2.log("Expected: ", expected);
console2.log("Deployed: ", address(deployed));
console.log("Deployed address mismatch");
console.log("Expected: ", expected);
console.log("Deployed: ", address(deployed));
revert();
}

console2.log("Deployed AccountImpl at: ", address(deployed));
console.log("Deployed AccountImpl at: ", address(deployed));
} else {
console2.log("Code found at expected address, skipping deployment");
console.log("Code found at expected address, skipping deployment");
}
}

function _deploySingleSignerValidation(bytes32 salt, address expected) internal {
console2.log(string.concat("Deploying SingleSignerValidation with salt: ", vm.toString(salt)));
console.log(string.concat("Deploying SingleSignerValidation with salt: ", vm.toString(salt)));

address addr = Create2.computeAddress(
salt, keccak256(abi.encodePacked(type(SingleSignerValidation).creationCode)), CREATE2_FACTORY
);
if (addr != expected) {
console2.log("Expected address mismatch");
console2.log("Expected: ", expected);
console2.log("Actual: ", addr);
console.log("Expected address mismatch");
console.log("Expected: ", expected);
console.log("Actual: ", addr);
revert();
}

if (addr.code.length == 0) {
console2.log("No code found at expected address, deploying...");
console.log("No code found at expected address, deploying...");
SingleSignerValidation deployed = new SingleSignerValidation{salt: salt}();

if (address(deployed) != expected) {
console2.log("Deployed address mismatch");
console2.log("Expected: ", expected);
console2.log("Deployed: ", address(deployed));
console.log("Deployed address mismatch");
console.log("Expected: ", expected);
console.log("Deployed: ", address(deployed));
revert();
}

console2.log("Deployed SingleSignerValidation at: ", address(deployed));
console.log("Deployed SingleSignerValidation at: ", address(deployed));
} else {
console2.log("Code found at expected address, skipping deployment");
console.log("Code found at expected address, skipping deployment");
}
}

function _deployAccountFactory(bytes32 salt, address expected) internal {
console2.log(string.concat("Deploying AccountFactory with salt: ", vm.toString(salt)));
console.log(string.concat("Deploying AccountFactory with salt: ", vm.toString(salt)));

address addr = Create2.computeAddress(
salt,
Expand All @@ -117,46 +116,46 @@ contract DeployScript is Script {
CREATE2_FACTORY
);
if (addr != expected) {
console2.log("Expected address mismatch");
console2.log("Expected: ", expected);
console2.log("Actual: ", addr);
console.log("Expected address mismatch");
console.log("Expected: ", expected);
console.log("Actual: ", addr);
revert();
}

if (addr.code.length == 0) {
console2.log("No code found at expected address, deploying...");
console.log("No code found at expected address, deploying...");
AccountFactory deployed = new AccountFactory{salt: salt}(
entryPoint, UpgradeableModularAccount(payable(accountImpl)), singleSignerValidation, owner
);

if (address(deployed) != expected) {
console2.log("Deployed address mismatch");
console2.log("Expected: ", expected);
console2.log("Deployed: ", address(deployed));
console.log("Deployed address mismatch");
console.log("Expected: ", expected);
console.log("Deployed: ", address(deployed));
revert();
}

console2.log("Deployed AccountFactory at: ", address(deployed));
console.log("Deployed AccountFactory at: ", address(deployed));
} else {
console2.log("Code found at expected address, skipping deployment");
console.log("Code found at expected address, skipping deployment");
}
}

function _addStakeForFactory(uint32 unstakeDelay, uint256 stakeAmount) internal {
console2.log("Adding stake to factory");
console.log("Adding stake to factory");

uint256 currentStake = entryPoint.getDepositInfo(address(factory)).stake;
console2.log("Current stake: ", currentStake);
console.log("Current stake: ", currentStake);
uint256 stakeToAdd = stakeAmount - currentStake;

if (stakeToAdd > 0) {
console2.log("Adding stake: ", stakeToAdd);
entryPoint.addStake{value: stakeToAdd}(unstakeDelay);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

: |

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha this comment made me realize a mistake - we should use the value stakeToAdd, not stakeAmount

console2.log("Staked factory: ", address(factory));
console2.log("Total stake amount: ", entryPoint.getDepositInfo(address(factory)).stake);
console2.log("Unstake delay: ", entryPoint.getDepositInfo(address(factory)).unstakeDelaySec);
console.log("Adding stake: ", stakeToAdd);
AccountFactory(factory).addStake{value: stakeToAdd}(unstakeDelay);
console.log("Staked factory: ", address(factory));
console.log("Total stake amount: ", entryPoint.getDepositInfo(address(factory)).stake);
console.log("Unstake delay: ", entryPoint.getDepositInfo(address(factory)).unstakeDelaySec);
} else {
console2.log("No stake to add");
console.log("No stake to add");
}
}
}
51 changes: 51 additions & 0 deletions script/DeployAllowlistModule.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.25;

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

import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";

import {AllowlistModule} from "../src/modules/permissionhooks/AllowlistModule.sol";

contract DeployAllowlistModuleScript is Script {
address public allowlistModule = vm.envOr("ALLOWLIST_MODULE", address(0));

bytes32 public allowlistModuleSalt = bytes32(vm.envOr("ALLOWLIST_MODULE_SALT", uint256(0)));

function run() public {
console.log("******** Deploying AllowlistModule ********");
console.log("Chain: ", block.chainid);

vm.startBroadcast();
_deployAllowlistModule(allowlistModuleSalt, allowlistModule);
vm.stopBroadcast();
}

function _deployAllowlistModule(bytes32 salt, address expected) internal {
console.log(string.concat("Deploying AllowlistModule with salt: ", vm.toString(salt)));

address addr = Create2.computeAddress(salt, keccak256(type(AllowlistModule).creationCode), CREATE2_FACTORY);
if (addr != expected) {
console.log("Expected address mismatch");
console.log("Expected: ", expected);
console.log("Actual: ", addr);
revert();
}

if (addr.code.length == 0) {
console.log("No code found at expected address, deploying...");
AllowlistModule deployed = new AllowlistModule{salt: salt}();

if (address(deployed) != expected) {
console.log("Deployed address mismatch");
console.log("Expected: ", expected);
console.log("Actual: ", address(deployed));
revert();
}

console.log("Deployed AllowlistModule at: ", address(deployed));
} else {
console.log("Code found at expected address, skipping deployment");
}
}
}
5 changes: 2 additions & 3 deletions src/account/AccountFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {ValidationConfigLib} from "../helpers/ValidationConfigLib.sol";
contract AccountFactory is Ownable {
UpgradeableModularAccount public immutable ACCOUNT_IMPL;
bytes32 private immutable _PROXY_BYTECODE_HASH;
uint32 public constant UNSTAKE_DELAY = 1 weeks;
IEntryPoint public immutable ENTRY_POINT;
address public immutable SINGLE_SIGNER_VALIDATION;

Expand Down Expand Up @@ -61,8 +60,8 @@ contract AccountFactory is Ownable {
return UpgradeableModularAccount(payable(addr));
}

function addStake() external payable onlyOwner {
ENTRY_POINT.addStake{value: msg.value}(UNSTAKE_DELAY);
function addStake(uint32 unstakeDelay) external payable onlyOwner {
ENTRY_POINT.addStake{value: msg.value}(unstakeDelay);
}

function unlockStake() external onlyOwner {
Expand Down
Loading
Loading