diff --git a/.dockerignore b/.dockerignore index 5961d58c..be7545b7 100644 --- a/.dockerignore +++ b/.dockerignore @@ -22,10 +22,7 @@ packages/contracts/cache packages/contracts/out packages/contracts/cache packages/contracts/artifacts -packages/contracts/test/build_integration/*.json -packages/contracts/test/build_integration/*.zkey -packages/contracts/test/build_integration/*.wasm -packages/contracts/test/build_integration/*.txt +packages/contracts/test # NFT Relayer packages/nft_relayer/sendgrid.env diff --git a/libs/rapidsnark.Dockerfile b/libs/rapidsnark.Dockerfile deleted file mode 100644 index 1a8cf1f7..00000000 --- a/libs/rapidsnark.Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM ubuntu:22.04 - -ARG DEBIAN_FRONTEND=noninteractive - -# Install Node.js, Yarn and required dependencies -RUN apt-get update \ - && apt-get install -y curl git gnupg build-essential cmake libgmp-dev libsodium-dev nasm curl m4 \ - && curl --silent --location https://deb.nodesource.com/setup_12.x | bash - \ - && apt-get install -y nodejs - -RUN git clone https://github.com/Orbiter-Finance/rapidsnark.git /rapidsnark -WORKDIR /rapidsnark -RUN git submodule init -RUN git submodule update -./build_gmp.sh host -mkdir build_prover && cd build_prover -cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package -make -j$(nproc) && make install - -ENTRYPOINT ["/rapidsnark/package/build/prover_cuda"] diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_completeRecovery.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_completeRecovery.t.sol new file mode 100644 index 00000000..435a403b --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_completeRecovery.t.sol @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; +import {RecoveryControllerZKSync} from "../helpers/RecoveryControllerZKSync.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; +import {SimpleWallet} from "../helpers/SimpleWallet.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { + constructor() {} + + function setUp() public override { + super.setUp(); + } + + function requestGuardian() public { + setUp(); + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.NONE + ); + + vm.startPrank(deployer); + recoveryControllerZKSync.requestGuardian(guardian); + vm.stopPrank(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + } + + function handleAcceptance() public { + requestGuardian(); + + console.log("guardian", guardian); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + // acceptGuardian is internal, we call handleAcceptance, which calls acceptGuardian internally. + vm.startPrank(someRelayer); + recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.ACCEPTED + ); + } + + function handleRecovery() public { + handleAcceptance(); + + assertEq( + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + false + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + + assertEq( + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + true + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + newSigner + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), + block.timestamp + + recoveryControllerZKSync.timelockPeriodOfAccount( + address(simpleWallet) + ) + ); + } + + function testCompleteRecovery() public { + skipIfNotZkSync(); + + handleRecovery(); + + assertEq( + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + true + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), + block.timestamp + + recoveryControllerZKSync.timelockPeriodOfAccount( + address(simpleWallet) + ) + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + newSigner + ); + + vm.startPrank(someRelayer); + vm.warp(4 days); + recoveryControllerZKSync.completeRecovery( + address(simpleWallet), + new bytes(0) + ); + vm.stopPrank(); + + assertEq( + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + false + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), + 0 + ); + assertEq(simpleWallet.owner(), newSigner); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + } + + function testExpectRevertCompleteRecoveryRecoveryNotInProgress() public { + skipIfNotZkSync(); + + handleAcceptance(); + + assertEq( + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + false + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + + vm.startPrank(someRelayer); + vm.warp(4 days); + vm.expectRevert(bytes("recovery not in progress")); + bytes memory recoveryCalldata; + recoveryControllerZKSync.completeRecovery( + address(simpleWallet), + recoveryCalldata + ); + + vm.stopPrank(); + } + + function testExpectRevertCompleteRecovery() public { + vm.warp(block.timestamp + 3 days); + + handleRecovery(); + + assertEq( + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + true + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), + block.timestamp + + recoveryControllerZKSync.timelockPeriodOfAccount( + address(simpleWallet) + ) + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + newSigner + ); + + vm.warp(0); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("timelock not expired")); + bytes memory recoveryCalldata; + recoveryControllerZKSync.completeRecovery( + address(simpleWallet), + recoveryCalldata + ); + + vm.stopPrank(); + } +} diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleAcceptance.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleAcceptance.t.sol new file mode 100644 index 00000000..fa88af64 --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleAcceptance.t.sol @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; +import {RecoveryControllerZKSync} from "../helpers/RecoveryControllerZKSync.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; +import {SimpleWallet} from "../helpers/SimpleWallet.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract EmailAccountRecoveryZKSyncTest_handleAcceptance is StructHelper { + constructor() {} + + function setUp() public override { + super.setUp(); + } + + function requestGuardian() public { + skipIfNotZkSync(); + + setUp(); + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.NONE + ); + + vm.startPrank(deployer); + recoveryControllerZKSync.requestGuardian(guardian); + vm.stopPrank(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + } + + function testHandleAcceptance() public { + skipIfNotZkSync(); + + requestGuardian(); + + console.log("guardian", guardian); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + // acceptGuardian is internal, we call handleAcceptance, which calls acceptGuardian internally. + vm.startPrank(someRelayer); + recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.ACCEPTED + ); + } + + // Can not test recovery in progress using handleAcceptance + // Can not test invalid guardian using handleAcceptance + + function testExpectRevertHandleAcceptanceGuardianStatusMustBeRequested() + public + { + skipIfNotZkSync(); + + requestGuardian(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + emailAuthMsg.proof.accountSalt = 0x0; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("guardian status must be REQUESTED")); + recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleAcceptanceInvalidTemplateIndex() public { + skipIfNotZkSync(); + + requestGuardian(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + + uint templateIdx = 1; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid template index")); + recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleAcceptanceInvalidcommandParams() public { + skipIfNotZkSync(); + + requestGuardian(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](2); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + commandParamsForAcceptance[1] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid command params")); + recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleAcceptanceInvalidWalletAddressInEmail() + public + { + skipIfNotZkSync(); + + requestGuardian(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(0x0)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid account in email")); + recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + } +} diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleRecovery.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleRecovery.t.sol new file mode 100644 index 00000000..288b234f --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleRecovery.t.sol @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; +import {RecoveryControllerZKSync} from "../helpers/RecoveryControllerZKSync.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; +import {SimpleWallet} from "../helpers/SimpleWallet.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { + constructor() {} + + function setUp() public override { + super.setUp(); + } + + function requestGuardian() public { + setUp(); + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.NONE + ); + + vm.startPrank(deployer); + recoveryControllerZKSync.requestGuardian(guardian); + vm.stopPrank(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + } + + function handleAcceptance() public { + skipIfNotZkSync(); + + requestGuardian(); + + console.log("guardian", guardian); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + // acceptGuardian is internal, we call handleAcceptance, which calls acceptGuardian internally. + vm.startPrank(someRelayer); + recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.ACCEPTED + ); + } + + function testHandleRecovery() public { + skipIfNotZkSync(); + + handleAcceptance(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), true); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + newSigner + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + block.timestamp + + recoveryControllerZKSync.timelockPeriodOfAccount( + address(simpleWallet) + ) + ); + } + + function testExpectRevertHandleRecoveryGuardianIsNotDeployed() public { + skipIfNotZkSync(); + + handleAcceptance(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + emailAuthMsg.proof.accountSalt = 0x0; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("guardian is not deployed")); + recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleRecoveryInvalidTemplateId() public { + skipIfNotZkSync(); + + handleAcceptance(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid template id")); + recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + // Can not test recovery in progress using handleRecovery + // Can not test invalid guardian using handleRecovery + + function testExpectRevertHandleRecoveryGuardianStatusMustBeAccepted() + public + { + skipIfNotZkSync(); + + handleAcceptance(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + emailAuthMsg.proof.accountSalt = 0x0; + + // vm.mockCall( + // address(simpleWallet.emailAuthImplementationAddr()), + // abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + // abi.encode(0x0) + // ); + + // // Deploy mock guardian, that status is NONE + // address mockCallAddress; + // if(block.chainid == 300) { + // mockCallAddress = address(0x889170C6bEe9053626f8460A9875d22Cf6DE0782); + // } else { + // mockCallAddress = address(0x2Cfb66029975B1c8881adaa3b79c5Caa4FEB84B5); + // } + // vm.mockCall( + // mockCallAddress, + // abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + // abi.encode(0x0) + // ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("guardian is not deployed")); + recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleRecoveryInvalidTemplateIndex() public { + skipIfNotZkSync(); + + handleAcceptance(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + uint templateIdx = 1; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid template index")); + recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleRecoveryInvalidcommandParams() public { + skipIfNotZkSync(); + + handleAcceptance(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForRecovery = new bytes[](3); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + commandParamsForRecovery[1] = abi.encode(address(0x0)); + emailAuthMsg.commandParams = commandParamsForRecovery; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid command params")); + recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + // function testExpectRevertHandleRecoveryInvalidGuardianInEmail() public { + // handleAcceptance(); + + // assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + // assertEq( + // recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + // 0 + // ); + // assertEq(simpleWallet.owner(), deployer); + // assertEq( + // recoveryControllerZKSync.newSignerCandidateOfAccount(address(simpleWallet)), + // address(0x0) + // ); + // uint templateIdx = 0; + + // EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + // uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId(templateIdx); + // emailAuthMsg.templateId = templateId; + // bytes[] memory commandParamsForRecovery = new bytes[](2); + // commandParamsForRecovery[0] = abi.encode(address(0x0)); + // commandParamsForRecovery[1] = abi.encode(newSigner); + // emailAuthMsg.commandParams = commandParamsForRecovery; + + // vm.mockCall( + // address(recoveryControllerZKSync.emailAuthImplementationAddr()), + // abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + // abi.encode(0x0) + // ); + + // vm.startPrank(someRelayer); + // vm.expectRevert(bytes("invalid guardian in email")); + // recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + // vm.stopPrank(); + // } + + function testExpectRevertHandleRecoveryInvalidNewSigner() public { + skipIfNotZkSync(); + + handleAcceptance(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(address(0x0)); + emailAuthMsg.commandParams = commandParamsForRecovery; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid new signer")); + recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } +} diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_rejectRecovery.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_rejectRecovery.t.sol new file mode 100644 index 00000000..e17c900e --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_rejectRecovery.t.sol @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; +import {RecoveryControllerZKSync} from "../helpers/RecoveryControllerZKSync.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; +import {SimpleWallet} from "../helpers/SimpleWallet.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract EmailAccountRecoveryZKSyncTest_rejectRecovery is StructHelper { + constructor() {} + + function setUp() public override { + super.setUp(); + } + + /** + * Set up functions + */ + function requestGuardian() public { + setUp(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.NONE + ); + + vm.startPrank(deployer); + recoveryControllerZKSync.requestGuardian(guardian); + vm.stopPrank(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + } + + function handleAcceptance() public { + requestGuardian(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + + console.log("guardian", guardian); + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + address recoveredAccount = recoveryControllerZKSync + .extractRecoveredAccountFromAcceptanceCommand( + emailAuthMsg.commandParams, + templateIdx + ); + address computedGuardian = recoveryControllerZKSync.computeEmailAuthAddress( + recoveredAccount, + emailAuthMsg.proof.accountSalt + ); + console.log("computed guardian", computedGuardian); + uint templateId = recoveryControllerZKSync.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + // acceptGuardian is internal, we call handleAcceptance, which calls acceptGuardian internally. + vm.startPrank(someRelayer); + recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.ACCEPTED + ); + } + + function handleRecovery() public { + handleAcceptance(); + + assertEq(simpleWallet.owner(), deployer); + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + + vm.mockCall( + address(recoveryControllerZKSync.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), true); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + newSigner + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + block.timestamp + + recoveryControllerZKSync.timelockPeriodOfAccount( + address(simpleWallet) + ) + ); + } + + function testRejectRecovery() public { + skipIfNotZkSync(); + + vm.warp(block.timestamp + 3 days); + + handleRecovery(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), true); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + block.timestamp + + recoveryControllerZKSync.timelockPeriodOfAccount( + address(simpleWallet) + ) + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + newSigner + ); + + vm.warp(0); + + vm.startPrank(address(simpleWallet)); + recoveryControllerZKSync.rejectRecovery(); + vm.stopPrank(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + } + + function testExpectRevertRejectRecoveryRecoveryNotInProgress() public { + skipIfNotZkSync(); + + handleAcceptance(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + 0 + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + address(0x0) + ); + + vm.startPrank(deployer); + vm.expectRevert(bytes("recovery not in progress")); + recoveryControllerZKSync.rejectRecovery(); + vm.stopPrank(); + } + + function testExpectRevertRejectRecovery() public { + skipIfNotZkSync(); + + vm.warp(block.timestamp + 1 days); + + handleRecovery(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), true); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + block.timestamp + + recoveryControllerZKSync.timelockPeriodOfAccount( + address(simpleWallet) + ) + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + newSigner + ); + + vm.startPrank(address(simpleWallet)); + vm.warp(block.timestamp + 4 days); + vm.expectRevert(bytes("timelock expired")); + recoveryControllerZKSync.rejectRecovery(); + vm.stopPrank(); + } + + function testExpectRevertRejectRecoveryOwnableUnauthorizedAccount() public { + skipIfNotZkSync(); + + handleRecovery(); + + assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), true); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + block.timestamp + + recoveryControllerZKSync.timelockPeriodOfAccount( + address(simpleWallet) + ) + ); + assertEq(simpleWallet.owner(), deployer); + assertEq( + recoveryControllerZKSync.newSignerCandidateOfAccount( + address(simpleWallet) + ), + newSigner + ); + + vm.startPrank(deployer); + vm.expectRevert("recovery not in progress"); + recoveryControllerZKSync.rejectRecovery(); + vm.stopPrank(); + } +} diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_requestGuardian.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_requestGuardian.t.sol new file mode 100644 index 00000000..03418653 --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_requestGuardian.t.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; +import {RecoveryControllerZKSync} from "../helpers/RecoveryControllerZKSync.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; +import {SimpleWallet} from "../helpers/SimpleWallet.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract EmailAccountRecoveryZKSyncTest_requestGuardian is StructHelper { + constructor() {} + + function setUp() public override { + super.setUp(); + } + + function testRequestGuardian() public { + skipIfNotZkSync(); + + setUp(); + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.NONE + ); + + vm.startPrank(deployer); + recoveryControllerZKSync.requestGuardian(guardian); + vm.stopPrank(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.REQUESTED + ); + } + + // function testRequestGuardianNotOwner() public { + // setUp(); + + // require( + // recoveryControllerZKSync.guardians(guardian) == + // recoveryControllerZKSync.GuardianStatus.NONE + // ); + + // vm.startPrank(receiver); + // recoveryControllerZKSync.requestGuardian(guardian); + // vm.stopPrank(); + + // require( + // recoveryControllerZKSync.guardians(guardian) == + // recoveryControllerZKSync.GuardianStatus.NONE + // ); + // } + + function testExpectRevertRequestGuardianInvalidGuardian() public { + skipIfNotZkSync(); + + setUp(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.NONE + ); + + vm.startPrank(deployer); + vm.expectRevert(bytes("invalid guardian")); + recoveryControllerZKSync.requestGuardian(address(0x0)); + vm.stopPrank(); + } + + function testExpectRevertRequestGuardianGuardianStatusMustBeNone() public { + skipIfNotZkSync(); + + setUp(); + + require( + recoveryControllerZKSync.guardians(guardian) == + RecoveryControllerZKSync.GuardianStatus.NONE + ); + + vm.startPrank(deployer); + recoveryControllerZKSync.requestGuardian(guardian); + vm.expectRevert(bytes("guardian status must be NONE")); + recoveryControllerZKSync.requestGuardian(guardian); + vm.stopPrank(); + } +} diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_transfer.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_transfer.t.sol new file mode 100644 index 00000000..b784847d --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_transfer.t.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; +import {RecoveryControllerZKSync} from "../helpers/RecoveryControllerZKSync.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; +import {SimpleWallet} from "../helpers/SimpleWallet.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract EmailAccountRecoveryZKSyncTest_transfer is StructHelper { + constructor() {} + + function setUp() public override { + super.setUp(); + } + + function testTransfer() public { + skipIfNotZkSync(); + + setUp(); + + assertEq(address(simpleWallet).balance, 1 ether); + assertEq(receiver.balance, 0 ether); + + vm.startPrank(deployer); + simpleWallet.transfer(receiver, 1 ether); + vm.stopPrank(); + + assertEq(address(simpleWallet).balance, 0 ether); + assertEq(receiver.balance, 1 ether); + } + + function testExpectRevertTransferOnlyOwner() public { + skipIfNotZkSync(); + + setUp(); + + assertEq(address(simpleWallet).balance, 1 ether); + assertEq(receiver.balance, 0 ether); + + vm.startPrank(receiver); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, + receiver + ) + ); + simpleWallet.transfer(receiver, 1 ether); + vm.stopPrank(); + } + + function testExpectRevertTransferOnlyOwnerInsufficientBalance() public { + skipIfNotZkSync(); + + setUp(); + + assertEq(address(simpleWallet).balance, 1 ether); + assertEq(receiver.balance, 0 ether); + + vm.startPrank(deployer); + assertEq(receiver.balance, 0 ether); + vm.expectRevert(bytes("insufficient balance")); + simpleWallet.transfer(receiver, 2 ether); + vm.stopPrank(); + } +} diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_withdraw.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_withdraw.t.sol new file mode 100644 index 00000000..07d347d6 --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_withdraw.t.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; +import {RecoveryControllerZKSync} from "../helpers/RecoveryControllerZKSync.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; +import {SimpleWallet} from "../helpers/SimpleWallet.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract EmailAccountRecoveryZKSyncTest_withdraw is StructHelper { + constructor() {} + + function setUp() public override { + super.setUp(); + } + + function testWithdraw() public { + skipIfNotZkSync(); + + setUp(); + + assertEq(address(simpleWallet).balance, 1 ether); + assertEq(deployer.balance, 0 ether); + + vm.startPrank(deployer); + simpleWallet.withdraw(1 ether); + vm.stopPrank(); + + assertEq(address(simpleWallet).balance, 0 ether); + assertEq(deployer.balance, 1 ether); + } + + function testExpectRevertWithdrawOnlyOwner() public { + skipIfNotZkSync(); + + setUp(); + + assertEq(address(simpleWallet).balance, 1 ether); + assertEq(deployer.balance, 0 ether); + + vm.startPrank(receiver); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, + address(receiver) + ) + ); + simpleWallet.withdraw(1 ether); + vm.stopPrank(); + } + + function testExpectRevertWithdrawInsufficientBalance() public { + skipIfNotZkSync(); + + setUp(); + + assertEq(address(simpleWallet).balance, 1 ether); + assertEq(deployer.balance, 0 ether); + + vm.startPrank(deployer); + vm.expectRevert(bytes("insufficient balance")); + simpleWallet.withdraw(10 ether); + vm.stopPrank(); + } +} diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_acceptanceCommandTemplates.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_acceptanceCommandTemplates.t.sol new file mode 100644 index 00000000..81d9a67c --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_acceptanceCommandTemplates.t.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; +import {RecoveryControllerZKSync} from "../helpers/RecoveryControllerZKSync.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; +import {SimpleWallet} from "../helpers/SimpleWallet.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract EmailAccountRecoveryZKSyncTest_acceptanceCommandTemplates is + StructHelper +{ + constructor() {} + + function setUp() public override { + super.setUp(); + } + + function testAcceptanceCommandTemplates() public { + skipIfNotZkSync(); + + setUp(); + string[][] memory res = recoveryController.acceptanceCommandTemplates(); + assertEq(res[0][0], "Accept"); + assertEq(res[0][1], "guardian"); + assertEq(res[0][2], "request"); + assertEq(res[0][3], "for"); + assertEq(res[0][4], "{ethAddr}"); + } +} diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_recoveryCommandTemplates.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_recoveryCommandTemplates.t.sol new file mode 100644 index 00000000..62271e43 --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_recoveryCommandTemplates.t.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; +import {RecoveryController} from "../helpers/RecoveryController.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; +import {SimpleWallet} from "../helpers/SimpleWallet.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +contract EmailAccountRecoveryZKSyncTest_recoveryCommandTemplates is + StructHelper +{ + constructor() {} + + function setUp() public override { + super.setUp(); + } + + function testRecoveryCommandTemplates() public { + skipIfNotZkSync(); + + setUp(); + string[][] memory res = recoveryController.recoveryCommandTemplates(); + assertEq(res[0][0], "Set"); + assertEq(res[0][1], "the"); + assertEq(res[0][2], "new"); + assertEq(res[0][3], "signer"); + assertEq(res[0][4], "of"); + assertEq(res[0][5], "{ethAddr}"); + assertEq(res[0][6], "to"); + assertEq(res[0][7], "{ethAddr}"); + } +} diff --git a/packages/prover/Dockerfile b/packages/prover/Dockerfile index 2007b8b8..97296dd7 100644 --- a/packages/prover/Dockerfile +++ b/packages/prover/Dockerfile @@ -36,7 +36,7 @@ RUN npm install -g n RUN n 22 RUN npm install -g yarn snarkjs -RUN git clone -b refactor https://github.com/zkemail/ether-email-auth.git +RUN git clone https://github.com/zkemail/ether-email-auth.git WORKDIR /ether-email-auth/packages/prover RUN pip install -r requirements.txt RUN cp ./circom_proofgen.sh /root