Skip to content

Commit

Permalink
fix: replace modules with hooks
Browse files Browse the repository at this point in the history
This is much more direct path to installing instead of using the install
to re-enter the account
  • Loading branch information
cpb8010 committed Dec 4, 2024
1 parent 12f007b commit e6024ab
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 100 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"eslint-plugin-simple-import-sort": "12.1.1",
"ethers": "6.13.2",
"globals": "15.9.0",
"hardhat": "^2.22.12",
"hardhat": "^2.22.17",
"husky": "9.1.6",
"ini": "5.0.0",
"lint-staged": "15.2.10",
Expand All @@ -73,14 +73,14 @@
"nx": "19.8.6",
"prettier": "3.3.3",
"prettier-plugin-solidity": "^1.4.1",
"solady": "^0.0.273",
"ts-node": "10.9.2",
"typechain": "8.3.2",
"typescript": "5.6.2",
"typescript-eslint": "8.7.0",
"viem": "^2.21.14",
"zksync-ethers": "6.15.0",
"zksync-sso": "0.0.0-beta.2",
"solady": "^0.0.273"
"zksync-sso": "0.0.0-beta.2"
},
"packageManager": "[email protected]"
}
162 changes: 81 additions & 81 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/AAFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ contract AAFactory is UpgradeableBeacon {
bytes32 _salt,
string calldata _uniqueAccountId,
bytes[] calldata _initialValidators,
bytes[] calldata _initialHooks,
address[] calldata _initialK1Owners
) external returns (address accountAddress) {
require(accountMappings[_uniqueAccountId] == address(0), "Account already exists");
Expand All @@ -62,8 +63,8 @@ contract AAFactory is UpgradeableBeacon {
require(success, "Deployment failed");
(accountAddress) = abi.decode(returnData, (address));

// Initialize the newly deployed account with validators and K1 owners.
ISsoAccount(accountAddress).initialize(_initialValidators, _initialK1Owners);
// Initialize the newly deployed account with validators, hooks and K1 owners.
ISsoAccount(accountAddress).initialize(_initialValidators, _initialHooks, _initialK1Owners);

accountMappings[_uniqueAccountId] = accountAddress;

Expand Down
12 changes: 11 additions & 1 deletion src/SsoAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,22 @@ contract SsoAccount is Initializable, HookManager, ERC1271Handler, TokenCallback
/// @dev Sets passkey and passkey validator within account storage
/// @param _initialValidators An array of module validator addresses and initial validation keys
/// in an ABI encoded format of `abi.encode(validatorAddr,validationKey))`.
/// @param _initialValidationHooks An array of hook module validator addresses and initial validation keys
/// in an ABI encoded format of `abi.encode(validatorAddr,validationKey))`.
/// @param _initialK1Owners An array of addresses with full control over the account.
function initialize(bytes[] calldata _initialValidators, address[] calldata _initialK1Owners) external initializer {
function initialize(
bytes[] calldata _initialValidators,
bytes[] calldata _initialValidationHooks,
address[] calldata _initialK1Owners
) external initializer {
for (uint256 i = 0; i < _initialValidators.length; ++i) {
(address validatorAddr, bytes memory validationKey) = abi.decode(_initialValidators[i], (address, bytes));
_addModuleValidator(validatorAddr, validationKey);
}
for (uint256 i = 0; i < _initialValidationHooks.length; ++i) {
(address validatorAddr, bytes memory validationKey) = abi.decode(_initialValidationHooks[i], (address, bytes));
_installHook(validatorAddr, validationKey, true);
}
for (uint256 i = 0; i < _initialK1Owners.length; ++i) {
_k1AddOwner(_initialK1Owners[i]);
}
Expand Down
6 changes: 5 additions & 1 deletion src/interfaces/ISsoAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,9 @@ interface ISsoAccount is
{
event FeePaid();

function initialize(bytes[] calldata initialValidators, address[] calldata k1Owners) external;
function initialize(
bytes[] calldata initialValidators,
bytes[] calldata initialHooks,
address[] calldata k1Owners
) external;
}
8 changes: 5 additions & 3 deletions src/managers/HookManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,14 @@ abstract contract HookManager is IHookManager, Auth {

address hookAddress = address(bytes20(hookAndData[0:20]));

bytes calldata initData = hookAndData[20:];
_installHook(hookAddress, initData, isValidation);
}

function _installHook(address hookAddress, bytes memory initData, bool isValidation) internal {
if (!_supportsHook(hookAddress, isValidation)) {
revert Errors.HOOK_ERC165_FAIL();
}

bytes calldata initData = hookAndData[20:];

if (isValidation) {
_validationHooksLinkedList().add(hookAddress);
} else {
Expand Down
7 changes: 1 addition & 6 deletions src/validators/SessionKeyValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,7 @@ contract SessionKeyValidator is IValidationHook, IModuleValidator {
emit SessionCreated(msg.sender, sessionHash, sessionSpec);
}

function init(bytes calldata data) external {
// to prevent recursion, since addHook also calls init
if (!_isInitialized(msg.sender)) {
IHookManager(msg.sender).addHook(abi.encodePacked(address(this)), true);
}
}
function init(bytes calldata data) external {}

function disable() external {
if (_isInitialized(msg.sender)) {
Expand Down
1 change: 1 addition & 0 deletions test/BasicTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe("Basic tests", function () {
randomBytes(32),
"id",
[],
[],
[fixtures.wallet.address],
);
const deployTxReceipt = await deployTx.wait();
Expand Down
11 changes: 8 additions & 3 deletions test/SessionKeyTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ class SessionTester {
};

const signedTransaction = await this.sessionAccount.signTransaction(this.aaTransaction);
await expect(provider.broadcastTransaction(signedTransaction)).to.be.reverted;
const txResponse = await provider.broadcastTransaction(signedTransaction);

// Because this rejects the transaction during validation, we don't get a receipt
expect (txResponse.blockNumber).to.be.null;
expect (await txResponse.confirmations()).to.be.equal(0)
};

getLimit(limit?: PartialLimit): SessionLib.UsageLimitStruct {
Expand Down Expand Up @@ -349,7 +353,7 @@ class SessionTester {
}
}

describe("SessionKeyModule tests", function () {
describe.only("SessionKeyModule tests", function () {
let proxyAccountAddress: string;

(hre.network.name == "dockerizedNode" ? it : it.skip)("should deposit funds", async () => {
Expand Down Expand Up @@ -388,7 +392,8 @@ describe("SessionKeyModule tests", function () {

const deployTx = await factoryContract.deployProxySsoAccount(
randomBytes(32),
"id",
"session-key-test-id",
[sessionKeyPayload],
[sessionKeyPayload],
[fixtures.wallet.address],
);
Expand Down

0 comments on commit e6024ab

Please sign in to comment.