diff --git a/contracts/AccountFactory.sol b/contracts/AccountFactory.sol index 86cbf10..7ec4aa0 100644 --- a/contracts/AccountFactory.sol +++ b/contracts/AccountFactory.sol @@ -118,6 +118,9 @@ contract AccountFactory is Ownable2Step { bytes32 salt, bytes calldata initializer ) external payable returns (address accountAddress) { + if (saltToAccount[salt] != address(0)) { + revert Errors.ALREADY_CREATED(); + } // Check that the initializer is not empty if (initializer.length < 4) { revert Errors.INVALID_INITIALIZER(); diff --git a/contracts/libraries/Errors.sol b/contracts/libraries/Errors.sol index 036e442..d96bfc5 100644 --- a/contracts/libraries/Errors.sol +++ b/contracts/libraries/Errors.sol @@ -100,8 +100,9 @@ library Errors { error DEPLOYMENT_FAILED(); // 0x0f02d218 error INITIALIZATION_FAILED(); // 0x5b101091 - error INVALID_INITIALIZER(); - error INVALID_SALT(); + error INVALID_INITIALIZER(); // 0x350366d7 + error INVALID_SALT(); // 0x8b3152e6 + error ALREADY_CREATED(); // 0x26ebf2e8 /*////////////////////////////////////////////////////////////// PAYMASTER diff --git a/test/deployments/deployer.test.ts b/test/deployments/deployer.test.ts index bbd7e5e..e75f61e 100644 --- a/test/deployments/deployer.test.ts +++ b/test/deployments/deployer.test.ts @@ -6,7 +6,7 @@ import { expect } from 'chai'; import type { ec } from 'elliptic'; import type { BytesLike, HDNodeWallet } from 'ethers'; -import { getAddress, hexlify, parseEther, randomBytes } from 'ethers'; +import { getAddress, hexlify, keccak256, parseEther, randomBytes } from 'ethers'; import * as hre from 'hardhat'; import type { Contract, Wallet } from 'zksync-ethers'; import { Provider } from 'zksync-ethers'; @@ -109,12 +109,22 @@ describe('AGW Contracts - Deployer class tests', () => { }); it('should not deploy an account with an empty initializer', async () => { - await expect(deployer.account(wallet, factory, eoaValidator, { initializer: '0x' })) + const pk = randomBytes(32); + const wallet = getWallet(hre, hexlify(pk)); + await expect(deployer.account(wallet, factory, eoaValidator, { + salt: keccak256(wallet.address), + initializer: '0x' + })) .to.be.revertedWithCustomError(factory, "INVALID_INITIALIZER"); }); it('should not deploy an account with an invalid initializer selector', async () => { - await expect(deployer.account(wallet, factory, eoaValidator, { initializer: '0xabababab' })) + const pk = randomBytes(32); + const wallet = getWallet(hre, hexlify(pk)); + await expect(deployer.account(wallet, factory, eoaValidator, { + salt: keccak256(wallet.address), + initializer: '0xabababab' + })) .to.be.revertedWithCustomError(factory, "INVALID_INITIALIZER"); });