-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
183 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.26; | ||
|
||
import {IEntryPoint} from "@eth-infinitism/account-abstraction/interfaces/IEntryPoint.sol"; | ||
import {IStakeManager} from "@eth-infinitism/account-abstraction/interfaces/IStakeManager.sol"; | ||
import {console} from "forge-std/console.sol"; | ||
|
||
import {AccountFactory} from "../src/factory/AccountFactory.sol"; | ||
|
||
import {ScriptBase} from "./ScriptBase.sol"; | ||
|
||
contract StakeFactoryScript is ScriptBase { | ||
AccountFactory internal _accountFactory; | ||
|
||
IEntryPoint internal _entryPoint; | ||
|
||
function setUp() public { | ||
_entryPoint = _getEntryPoint(); | ||
|
||
// Has to use a different env var name to avoid conflicts with the one in DeployFactoryScript, because | ||
// vm.setEnv in tests doesn't isolate and it would result in a race condition. | ||
_accountFactory = AccountFactory(vm.envOr("ACCOUNT_FACTORY_TO_STAKE", address(0))); | ||
} | ||
|
||
function run() public { | ||
console.log("******** Staking Account Factory *********"); | ||
|
||
if (address(_accountFactory) == address(0)) { | ||
console.log("Account Factory not found or invalid"); | ||
revert(); | ||
} | ||
|
||
console.log("Using AccountFactory at address: ", address(_accountFactory)); | ||
|
||
(uint256 stakeAmountWei, uint256 unstakeDelay) = _getStakeParams(); | ||
|
||
uint256 stakeNeeded = _checkCurrentStake(stakeAmountWei); | ||
|
||
vm.startBroadcast(); | ||
|
||
_accountFactory.addStake{value: stakeNeeded}(uint32(unstakeDelay)); | ||
|
||
vm.stopBroadcast(); | ||
|
||
console.log("******** Done Staking Account Factory *********"); | ||
} | ||
|
||
function _getStakeParams() internal view returns (uint256 stakeAmountWei, uint256 unstakeDelaySec) { | ||
stakeAmountWei = vm.envOr("REQUIRED_STAKE_AMOUNT_WEI", uint256(0)); | ||
|
||
if (stakeAmountWei == 0) { | ||
console.log("Env Variable 'REQUIRED_STAKE_AMOUNT_WEI' not found or invalid."); | ||
revert(); | ||
} | ||
|
||
console.log("Using user-defined stake amount: ", stakeAmountWei); | ||
|
||
unstakeDelaySec = vm.envOr("UNSTAKE_DELAY_SEC", uint256(0)); | ||
|
||
if (unstakeDelaySec == 0) { | ||
console.log("Env Variable 'UNSTAKE_DELAY_SEC' not found or invalid."); | ||
revert(); | ||
} | ||
|
||
console.log("Using user-defined unstake delay: ", unstakeDelaySec); | ||
} | ||
|
||
function _checkCurrentStake(uint256 requiredStakeAmountWei) internal view returns (uint256 stakeNeeded) { | ||
IStakeManager.DepositInfo memory factoryDepositInfo = _entryPoint.getDepositInfo(address(_accountFactory)); | ||
|
||
uint256 currentStake = factoryDepositInfo.stake; | ||
|
||
if (currentStake > requiredStakeAmountWei) { | ||
console.log("Factory already has enough stake: ", currentStake); | ||
stakeNeeded = 0; | ||
} else { | ||
stakeNeeded = requiredStakeAmountWei - currentStake; | ||
console.log("Adding stake to factory: ", stakeNeeded); | ||
} | ||
|
||
return stakeNeeded; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.26; | ||
|
||
import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.sol"; | ||
import {IEntryPoint} from "@eth-infinitism/account-abstraction/interfaces/IEntryPoint.sol"; | ||
|
||
import {StakeFactoryScript} from "../../script/StakeFactory.s.sol"; | ||
import {AccountFactory} from "../../src/factory/AccountFactory.sol"; | ||
import {ExecutionInstallDelegate} from "../../src/helpers/ExecutionInstallDelegate.sol"; | ||
import {WebAuthnValidationModule} from "../../src/modules/validation/WebAuthnValidationModule.sol"; | ||
|
||
import {OptimizedTest} from "../utils/OptimizedTest.sol"; | ||
|
||
contract StakeFactoryTest is OptimizedTest { | ||
StakeFactoryScript internal _stakeFactoryScript; | ||
|
||
EntryPoint internal _entryPoint; | ||
|
||
AccountFactory internal _accountFactory; | ||
|
||
uint256 internal constant _REQUIRED_STAKE_AMOUNT_WEI = 100_000_000_000_000_000; | ||
uint32 internal constant _UNSTAKE_DELAY_SEC = 86_400; | ||
|
||
function setUp() public { | ||
_stakeFactoryScript = new StakeFactoryScript(); | ||
|
||
_entryPoint = _deployEntryPoint070(); | ||
|
||
ExecutionInstallDelegate executionInstallDelegate = _deployExecutionInstallDelegate(); | ||
|
||
_accountFactory = new AccountFactory( | ||
_entryPoint, | ||
_deployModularAccount(_entryPoint, executionInstallDelegate), | ||
_deploySemiModularAccountBytecode(_entryPoint, executionInstallDelegate), | ||
address(_deploySingleSignerValidationModule()), | ||
address(new WebAuthnValidationModule()), | ||
DEFAULT_SENDER | ||
); | ||
|
||
vm.setEnv("REQUIRED_STAKE_AMOUNT_WEI", vm.toString(_REQUIRED_STAKE_AMOUNT_WEI)); | ||
vm.setEnv("UNSTAKE_DELAY_SEC", vm.toString(_UNSTAKE_DELAY_SEC)); | ||
vm.setEnv("ACCOUNT_FACTORY_TO_STAKE", vm.toString(address(_accountFactory))); | ||
} | ||
|
||
function test_stakeFactoryScript_fromZero() public { | ||
IEntryPoint.DepositInfo memory factoryDepositInfo = _entryPoint.getDepositInfo(address(_accountFactory)); | ||
|
||
assertFalse(factoryDepositInfo.staked, "Factory should not be staked"); | ||
assertEq(factoryDepositInfo.stake, 0, "Factory Stake should be 0"); | ||
assertEq(factoryDepositInfo.unstakeDelaySec, 0, "Factory Unstake Delay should be 0"); | ||
|
||
_stakeFactoryScript.setUp(); | ||
|
||
_stakeFactoryScript.run(); | ||
|
||
factoryDepositInfo = _entryPoint.getDepositInfo(address(_accountFactory)); | ||
|
||
assertTrue(factoryDepositInfo.staked, "Factory should be staked"); | ||
assertEq(factoryDepositInfo.stake, _REQUIRED_STAKE_AMOUNT_WEI, "Factory Stake should be 1000"); | ||
assertEq(factoryDepositInfo.unstakeDelaySec, _UNSTAKE_DELAY_SEC, "Factory Unstake Delay should be 86_400"); | ||
} | ||
|
||
function test_stakeFactoryScript_fromNonZero() public { | ||
vm.prank(DEFAULT_SENDER); | ||
_accountFactory.addStake{value: _REQUIRED_STAKE_AMOUNT_WEI / 2}(uint32(_UNSTAKE_DELAY_SEC / 2)); | ||
|
||
IEntryPoint.DepositInfo memory factoryDepositInfo = _entryPoint.getDepositInfo(address(_accountFactory)); | ||
|
||
assertTrue(factoryDepositInfo.staked, "Factory should be staked"); | ||
assertEq(factoryDepositInfo.stake, _REQUIRED_STAKE_AMOUNT_WEI / 2, "Factory Stake should be 500"); | ||
assertEq( | ||
factoryDepositInfo.unstakeDelaySec, _UNSTAKE_DELAY_SEC / 2, "Factory Unstake Delay should be 43_200" | ||
); | ||
|
||
_stakeFactoryScript.setUp(); | ||
|
||
_stakeFactoryScript.run(); | ||
|
||
factoryDepositInfo = _entryPoint.getDepositInfo(address(_accountFactory)); | ||
|
||
assertTrue(factoryDepositInfo.staked, "Factory should be staked"); | ||
assertEq(factoryDepositInfo.stake, _REQUIRED_STAKE_AMOUNT_WEI, "Factory Stake should be 1000"); | ||
assertEq(factoryDepositInfo.unstakeDelaySec, _UNSTAKE_DELAY_SEC, "Factory Unstake Delay should be 86_400"); | ||
} | ||
} |