From 0daa0d084a2239e4c828cee8b79a83d2018bf9d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Federico=20Mart=C3=ADn=20Alconada=20Verzini?= Date: Wed, 3 Jan 2024 17:17:36 -0300 Subject: [PATCH] tmp --- .gas-snapshot | 80 +++--- test/DeployTests.t.sol | 2 +- test/ETHPriceIsRight.t.sol | 4 +- test/EngenCredits.t.sol | 18 +- test/Faucet.t.sol | 6 +- test/KYCViewer.t.sol | 4 +- test/KintoEntryPoint.t.sol | 2 +- test/KintoID.t.sol | 31 ++- test/KintoWallet.t.sol | 422 +++++++++++++---------------- test/KintoWalletFactory.t.sol | 10 +- test/SponsorPaymastExploit.t.sol | 7 +- test/SponsorPaymaster.t.sol | 6 +- test/helpers/AATestScaffolding.sol | 108 ++++++-- test/helpers/UserOp.sol | 1 - 14 files changed, 364 insertions(+), 337 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index a3546a744..0902507ff 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,12 +1,12 @@ DeveloperDeployTest:testUp() (gas: 24279) ETHPriceIsRightTest:testAnyoneCanChangeGuessBeforeEnd() (gas: 131807) ETHPriceIsRightTest:testAnyoneCanEnterGuessBeforeEnd() (gas: 127341) -ETHPriceIsRightTest:testFailCannotEnterGuessAfterTime() (gas: 11629) +ETHPriceIsRightTest:test_RevertWhen_CannotEnterGuessAfterTime() (gas: 11629) ETHPriceIsRightTest:testGuessCalculations() (gas: 156151) ETHPriceIsRightTest:testUp() (gas: 16852) EngenCreditsTest:testCanBurnAfterSettingFlag() (gas: 70853) EngenCreditsTest:testCanTransferAfterSettingFlag() (gas: 100027) -EngenCreditsTest:testFailOthersCannotUpgrade() (gas: 2102028) +EngenCreditsTest:test_RevertWhen_OthersCannotUpgrade() (gas: 2102028) EngenCreditsTest:testNobodyCanBurn() (gas: 70679) EngenCreditsTest:testNobodyCanTransfer() (gas: 71888) EngenCreditsTest:testOthersCannotMint() (gas: 25978) @@ -18,12 +18,12 @@ EngenCreditsTest:testWalletCanGetPointsWithOverride() (gas: 657489) EngenCreditsTest:testWalletCannotGetPointsTwice() (gas: 718288) FaucetTest:testClaim() (gas: 81023) FaucetTest:testClaimOnBehalf() (gas: 115966) -FaucetTest:testFailIfClaimedTwice() (gas: 77198) -FaucetTest:testFailOwnerCannotStartWithoutAmount() (gas: 19407) -FaucetTest:testFailStartFaucetByOthers() (gas: 16870) +FaucetTest:test_RevertWhen_IfClaimedTwice() (gas: 77198) +FaucetTest:test_RevertWhen_OwnerCannotStartWithoutAmount() (gas: 19407) +FaucetTest:test_RevertWhen_StartFaucetByOthers() (gas: 16870) FaucetTest:testOwnerCanStartFaucet() (gas: 42651) FaucetTest:testUp() (gas: 6294) -KYCViewerTest:testFailOthersCannotUpgradeFactory() (gas: 1029248) +KYCViewerTest:test_RevertWhen_OthersCannotUpgradeFactory() (gas: 1029248) KYCViewerTest:testIsKYCBothOwnerAndWallet() (gas: 82707) KYCViewerTest:testOwnerCanUpgradeViewer() (gas: 1065414) KYCViewerTest:testUp() (gas: 40633) @@ -34,14 +34,14 @@ KintoIDTest:testBurnFailsWithoutMinting() (gas: 26911) KintoIDTest:testBurnKYC() (gas: 250194) KintoIDTest:testBurningTwiceFails() (gas: 254209) KintoIDTest:testDappSignature() (gas: 166) -KintoIDTest:testFailOnlyProviderCanMonitor() (gas: 48382) -KintoIDTest:testFailOthersCannotUpgrade() (gas: 3885070) -KintoIDTest:testFailProviderCanAddTraitUnknownUser() (gas: 22719) -KintoIDTest:testFailTransfersAreDisabled() (gas: 297354) -KintoIDTest:testFailUserCannotAddSanction() (gas: 47795) -KintoIDTest:testFailUserCannotAddTrait() (gas: 47797) -KintoIDTest:testFailUserCannotRemoveSanction() (gas: 22608) -KintoIDTest:testFailUserCannotRemoveTrait() (gas: 326993) +KintoIDTest:test_RevertWhen_OnlyProviderCanMonitor() (gas: 48382) +KintoIDTest:test_RevertWhen_OthersCannotUpgrade() (gas: 3885070) +KintoIDTest:test_RevertWhen_ProviderCanAddTraitUnknownUser() (gas: 22719) +KintoIDTest:test_RevertWhen_TransfersAreDisabled() (gas: 297354) +KintoIDTest:test_RevertWhen_UserCannotAddSanction() (gas: 47795) +KintoIDTest:test_RevertWhen_UserCannotAddTrait() (gas: 47797) +KintoIDTest:test_RevertWhen_UserCannotRemoveSanction() (gas: 22608) +KintoIDTest:test_RevertWhen_UserCannotRemoveTrait() (gas: 326993) KintoIDTest:testIsSanctionsMonitored() (gas: 28227) KintoIDTest:testMintCompanyKYC() (gas: 284477) KintoIDTest:testMintIndividualKYC() (gas: 282508) @@ -60,9 +60,9 @@ KintoIDTest:testSettingTraitsAndSanctions() (gas: 317512) KintoIDTest:testUp() (gas: 17956) KintoWalletFactoryTest:testAllWalletsUpgrade() (gas: 3517833) KintoWalletFactoryTest:testDeployCustomContract() (gas: 136473) -KintoWalletFactoryTest:testFailCreateWalletThroughDeploy() (gas: 51285) -KintoWalletFactoryTest:testFailOthersCannotUpgradeFactory() (gas: 2636897) -KintoWalletFactoryTest:testFailOthersCannotUpgradeWallets() (gas: 3498853) +KintoWalletFactoryTest:test_RevertWhen_CreateWalletThroughDeploy() (gas: 51285) +KintoWalletFactoryTest:test_RevertWhen_OthersCannotUpgradeFactory() (gas: 2636897) +KintoWalletFactoryTest:test_RevertWhen_OthersCannotUpgradeWallets() (gas: 3498853) KintoWalletFactoryTest:testOwnerCanUpgradeFactory() (gas: 2673030) KintoWalletFactoryTest:testRandomSignerCannotFundWallet() (gas: 77154) KintoWalletFactoryTest:testSignerCanFundWallet() (gas: 71109) @@ -76,26 +76,26 @@ KintoWalletTest:testApproveAndRevokeTokens() (gas: 580610) KintoWalletTest:testApproveTokens() (gas: 530958) KintoWalletTest:testChangingPolicyWithThreeSigners() (gas: 442028) KintoWalletTest:testChangingPolicyWithTwoSigners() (gas: 413114) -KintoWalletTest:testFailApproveTokensWithoutWhitelist() (gas: 157159) -KintoWalletTest:testFailCallingApproveDirectly() (gas: 625818) -KintoWalletTest:testFailChangingPolicyWithoutRightSigners() (gas: 174419) -KintoWalletTest:testFailDirectCall() (gas: 65568) -KintoWalletTest:testFailMultipleTransactionsExecuteBatchPaymasterRefuses() (gas: 363188) -KintoWalletTest:testFailMultisigTransaction() (gas: 605529) -KintoWalletTest:testFailMultisigTransactionWhen2OutOf3Signers() (gas: 620528) -KintoWalletTest:testFailOthersCannotUpgrade() (gas: 3151175) -KintoWalletTest:testFailOwnerCannotUpgrade() (gas: 3467167) -KintoWalletTest:testFailRecoverNotEnoughTime() (gas: 430100) -KintoWalletTest:testFailRecoverNotRecoverer() (gas: 79216) -KintoWalletTest:testFailRecoverWithoutBurningOldOwner() (gas: 368060) -KintoWalletTest:testFailRecoverWithoutMintingNewOwner() (gas: 218345) -KintoWalletTest:testFailSendingTransactionDirectly() (gas: 184911) -KintoWalletTest:testFailSettingAppKeyNoWhitelist() (gas: 389794) -KintoWalletTest:testFailTransactionViaPaymasterNoapproval() (gas: 457146) -KintoWalletTest:testFailWithDuplicateSigner() (gas: 379042) -KintoWalletTest:testFailWithEmptyArray() (gas: 383567) -KintoWalletTest:testFailWithManyOwners() (gas: 379274) -KintoWalletTest:testFailWithoutKYCSigner() (gas: 377318) +KintoWalletTest:test_RevertWhen_ApproveTokensWithoutWhitelist() (gas: 157159) +KintoWalletTest:test_RevertWhen_CallingApproveDirectly() (gas: 625818) +KintoWalletTest:test_RevertWhen_ChangingPolicyWithoutRightSigners() (gas: 174419) +KintoWalletTest:test_RevertWhen_DirectCall() (gas: 65568) +KintoWalletTest:test_RevertWhen_MultipleTransactionsExecuteBatchPaymasterRefuses() (gas: 363188) +KintoWalletTest:test_RevertWhen_MultisigTransaction() (gas: 605529) +KintoWalletTest:test_RevertWhen_MultisigTransactionWhen2OutOf3Signers() (gas: 620528) +KintoWalletTest:test_RevertWhen_OthersCannotUpgrade() (gas: 3151175) +KintoWalletTest:test_RevertWhen_OwnerCannotUpgrade() (gas: 3467167) +KintoWalletTest:test_RevertWhen_RecoverNotEnoughTime() (gas: 430100) +KintoWalletTest:test_RevertWhen_RecoverNotRecoverer() (gas: 79216) +KintoWalletTest:test_RevertWhen_RecoverWithoutBurningOldOwner() (gas: 368060) +KintoWalletTest:test_RevertWhen_RecoverWithoutMintingNewOwner() (gas: 218345) +KintoWalletTest:test_RevertWhen_SendingTransactionDirectly() (gas: 184911) +KintoWalletTest:test_RevertWhen_SettingAppKeyNoWhitelist() (gas: 389794) +KintoWalletTest:test_RevertWhen_TransactionViaPaymasterNoapproval() (gas: 457146) +KintoWalletTest:test_RevertWhen_WithDuplicateSigner() (gas: 379042) +KintoWalletTest:test_RevertWhen_WithEmptyArray() (gas: 383567) +KintoWalletTest:test_RevertWhen_WithManyOwners() (gas: 379274) +KintoWalletTest:test_RevertWhen_WithoutKYCSigner() (gas: 377318) KintoWalletTest:testMultipleTransactionsExecuteBatchPaymaster() (gas: 534232) KintoWalletTest:testMultipleTransactionsViaPaymaster() (gas: 756771) KintoWalletTest:testMultisigTransaction() (gas: 859779) @@ -108,9 +108,9 @@ KintoWalletTest:testTransactionViaPaymaster() (gas: 694244) KintoWalletTest:testUp() (gas: 32038) KintoWalletTest:testWalletOwnersAreWhitelisted() (gas: 39988) SponsorPaymasterExploitTest:testExploit() (gas: 283756) -SponsorPaymasterTest:testFailOthersCannotUpgrade() (gas: 2205926) -SponsorPaymasterTest:testFailUserCanDepositStakeAndWithdrawWithoutRoll() (gas: 129377) -SponsorPaymasterTest:testFailUserCanWithdrawAllInEmergency() (gas: 137198) +SponsorPaymasterTest:test_RevertWhen_OthersCannotUpgrade() (gas: 2205926) +SponsorPaymasterTest:test_RevertWhen_UserCanDepositStakeAndWithdrawWithoutRoll() (gas: 129377) +SponsorPaymasterTest:test_RevertWhen_UserCanWithdrawAllInEmergency() (gas: 137198) SponsorPaymasterTest:testOwnerCanDepositStakeAndWithdraw() (gas: 95286) SponsorPaymasterTest:testOwnerCanUpgrade() (gas: 2242110) SponsorPaymasterTest:testOwnerCanWithdrawAllInEmergency() (gas: 123988) diff --git a/test/DeployTests.t.sol b/test/DeployTests.t.sol index 4437e5c12..fb6990d8e 100644 --- a/test/DeployTests.t.sol +++ b/test/DeployTests.t.sol @@ -77,7 +77,7 @@ contract DeveloperDeployTest is Create2Helper, UserOp, AATestScaffolding { vm.startPrank(address(1)); _owner.transfer(1e18); vm.stopPrank(); - deployAAScaffolding(_owner, _kycProvider, _recoverer); + deployAAScaffolding(_owner, 1, _kycProvider, _recoverer); vm.startPrank(_owner); address created = _walletFactory.deployContract(0, abi.encodePacked(type(Counter).creationCode), bytes32(0)); diff --git a/test/ETHPriceIsRight.t.sol b/test/ETHPriceIsRight.t.sol index 4f1d3e9cc..5fc6597ad 100644 --- a/test/ETHPriceIsRight.t.sol +++ b/test/ETHPriceIsRight.t.sol @@ -63,9 +63,11 @@ contract ETHPriceIsRightTest is Test { assertEq(_priceIsRight.avgGuess(), 3000 ether); } - function testFailCannotEnterGuessAfterTime() public { + function test_RevertWhen_CannotEnterGuessAfterTime() public { vm.startPrank(_user); vm.warp(_priceIsRight.END_ENTER_TIMESTAMP() + 1); + + vm.expectRevert("You cannot enter guesses anymore"); _priceIsRight.enterGuess(2000 ether); vm.stopPrank(); } diff --git a/test/EngenCredits.t.sol b/test/EngenCredits.t.sol index 4df7a7a60..9b931f1df 100644 --- a/test/EngenCredits.t.sol +++ b/test/EngenCredits.t.sol @@ -34,9 +34,9 @@ contract EngenCreditsTest is Create2Helper, UserOp, AATestScaffolding { vm.startPrank(address(1)); _owner.transfer(1e18); vm.stopPrank(); - deployAAScaffolding(_owner, _kycProvider, _recoverer); - _setPaymasterForContract(address(_engenCredits)); - _setPaymasterForContract(address(_kintoWalletv1)); + deployAAScaffolding(_owner, 1, _kycProvider, _recoverer); + _fundPaymasterForContract(address(_engenCredits)); + _fundPaymasterForContract(address(_kintoWalletv1)); } function testUp() public { @@ -52,20 +52,18 @@ contract EngenCreditsTest is Create2Helper, UserOp, AATestScaffolding { vm.startPrank(_owner); EngenCreditsV2 _implementationV2 = new EngenCreditsV2(); _engenCredits.upgradeTo(address(_implementationV2)); - // re-wrap the _proxy + + // ensure that the implementation has been upgraded _engenCreditsV2 = EngenCreditsV2(address(_engenCredits)); assertEq(_engenCreditsV2.newFunction(), 1); vm.stopPrank(); } - function testFailOthersCannotUpgrade() public { - vm.startPrank(_recoverer); + function test_RevertWhen_OthersCannotUpgrade() public { EngenCreditsV2 _implementationV2 = new EngenCreditsV2(); + + vm.expectRevert("Ownable: caller is not the owner"); _engenCredits.upgradeTo(address(_implementationV2)); - // re-wrap the _proxy - _engenCreditsV2 = EngenCreditsV2(address(_engenCredits)); - assertEq(_engenCreditsV2.newFunction(), 1); - vm.stopPrank(); } /* ============ Token Tests ============ */ diff --git a/test/Faucet.t.sol b/test/Faucet.t.sol index 12a742cde..ae9bb1657 100644 --- a/test/Faucet.t.sol +++ b/test/Faucet.t.sol @@ -54,13 +54,13 @@ contract FaucetTest is Test { vm.stopPrank(); } - function testFailOwnerCannotStartWithoutAmount() public { + function test_RevertWhen_OwnerCannotStartWithoutAmount() public { vm.startPrank(_owner); _faucet.startFaucet{value: 0.1 ether}(); vm.stopPrank(); } - function testFailStartFaucetByOthers() public { + function test_RevertWhen_StartFaucetByOthers() public { vm.startPrank(_user); _faucet.startFaucet{value: 1 ether}(); vm.stopPrank(); @@ -78,7 +78,7 @@ contract FaucetTest is Test { vm.stopPrank(); } - function testFailIfClaimedTwice() public { + function test_RevertWhen_IfClaimedTwice() public { vm.startPrank(_owner); _faucet.startFaucet{value: 1 ether}(); vm.stopPrank(); diff --git a/test/KYCViewer.t.sol b/test/KYCViewer.t.sol index b8372fe89..0ed11b980 100644 --- a/test/KYCViewer.t.sol +++ b/test/KYCViewer.t.sol @@ -58,7 +58,7 @@ contract KYCViewerTest is Create2Helper, UserOp, AATestScaffolding { vm.startPrank(address(1)); _owner.transfer(1e18); vm.stopPrank(); - deployAAScaffolding(_owner, _kycProvider, _recoverer); + deployAAScaffolding(_owner, 1, _kycProvider, _recoverer); vm.startPrank(_owner); _implkycViewer = new KYCViewer{salt: 0}(address(_walletFactory)); // deploy _proxy contract and point it to _implementation @@ -90,7 +90,7 @@ contract KYCViewerTest is Create2Helper, UserOp, AATestScaffolding { vm.stopPrank(); } - function testFailOthersCannotUpgradeFactory() public { + function test_RevertWhen_OthersCannotUpgradeFactory() public { KYCViewerV2 _implementationV2 = new KYCViewerV2(address(_walletFactory)); _kycViewer.upgradeTo(address(_implementationV2)); // re-wrap the _proxy diff --git a/test/KintoEntryPoint.t.sol b/test/KintoEntryPoint.t.sol index f957383d4..bad9c452d 100644 --- a/test/KintoEntryPoint.t.sol +++ b/test/KintoEntryPoint.t.sol @@ -38,7 +38,7 @@ contract KintoEntryPointTest is AATestScaffolding, UserOp { vm.startPrank(address(1)); _owner.transfer(1e18); vm.stopPrank(); - deployAAScaffolding(_owner, _kycProvider, _recoverer); + deployAAScaffolding(_owner, 1, _kycProvider, _recoverer); } function testUp() public { diff --git a/test/KintoID.t.sol b/test/KintoID.t.sol index 78405d387..bb8745364 100644 --- a/test/KintoID.t.sol +++ b/test/KintoID.t.sol @@ -9,6 +9,7 @@ import "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable. import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; import "forge-std/Test.sol"; import "forge-std/console.sol"; @@ -63,18 +64,24 @@ contract KintoIDTest is KYCSignature { vm.startPrank(_owner); KintoIDv2 _implementationV2 = new KintoIDv2(); _kintoIDv1.upgradeTo(address(_implementationV2)); - // re-wrap the _proxy + + // ensure that the _proxy is now pointing to the new implementation _kintoIDv2 = KintoIDv2(address(_proxy)); assertEq(_kintoIDv2.newFunction(), 1); vm.stopPrank(); } - function testFailOthersCannotUpgrade() public { + function test_RevertWhen_OthersCannotUpgrade() public { KintoIDv2 _implementationV2 = new KintoIDv2(); + + bytes memory err = abi.encodePacked( + "AccessControl: account ", + Strings.toHexString(address(this)), + " is missing role ", + Strings.toHexString(uint256(_implementationV2.UPGRADER_ROLE()), 32) + ); + vm.expectRevert(err); _kintoIDv1.upgradeTo(address(_implementationV2)); - // re-wrap the _proxy - _kintoIDv2 = KintoIDv2(address(_proxy)); - assertEq(_kintoIDv2.newFunction(), 1); } function testAuthorizedCanUpgrade() public { @@ -218,7 +225,7 @@ contract KintoIDTest is KYCSignature { assertEq(_kintoIDv1.lastMonitoredAt(), block.timestamp); } - function testFailOnlyProviderCanMonitor() public { + function test_RevertWhen_OnlyProviderCanMonitor() public { vm.startPrank(_user); _kintoIDv1.monitor(new address[](0), new IKintoID.MonitorUpdateData[][](0)); } @@ -261,13 +268,13 @@ contract KintoIDTest is KYCSignature { assertEq(_kintoIDv1.lastMonitoredAt(), block.timestamp); } - function testFailProviderCanAddTraitUnknownUser() public { + function test_RevertWhen_ProviderCanAddTraitUnknownUser() public { vm.startPrank(_kycProvider); _kintoIDv1.addTrait(_user, 1); assertEq(_kintoIDv1.hasTrait(_user, 1), true); } - function testFailUserCannotAddTrait() public { + function test_RevertWhen_UserCannotAddTrait() public { vm.startPrank(_user); IKintoID.SignatureData memory sigdata = _auxCreateSignature(_kintoIDv1, _user, _user, 3, block.timestamp + 1000); uint8[] memory traits = new uint8[](1); @@ -289,7 +296,7 @@ contract KintoIDTest is KYCSignature { assertEq(_kintoIDv1.lastMonitoredAt(), block.timestamp); } - function testFailUserCannotRemoveTrait() public { + function test_RevertWhen_UserCannotRemoveTrait() public { vm.startPrank(_kycProvider); IKintoID.SignatureData memory sigdata = _auxCreateSignature(_kintoIDv1, _user, _user, 3, block.timestamp + 1000); uint8[] memory traits = new uint8[](1); @@ -329,7 +336,7 @@ contract KintoIDTest is KYCSignature { assertEq(_kintoIDv1.lastMonitoredAt(), block.timestamp); } - function testFailUserCannotAddSanction() public { + function test_RevertWhen_UserCannotAddSanction() public { vm.startPrank(_user); IKintoID.SignatureData memory sigdata = _auxCreateSignature(_kintoIDv1, _user, _user, 3, block.timestamp + 1000); uint8[] memory traits = new uint8[](1); @@ -338,7 +345,7 @@ contract KintoIDTest is KYCSignature { _kintoIDv1.addSanction(_user2, 1); } - function testFailUserCannotRemoveSanction() public { + function test_RevertWhen_UserCannotRemoveSanction() public { vm.startPrank(_kycProvider); _kintoIDv1.addSanction(_user, 1); assertEq(_kintoIDv1.isSanctionsSafeIn(_user, 1), false); @@ -349,7 +356,7 @@ contract KintoIDTest is KYCSignature { // Transfer - function testFailTransfersAreDisabled() public { + function test_RevertWhen_TransfersAreDisabled() public { IKintoID.SignatureData memory sigdata = _auxCreateSignature(_kintoIDv1, _user, _user, 3, block.timestamp + 1000); uint8[] memory traits = new uint8[](1); traits[0] = 1; diff --git a/test/KintoWallet.t.sol b/test/KintoWallet.t.sol index 6ec1bd098..727c824e2 100644 --- a/test/KintoWallet.t.sol +++ b/test/KintoWallet.t.sol @@ -49,24 +49,52 @@ contract KintoWalletTest is AATestScaffolding, UserOp { using SignatureChecker for address; KintoWalletv2 _kintoWalletv2; + uint256[] privateKeys; uint256 _chainID = 1; - address payable _owner = payable(vm.addr(1)); - address _secondowner = address(2); - address _user = vm.addr(3); - address _user2 = vm.addr(5); - address _upgrader = address(5); - address _kycProvider = address(6); - address _recoverer = address(7); + // private keys + uint256 _ownerPk = 1; + uint256 _secondownerPk = 2; + uint256 _userPk = 3; + uint256 _user2Pk = 4; + uint256 _upgraderPk = 5; + uint256 _kycProviderPk = 6; + uint256 _recovererPk = 7; + + // users + address payable _owner = payable(vm.addr(_ownerPk)); + address payable _secondowner = payable(vm.addr(_secondownerPk)); + address payable _user = payable(vm.addr(_userPk)); + address payable _user2 = payable(vm.addr(_user2Pk)); + address payable _upgrader = payable(vm.addr(_upgraderPk)); + address payable _kycProvider = payable(vm.addr(_kycProviderPk)); + address payable _recoverer = payable(vm.addr(_recovererPk)); + + // events + event UserOperationRevertReason( + bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason + ); + event KintoWalletInitialized(IEntryPoint indexed entryPoint, address indexed owner); + event WalletPolicyChanged(uint256 newPolicy, uint256 oldPolicy); + event RecovererChanged(address indexed newRecoverer, address indexed recoverer); function setUp() public { vm.chainId(_chainID); - vm.startPrank(address(1)); + + vm.prank(address(1)); _owner.transfer(1e18); - vm.stopPrank(); - deployAAScaffolding(_owner, _kycProvider, _recoverer); - _setPaymasterForContract(address(_kintoWalletv1)); + + deployAAScaffolding(_owner, 1, _kycProvider, _recoverer); + + // Add paymaster to _kintoWalletv1 + _fundPaymasterForContract(address(_kintoWalletv1)); + + // Default tests to use 1 private key for simplicity + privateKeys = new uint256[](1); + + // Default tests to use _ownerPk unless otherwise specified + privateKeys[0] = _ownerPk; } function testUp() public { @@ -76,13 +104,13 @@ contract KintoWalletTest is AATestScaffolding, UserOp { /* ============ Upgrade Tests ============ */ - function testFailOwnerCannotUpgrade() public { - _setPaymasterForContract(address(_kintoWalletv1)); - vm.startPrank(_owner); - uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; + function test_RevertWhen_OwnerCannotUpgrade() public { + // deploy a KintoWalletv2 KintoWalletv2 _implementationV2 = new KintoWalletv2(_entryPoint, _kintoIDv1); + + uint256 startingNonce = _kintoWalletv1.getNonce(); + + // try calling upgradeTo from _owner wallet to upgrade _owner wallet UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -95,23 +123,34 @@ contract KintoWalletTest is AATestScaffolding, UserOp { ); UserOperation[] memory userOps = new UserOperation[](1); userOps[0] = userOp; - // Execute the transaction via the entry point + + // execute the transaction via the entry point and expect a revert event + // @dev handleOps fails silently (does not revert) + vm.expectEmit(true, true, true, false); + emit UserOperationRevertReason( + _entryPoint.getUserOpHash(userOp), + userOp.sender, + userOp.nonce, + bytes("") // todo: add revert reason + ); _entryPoint.handleOps(userOps, payable(_owner)); - _kintoWalletv2 = KintoWalletv2(payable(address(_kintoWalletv1))); - assertEq(_kintoWalletv2.newFunction(), 1); - vm.stopPrank(); } - function testFailOthersCannotUpgrade() public { - _setPaymasterForContract(address(_kintoWalletv1)); - vm.startPrank(_owner); + function test_RevertWhen_OthersCannotUpgrade() public { + // create a wallet for _user + approveKYC(_user, _userPk); + IKintoWallet userWallet = _walletFactory.createAccount(_user, _recoverer, 0); + + // deploy a KintoWalletv2 KintoWalletv2 _implementationV2 = new KintoWalletv2(_entryPoint, _kintoIDv1); - uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 3; + + // try calling upgradeTo from _user wallet to upgrade _owner wallet + uint256 startingNonce = userWallet.getNonce(); + privateKeys[0] = _userPk; + UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, - address(_user), + address(userWallet), startingNonce, privateKeys, address(_kintoWalletv1), @@ -119,26 +158,34 @@ contract KintoWalletTest is AATestScaffolding, UserOp { abi.encodeWithSignature("upgradeTo(address)", address(_implementationV2)), address(_paymaster) ); + UserOperation[] memory userOps = new UserOperation[](1); userOps[0] = userOp; - // Execute the transaction via the entry point + + // execute the transaction via the entry point + // @dev handleOps seems to fail silently (does not revert) + vm.expectEmit(true, true, true, false); + emit UserOperationRevertReason( + _entryPoint.getUserOpHash(userOp), + userOp.sender, + userOp.nonce, + bytes("") // todo: add revert reason + ); + _entryPoint.handleOps(userOps, payable(_owner)); - _kintoWalletv2 = KintoWalletv2(payable(address(_kintoWalletv1))); - assertEq(_kintoWalletv2.newFunction(), 1); + vm.stopPrank(); } /* ============ One Signer Account Transaction Tests ============ */ - function testFailSendingTransactionDirectly() public { + function test_RevertWhen_SendingTransactionDirectly() public { vm.startPrank(_owner); // Let's deploy the counter contract Counter counter = new Counter(); assertEq(counter.count(), 0); // Let's send a transaction to the counter contract through our wallet uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperation( _chainID, address(_kintoWalletv1), @@ -156,18 +203,16 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); } - function testFailTransactionViaPaymasterNoapproval() public { + function test_RevertWhen_TransactionViaPaymasterNoapproval() public { vm.startPrank(_owner); // Let's deploy the counter contract Counter counter = new Counter(); assertEq(counter.count(), 0); vm.stopPrank(); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); vm.startPrank(_owner); // Let's send a transaction to the counter contract through our wallet uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -193,14 +238,12 @@ contract KintoWalletTest is AATestScaffolding, UserOp { Counter counter = new Counter(); assertEq(counter.count(), 0); vm.stopPrank(); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); vm.startPrank(_owner); // Let's send a transaction to the counter contract through our wallet uint256 startingNonce = _kintoWalletv1.getNonce(); bool[] memory flags = new bool[](1); flags[0] = true; - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp2 = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -233,11 +276,9 @@ contract KintoWalletTest is AATestScaffolding, UserOp { Counter counter = new Counter(); assertEq(counter.count(), 0); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; vm.stopPrank(); vm.startPrank(_owner); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); // Let's send a transaction to the counter contract through our wallet UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, @@ -277,11 +318,9 @@ contract KintoWalletTest is AATestScaffolding, UserOp { Counter counter = new Counter(); assertEq(counter.count(), 0); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; vm.stopPrank(); vm.startPrank(_owner); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); address[] memory targets = new address[](3); targets[0] = address(_kintoWalletv1); targets[1] = address(counter); @@ -311,18 +350,16 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); } - function testFailMultipleTransactionsExecuteBatchPaymasterRefuses() public { + function test_RevertWhen_MultipleTransactionsExecuteBatchPaymasterRefuses() public { vm.startPrank(_owner); // Let's deploy the counter contract Counter counter = new Counter(); Counter counter2 = new Counter(); assertEq(counter.count(), 0); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; vm.stopPrank(); vm.startPrank(_owner); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); address[] memory targets = new address[](3); targets[0] = address(_kintoWalletv1); targets[1] = address(counter); @@ -357,13 +394,10 @@ contract KintoWalletTest is AATestScaffolding, UserOp { function testAddingOneSigner() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address[] memory owners = new address[](2); owners[0] = _owner; owners[1] = _user; uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -382,15 +416,12 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); } - function testFailWithDuplicateSigner() public { + function test_RevertWhen_WithDuplicateSigner() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address[] memory owners = new address[](2); owners[0] = _owner; owners[1] = _owner; uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -409,13 +440,10 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); } - function testFailWithEmptyArray() public { + function test_RevertWhen_WithEmptyArray() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address[] memory owners = new address[](0); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -434,12 +462,9 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); } - function testFailWithManyOwners() public { + function test_RevertWhen_WithManyOwners() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; address[] memory owners = new address[](4); owners[0] = _owner; owners[1] = _user; @@ -463,12 +488,9 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); } - function testFailWithoutKYCSigner() public { + function test_RevertWhen_WithoutKYCSigner() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; address[] memory owners = new address[](1); owners[0] = _user; UserOperation memory userOp = this.createUserOperationWithPaymaster( @@ -491,13 +513,10 @@ contract KintoWalletTest is AATestScaffolding, UserOp { function testChangingPolicyWithTwoSigners() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address[] memory owners = new address[](2); owners[0] = _owner; owners[1] = _user; uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -519,14 +538,11 @@ contract KintoWalletTest is AATestScaffolding, UserOp { function testChangingPolicyWithThreeSigners() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address[] memory owners = new address[](3); owners[0] = _owner; owners[1] = _user; owners[2] = _user2; uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -547,15 +563,12 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); } - function testFailChangingPolicyWithoutRightSigners() public { + function test_RevertWhen_ChangingPolicyWithoutRightSigners() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address[] memory owners = new address[](2); owners[0] = _owner; owners[1] = _user; uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -589,18 +602,15 @@ contract KintoWalletTest is AATestScaffolding, UserOp { /* ============ Multisig Transactions ============ */ function testMultisigTransaction() public { - vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); + // (1). generate resetSigners UserOp to set 2 owners address[] memory owners = new address[](2); owners[0] = _owner; owners[1] = _user; - uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; + UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), - startingNonce, + _kintoWalletv1.getNonce(), privateKeys, address(_kintoWalletv1), 0, @@ -609,55 +619,72 @@ contract KintoWalletTest is AATestScaffolding, UserOp { ); UserOperation[] memory userOps = new UserOperation[](1); userOps[0] = userOp; - // Execute the transaction via the entry point + + // (2). execute the transaction via the entry point + vm.expectEmit(); + emit WalletPolicyChanged(_kintoWalletv1.ALL_SIGNERS(), _kintoWalletv1.SINGLE_SIGNER()); _entryPoint.handleOps(userOps, payable(_owner)); + assertEq(_kintoWalletv1.owners(1), _user); assertEq(_kintoWalletv1.signerPolicy(), _kintoWalletv1.ALL_SIGNERS()); - // Deploy Counter contract + + // (3). deploy Counter contract Counter counter = new Counter(); assertEq(counter.count(), 0); - vm.stopPrank(); - // Fund counter contract - vm.startPrank(_owner); - _setPaymasterForContract(address(counter)); - // Create counter increment transaction - userOps = new UserOperation[](2); + + // (4). fund paymaster for Counter contract + _fundPaymasterForContract(address(counter)); + + // (5). Set private keys privateKeys = new uint256[](2); - privateKeys[0] = 1; - privateKeys[1] = 3; - userOp = this.createUserOperationWithPaymaster( + privateKeys[0] = _ownerPk; + privateKeys[1] = _userPk; + + // (6). Create 2 user ops: + userOps = new UserOperation[](2); + // a. Approval UserOp + userOps[0] = createApprovalUserOp( _chainID, - address(_kintoWalletv1), - _kintoWalletv1.getNonce() + 1, privateKeys, + address(_kintoWalletv1), + _kintoWalletv1.getNonce(), address(counter), - 0, - abi.encodeWithSignature("increment()"), address(_paymaster) ); - userOps[0] = createApprovalUserOp( + + // b. Counter increment + userOps[1] = this.createUserOperationWithPaymaster( _chainID, - privateKeys, address(_kintoWalletv1), - _kintoWalletv1.getNonce(), + _kintoWalletv1.getNonce() + 1, + privateKeys, address(counter), + 0, + abi.encodeWithSignature("increment()"), address(_paymaster) ); - userOps[1] = userOp; + + // (7). execute the transaction via the entry point _entryPoint.handleOps(userOps, payable(_owner)); assertEq(counter.count(), 1); - vm.stopPrank(); } - function testFailMultisigTransaction() public { + function test_RevertWhen_MultisigTransaction() public { + // (1). generate resetSigners UserOp to set 3 owners + // (2). execute the transaction via the entry point + // (3). deploy Counter contract + // (4). fund paymaster for Counter contract + // (5). Set private keys + // (6). Create 2 user ops: + // a. Approval UserOp + // b. Counter increment + // (7). execute the transaction via the entry point + vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address[] memory owners = new address[](2); owners[0] = _owner; owners[1] = _user; uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -680,11 +707,10 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); // Fund counter contract vm.startPrank(_owner); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); // Create counter increment transaction userOps = new UserOperation[](2); privateKeys = new uint256[](1); - privateKeys[0] = 1; userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -711,26 +737,16 @@ contract KintoWalletTest is AATestScaffolding, UserOp { } function testMultisigTransactionWith3Signers() public { - vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); - - // set 3 owners + // (1). generate resetSigners UserOp to set 3 owners address[] memory owners = new address[](3); owners[0] = _owner; owners[1] = _user; owners[2] = _user2; - // get nonce - uint256 startingNonce = _kintoWalletv1.getNonce(); - - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; - - // generate the user operation wihch changes the policy to ALL_SIGNERS UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), - startingNonce, + _kintoWalletv1.getNonce(), privateKeys, address(_kintoWalletv1), 0, @@ -740,26 +756,30 @@ contract KintoWalletTest is AATestScaffolding, UserOp { UserOperation[] memory userOps = new UserOperation[](1); userOps[0] = userOp; - // Execute the transaction via the entry point + // (2). execute the transaction via the entry point + vm.expectEmit(); + emit WalletPolicyChanged(_kintoWalletv1.ALL_SIGNERS(), _kintoWalletv1.SINGLE_SIGNER()); _entryPoint.handleOps(userOps, payable(_owner)); assertEq(_kintoWalletv1.owners(1), _user); assertEq(_kintoWalletv1.signerPolicy(), _kintoWalletv1.ALL_SIGNERS()); - // Deploy Counter contract + // (3). deploy Counter contract Counter counter = new Counter(); assertEq(counter.count(), 0); vm.stopPrank(); - // Fund counter contract + // (4). fund paymaster for Counter contract vm.startPrank(_owner); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); - // Create counter increment transaction - userOps = new UserOperation[](2); + // (5). Set private keys privateKeys = new uint256[](3); - privateKeys[0] = 1; - privateKeys[1] = 3; - privateKeys[2] = 5; + privateKeys[1] = _userPk; + privateKeys[2] = _upgraderPk; + + // (6). Create 2 user ops: + userOps = new UserOperation[](2); + // a. Approval UserOp userOps[0] = createApprovalUserOp( _chainID, privateKeys, @@ -768,7 +788,8 @@ contract KintoWalletTest is AATestScaffolding, UserOp { address(counter), address(_paymaster) ); - userOp = this.createUserOperationWithPaymaster( + // b. Counter increment + userOps[1] = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), _kintoWalletv1.getNonce() + 1, @@ -780,61 +801,24 @@ contract KintoWalletTest is AATestScaffolding, UserOp { ); userOps[1] = userOp; - // execute + // (7). execute the transaction via the entry point _entryPoint.handleOps(userOps, payable(_owner)); assertEq(counter.count(), 1); vm.stopPrank(); } function testMultisigTransactionWith1SignerButSeveralOwners() public { - vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); - - // set 3 owners - address[] memory owners = new address[](3); - owners[0] = _owner; - owners[1] = _user; - owners[2] = _user2; - - // get nonce - uint256 startingNonce = _kintoWalletv1.getNonce(); - - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; - - // generate the user operation wihch changes the policy to ALL_SIGNERS - UserOperation memory userOp = this.createUserOperationWithPaymaster( - _chainID, - address(_kintoWalletv1), - startingNonce, - privateKeys, - address(_kintoWalletv1), - 0, - abi.encodeWithSignature("resetSigners(address[],uint8)", owners, _kintoWalletv1.SINGLE_SIGNER()), - address(_paymaster) - ); - UserOperation[] memory userOps = new UserOperation[](1); - userOps[0] = userOp; - - // Execute the transaction via the entry point - _entryPoint.handleOps(userOps, payable(_owner)); - assertEq(_kintoWalletv1.owners(1), _user); - assertEq(_kintoWalletv1.signerPolicy(), _kintoWalletv1.SINGLE_SIGNER()); - - // Deploy Counter contract + // (1). deploy Counter contract Counter counter = new Counter(); assertEq(counter.count(), 0); - vm.stopPrank(); - // Fund counter contract - vm.startPrank(_owner); - _setPaymasterForContract(address(counter)); + // (2). fund paymaster for Counter contract + _fundPaymasterForContract(address(counter)); - // Create counter increment transaction + // (3). Create 2 user ops: + UserOperation[] memory userOps = new UserOperation[](1); userOps = new UserOperation[](2); - privateKeys = new uint256[](1); - privateKeys[0] = 1; - + // a. Approval UserOp userOps[0] = createApprovalUserOp( _chainID, privateKeys, @@ -844,7 +828,8 @@ contract KintoWalletTest is AATestScaffolding, UserOp { address(_paymaster) ); - userOp = this.createUserOperationWithPaymaster( + // b. Counter increment + userOps[1] = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), _kintoWalletv1.getNonce() + 1, @@ -854,17 +839,25 @@ contract KintoWalletTest is AATestScaffolding, UserOp { abi.encodeWithSignature("increment()"), address(_paymaster) ); - userOps[1] = userOp; - // execute + // (4). execute the transaction via the entry point _entryPoint.handleOps(userOps, payable(_owner)); assertEq(counter.count(), 1); vm.stopPrank(); } - function testFailMultisigTransactionWhen2OutOf3Signers() public { + function test_RevertWhen_MultisigTransactionWhen2OutOf3Signers() public { + // (1). generate resetSigners UserOp to set 3 owners + // (2). execute the transaction via the entry point + // (3). deploy Counter contract + // (4). fund paymaster for Counter contract + // (5). Set private keys + // (6). Create 2 user ops: + // a. Approval UserOp + // b. Counter increment + // (7). execute the transaction via the entry point + vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); // set 3 owners address[] memory owners = new address[](3); @@ -875,9 +868,6 @@ contract KintoWalletTest is AATestScaffolding, UserOp { // get nonce uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; - // generate the user operation wihch changes the policy to ALL_SIGNERS UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, @@ -904,13 +894,13 @@ contract KintoWalletTest is AATestScaffolding, UserOp { // Fund counter contract vm.startPrank(_owner); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); // Create counter increment transaction userOps = new UserOperation[](2); privateKeys = new uint256[](2); - privateKeys[0] = 1; - privateKeys[1] = 3; + privateKeys[1] = _ownerPk; + privateKeys[1] = _userPk; userOps[0] = createApprovalUserOp( _chainID, @@ -942,7 +932,6 @@ contract KintoWalletTest is AATestScaffolding, UserOp { function testRecoverAccountSuccessfully() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); vm.stopPrank(); vm.startPrank(_recoverer); assertEq(_kintoWalletv1.owners(0), _owner); @@ -978,27 +967,24 @@ contract KintoWalletTest is AATestScaffolding, UserOp { assertEq(_kintoWalletv1.owners(0), _user); } - function testFailRecoverNotRecoverer() public { + function test_RevertWhen_RecoverNotRecoverer() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); assertEq(_kintoWalletv1.owners(0), _owner); // Start Recovery _walletFactory.startWalletRecovery(payable(address(_kintoWalletv1))); } - function testFailDirectCall() public { + function test_RevertWhen_DirectCall() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); vm.startPrank(_recoverer); // Start Recovery _kintoWalletv1.startRecovery(); } - function testFailRecoverWithoutBurningOldOwner() public { + function test_RevertWhen_RecoverWithoutBurningOldOwner() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); vm.startPrank(_recoverer); assertEq(_kintoWalletv1.owners(0), _owner); @@ -1029,9 +1015,8 @@ contract KintoWalletTest is AATestScaffolding, UserOp { _walletFactory.completeWalletRecovery(payable(address(_kintoWalletv1)), users); } - function testFailRecoverWithoutMintingNewOwner() public { + function test_RevertWhen_RecoverWithoutMintingNewOwner() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); vm.startPrank(_recoverer); assertEq(_kintoWalletv1.owners(0), _owner); @@ -1055,9 +1040,8 @@ contract KintoWalletTest is AATestScaffolding, UserOp { _walletFactory.completeWalletRecovery(payable(address(_kintoWalletv1)), users); } - function testFailRecoverNotEnoughTime() public { + function test_RevertWhen_RecoverNotEnoughTime() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); vm.startPrank(_recoverer); assertEq(_kintoWalletv1.owners(0), _owner); @@ -1101,12 +1085,9 @@ contract KintoWalletTest is AATestScaffolding, UserOp { function testAddingOneFunder() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address[] memory funders = new address[](1); funders[0] = address(23); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; bool[] memory flags = new bool[](1); flags[0] = true; UserOperation memory userOp = this.createUserOperationWithPaymaster( @@ -1131,7 +1112,6 @@ contract KintoWalletTest is AATestScaffolding, UserOp { function testApproveTokens() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address app = address(100); address[] memory tokens = new address[](1); tokens[0] = address(_engenCredits); @@ -1139,8 +1119,6 @@ contract KintoWalletTest is AATestScaffolding, UserOp { amounts[0] = 1e12; uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, @@ -1164,9 +1142,8 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); } - function testFailApproveTokensWithoutWhitelist() public { + function test_RevertWhen_ApproveTokensWithoutWhitelist() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address app = address(100); address[] memory tokens = new address[](1); tokens[0] = address(_engenCredits); @@ -1174,8 +1151,6 @@ contract KintoWalletTest is AATestScaffolding, UserOp { amounts[0] = 1e12; uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, @@ -1198,7 +1173,6 @@ contract KintoWalletTest is AATestScaffolding, UserOp { function testApproveAndRevokeTokens() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address app = address(100); address[] memory tokens = new address[](1); tokens[0] = address(_engenCredits); @@ -1206,8 +1180,6 @@ contract KintoWalletTest is AATestScaffolding, UserOp { amounts[0] = 1e12; uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, @@ -1246,14 +1218,12 @@ contract KintoWalletTest is AATestScaffolding, UserOp { vm.stopPrank(); } - function testFailCallingApproveDirectly() public { + function test_RevertWhen_CallingApproveDirectly() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_engenCredits)); + _fundPaymasterForContract(address(_engenCredits)); address app = address(100); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, @@ -1283,13 +1253,10 @@ contract KintoWalletTest is AATestScaffolding, UserOp { /* ============ App Key ============ */ - function testFailSettingAppKeyNoWhitelist() public { + function test_RevertWhen_SettingAppKeyNoWhitelist() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address app = address(_engenCredits); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -1310,11 +1277,8 @@ contract KintoWalletTest is AATestScaffolding, UserOp { function testSettingAppKey() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); address app = address(_engenCredits); uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, address(_kintoWalletv1), @@ -1343,7 +1307,6 @@ contract KintoWalletTest is AATestScaffolding, UserOp { function testMultisigTransactionWith2SignersWithAppkey() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); // set 2 owners address[] memory owners = new address[](2); @@ -1353,9 +1316,6 @@ contract KintoWalletTest is AATestScaffolding, UserOp { // get nonce uint256 startingNonce = _kintoWalletv1.getNonce(); - uint256[] memory privateKeys = new uint256[](1); - privateKeys[0] = 1; - // generate the user operation wihch changes the policy to ALL_SIGNERS UserOperation memory userOp = this.createUserOperationWithPaymaster( _chainID, @@ -1382,13 +1342,13 @@ contract KintoWalletTest is AATestScaffolding, UserOp { // Fund counter contract vm.startPrank(_owner); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); // Create counter increment transaction userOps = new UserOperation[](2); privateKeys = new uint256[](2); - privateKeys[0] = 1; - privateKeys[1] = 5; + privateKeys[0] = _ownerPk; + privateKeys[1] = _upgraderPk; userOps[0] = createApprovalUserOp( _chainID, privateKeys, diff --git a/test/KintoWalletFactory.t.sol b/test/KintoWalletFactory.t.sol index b941fbd83..4720b9ab6 100644 --- a/test/KintoWalletFactory.t.sol +++ b/test/KintoWalletFactory.t.sol @@ -74,7 +74,7 @@ contract KintoWalletFactoryTest is Create2Helper, UserOp, AATestScaffolding { vm.startPrank(address(1)); _owner.transfer(1e18); vm.stopPrank(); - deployAAScaffolding(_owner, _kycProvider, _recoverer); + deployAAScaffolding(_owner, 1, _kycProvider, _recoverer); } function testUp() public { @@ -94,7 +94,7 @@ contract KintoWalletFactoryTest is Create2Helper, UserOp, AATestScaffolding { vm.stopPrank(); } - function testFailOthersCannotUpgradeFactory() public { + function test_RevertWhen_OthersCannotUpgradeFactory() public { KintoWalletFactoryV2 _implementationV2 = new KintoWalletFactoryV2(_kintoWalletImpl); _walletFactory.upgradeTo(address(_implementationV2)); // re-wrap the _proxy @@ -119,7 +119,7 @@ contract KintoWalletFactoryTest is Create2Helper, UserOp, AATestScaffolding { vm.stopPrank(); } - function testFailOthersCannotUpgradeWallets() public { + function test_RevertWhen_OthersCannotUpgradeWallets() public { // Deploy wallet implementation _kintoWalletImpl = new KintoWalletV999(_entryPoint, _kintoIDv1); // deploy walletv1 through wallet factory and initializes it @@ -141,7 +141,7 @@ contract KintoWalletFactoryTest is Create2Helper, UserOp, AATestScaffolding { vm.stopPrank(); } - function testFailCreateWalletThroughDeploy() public { + function test_RevertWhen_CreateWalletThroughDeploy() public { vm.startPrank(_owner); bytes memory a = abi.encodeWithSelector(KintoWallet.initialize.selector, _owner, _owner); _walletFactory.deployContract( @@ -160,7 +160,7 @@ contract KintoWalletFactoryTest is Create2Helper, UserOp, AATestScaffolding { function testWhitelistedSignerCanFundWallet() public { vm.startPrank(_owner); - _setPaymasterForContract(address(_kintoWalletv1)); + _fundPaymasterForContract(address(_kintoWalletv1)); uint256 startingNonce = _kintoWalletv1.getNonce(); address[] memory funders = new address[](1); funders[0] = _funder; diff --git a/test/SponsorPaymastExploit.t.sol b/test/SponsorPaymastExploit.t.sol index 9ba9290c7..b92fb51e9 100644 --- a/test/SponsorPaymastExploit.t.sol +++ b/test/SponsorPaymastExploit.t.sol @@ -32,7 +32,7 @@ contract MyOpCreator is UserOp, KYCSignature { uint256 value, bytes calldata _bytesOp, address _paymaster - ) public view returns (UserOperation memory op) { + ) public returns (UserOperation memory op) { op = UserOperation({ sender: _account, nonce: nonce, @@ -145,7 +145,7 @@ contract SponsorPaymasterExploitTest is MyOpCreator { Counter counter = new Counter(); assertEq(counter.count(), 0); vm.stopPrank(); - _setPaymasterForContract(address(counter)); + _fundPaymasterForContract(address(counter)); vm.startPrank(_owner); // Let's send a transaction to the counter contract through our wallet uint256 startingNonce = _kintoWalletv1.getNonce(); @@ -176,7 +176,8 @@ contract SponsorPaymasterExploitTest is MyOpCreator { vm.stopPrank(); } - function _setPaymasterForContract(address _contract) private { + // funds contract so paymaster can use to pay for gas + function _fundPaymasterForContract(address _contract) private { vm.startPrank(_owner); vm.deal(_owner, 1000e18); // We add the deposit to the counter contract in the paymaster diff --git a/test/SponsorPaymaster.t.sol b/test/SponsorPaymaster.t.sol index 67b1e4462..b68e6ff8e 100644 --- a/test/SponsorPaymaster.t.sol +++ b/test/SponsorPaymaster.t.sol @@ -74,7 +74,7 @@ contract SponsorPaymasterTest is KYCSignature { vm.stopPrank(); } - function testFailOthersCannotUpgrade() public { + function test_RevertWhen_OthersCannotUpgrade() public { SponsorPaymasterV2 _implementationV2 = new SponsorPaymasterV2(_entryPoint, _owner); _paymaster.upgradeTo(address(_implementationV2)); // re-wrap the _proxy @@ -108,7 +108,7 @@ contract SponsorPaymasterTest is KYCSignature { vm.stopPrank(); } - function testFailUserCanDepositStakeAndWithdrawWithoutRoll() public { + function test_RevertWhen_UserCanDepositStakeAndWithdrawWithoutRoll() public { vm.startPrank(_user); uint256 balance = address(_user).balance; _paymaster.addDepositFor{value: 5e18}(address(_user)); @@ -131,7 +131,7 @@ contract SponsorPaymasterTest is KYCSignature { vm.stopPrank(); } - function testFailUserCanWithdrawAllInEmergency() public { + function test_RevertWhen_UserCanWithdrawAllInEmergency() public { vm.startPrank(_owner); _paymaster.addDepositFor{value: 5e18}(address(_owner)); vm.startPrank(_user); diff --git a/test/helpers/AATestScaffolding.sol b/test/helpers/AATestScaffolding.sol index aedbe6ff7..123c7787f 100644 --- a/test/helpers/AATestScaffolding.sol +++ b/test/helpers/AATestScaffolding.sol @@ -42,7 +42,45 @@ abstract contract AATestScaffolding is KYCSignature { UUPSProxy _proxycredit; EngenCredits _engenCredits; - function deployAAScaffolding(address _owner, address _kycProvider, address _recoverer) public { + address kycProvider; + + function deployAAScaffolding(address _owner, uint256 _ownerPk, address _kycProvider, address _recoverer) public { + kycProvider = _kycProvider; + + // Deploy Kinto ID + deployKintoID(_owner); + + // vm.startPrank(_owner); + EntryPoint entry = new EntryPoint{salt: 0}(); + _entryPoint = IKintoEntryPoint(address(entry)); + // vm.stopPrank(); + + // Deploy wallet & wallet factory + deployWalletFactory(_owner); + + // Approve wallet's owner KYC + approveKYC(_owner, _ownerPk); + + // deploy WalletV1 through wallet factory and initialize it + vm.prank(_owner); + _kintoWalletv1 = _walletFactory.createAccount(_owner, _recoverer, 0); + + // Deploy paymaster + deployPaymaster(_owner); + + // Deploy Engen Credits + deployEngenCredits(_owner); + + // Give some eth + vm.deal(_owner, 1e20); + } + + function _fundPaymasterForContract(address _contract) internal { + // We add the deposit to the counter contract in the paymaster + _paymaster.addDepositFor{value: 1e19}(address(_contract)); + } + + function deployKintoID(address _owner) public { vm.startPrank(_owner); // Deploy Kinto ID _implementation = new KintoID(); @@ -52,52 +90,74 @@ abstract contract AATestScaffolding is KYCSignature { _kintoIDv1 = KintoID(address(_proxy)); // Initialize _proxy _kintoIDv1.initialize(); - _kintoIDv1.grantRole(_kintoIDv1.KYC_PROVIDER_ROLE(), _kycProvider); - EntryPoint entry = new EntryPoint{salt: 0}(); - _entryPoint = IKintoEntryPoint(address(entry)); + _kintoIDv1.grantRole(_kintoIDv1.KYC_PROVIDER_ROLE(), kycProvider); + vm.stopPrank(); + } + + function deployWalletFactory(address _owner) public { + vm.startPrank(_owner); + // Deploy wallet implementation _kintoWalletImpl = new KintoWallet{salt: 0}(_entryPoint, _kintoIDv1); + //Deploy wallet factory implementation - _walletFactoryI = new KintoWalletFactory{salt: 0}(KintoWallet(payable(_kintoWalletImpl))); + _walletFactoryI = new KintoWalletFactory{salt: 0}(_kintoWalletImpl); _proxyf = new UUPSProxy{salt: 0}(address(_walletFactoryI), ""); _walletFactory = KintoWalletFactory(address(_proxyf)); + // Initialize wallet factory _walletFactory.initialize(_kintoIDv1); + // Set the wallet factory in the entry point _entryPoint.setWalletFactory(address(_walletFactory)); - // Mint an nft to the owner - IKintoID.SignatureData memory sigdata = - _auxCreateSignature(_kintoIDv1, _owner, _owner, 1, block.timestamp + 1000); - uint8[] memory traits = new uint8[](0); - vm.startPrank(_kycProvider); - _kintoIDv1.mintIndividualKyc(sigdata, traits); + vm.stopPrank(); + } + + function deployPaymaster(address _owner) public { vm.startPrank(_owner); - // deploy walletv1 through wallet factory and initializes it - _kintoWalletv1 = _walletFactory.createAccount(_owner, _recoverer, 0); + // deploy the paymaster _paymaster = new SponsorPaymaster{salt: 0}(_entryPoint); + // deploy _proxy contract and point it to _implementation - _proxys = new UUPSProxy(address(_paymaster), ""); + _proxys = new UUPSProxy{salt: 0}(address(_paymaster), ""); + // wrap in ABI to support easier calls _paymaster = SponsorPaymaster(address(_proxys)); - // Initialize proxy + + // initialize proxy _paymaster.initialize(_owner); - // Deploy engen credits - EngenCredits _imp = new EngenCredits{salt: 0}(); + + vm.stopPrank(); + } + + function deployEngenCredits(address _owner) public { + vm.startPrank(_owner); + + // deploy the engen credits + _engenCredits = new EngenCredits{salt: 0}(); + // deploy _proxy contract and point it to _implementation - _proxycredit = new UUPSProxy{salt: 0}(address(_imp), ""); + _proxycredit = new UUPSProxy{salt: 0}(address(_engenCredits), ""); + // wrap in ABI to support easier calls _engenCredits = EngenCredits(address(_proxycredit)); - // Initialize kyc viewer _proxy + + // initialize proxy _engenCredits.initialize(); - // Give some eth - vm.deal(_owner, 1e20); + vm.stopPrank(); } - function _setPaymasterForContract(address _contract) internal { - // We add the deposit to the counter contract in the paymaster - _paymaster.addDepositFor{value: 1e19}(address(_contract)); + function approveKYC(address _account, uint256 _accountPk) public { + vm.startPrank(kycProvider); + + IKintoID.SignatureData memory sigdata = + _auxCreateSignature(_kintoIDv1, _account, _account, _accountPk, block.timestamp + 1000); + uint8[] memory traits = new uint8[](0); + _kintoIDv1.mintIndividualKyc(sigdata, traits); + + vm.stopPrank(); } } diff --git a/test/helpers/UserOp.sol b/test/helpers/UserOp.sol index 0829ecadf..7a41f2e0d 100644 --- a/test/helpers/UserOp.sol +++ b/test/helpers/UserOp.sol @@ -164,7 +164,6 @@ abstract contract UserOp is Test { address _paymaster ) public view returns (UserOperation memory op) { op = _prepareUserOperation(_account, nonce, opParams, _paymaster); - op.signature = _signUserOp(op, KintoWallet(payable(_account)).entryPoint(), _chainID, _privateKeyOwners); }