From 67864e1a98e5e4fbb980c1b740ce9f80d9e7bb2d Mon Sep 17 00:00:00 2001 From: aboudjem Date: Wed, 29 May 2024 18:42:16 +0400 Subject: [PATCH 1/9] chore: Fix indentation --- .github/workflows/ci.yml | 2 +- scripts/foundry/generateGasReport.js | 210 +++++++++--------- .../base/TestNexusSwapETH_Integration.t.sol | 77 ++++--- .../base/TestNexusSwapWETH_Integration.t.sol | 77 +++---- .../fallback/TestNexus_FallbackFunction.t.sol | 2 +- 5 files changed, 182 insertions(+), 186 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85eb26e1..03af01ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -171,4 +171,4 @@ jobs: console.log("Slither report is empty. No comment will be posted."); return; } - await script({ github, context, header, body }) \ No newline at end of file + await script({ github, context, header, body }) diff --git a/scripts/foundry/generateGasReport.js b/scripts/foundry/generateGasReport.js index 8f6297d7..01bb4a96 100644 --- a/scripts/foundry/generateGasReport.js +++ b/scripts/foundry/generateGasReport.js @@ -1,121 +1,125 @@ -const fs = require('fs'); -const readline = require('readline'); -const { exec } = require('child_process'); +const fs = require("fs"); +const readline = require("readline"); +const { exec } = require("child_process"); // Define the log file and the output markdown file -const LOG_FILE = 'gas.log'; -const OUTPUT_FILE = 'gas_report.md'; +const LOG_FILE = "gas.log"; +const OUTPUT_FILE = "gas_report.md"; // Function to execute the `forge test` command function runForgeTest() { - return new Promise((resolve, reject) => { - console.log('๐Ÿš€ Running forge tests, this may take a few minutes...'); - exec('forge test -vv --mt test_Gas > gas.log', (error, stdout, stderr) => { - if (error) { - console.error(`โŒ Exec error: ${error}`); - reject(`exec error: ${error}`); - } - console.log('โœ… Forge tests completed.'); - resolve(stdout ? stdout : stderr); - }); + return new Promise((resolve, reject) => { + console.log("๐Ÿš€ Running forge tests, this may take a few minutes..."); + exec("forge test -vv --mt test_Gas > gas.log", (error, stdout, stderr) => { + if (error) { + console.error(`โŒ Exec error: ${error}`); + reject(`exec error: ${error}`); + } + console.log("โœ… Forge tests completed."); + resolve(stdout ? stdout : stderr); }); + }); } // Function to parse the log file and generate the report async function generateReport() { - await runForgeTest(); - - const fileStream = fs.createReadStream(LOG_FILE); - const rl = readline.createInterface({ - input: fileStream, - crlfDelay: Infinity - }); - - const results = []; - - console.log('๐Ÿ“„ Parsing log file, please wait...'); - for await (const line of rl) { - console.log(line); - if (line.includes('::')) { - const parts = line.split('::'); - const PROTOCOL = parts[0]; - const ACTION_FUNCTION = parts[1]; - let ACCOUNT_TYPE; - let IS_DEPLOYED; - if (line.includes('EOA')) { - ACCOUNT_TYPE = 'EOA'; - IS_DEPLOYED = 'False'; - } else if (line.includes('Nexus')) { - ACCOUNT_TYPE = 'Smart Account'; - IS_DEPLOYED = 'True'; - } else { - ACCOUNT_TYPE = 'Smart Account'; - IS_DEPLOYED = 'False'; - } - - const WITH_PAYMASTER = line.includes('WithPaymaster') ? 'True' : 'False'; - - const GAS_INFO = parts[4]; - const ACCESS_TYPE = GAS_INFO.split(': ')[0]; - const GAS_USED = GAS_INFO.split(': ')[1]; - - let RECEIVER_ACCESS; - if (ACCESS_TYPE === 'ColdAccess') { - RECEIVER_ACCESS = '๐ŸงŠ ColdAccess'; - } else if (ACCESS_TYPE === 'WarmAccess') { - RECEIVER_ACCESS = '๐Ÿ”ฅ WarmAccess'; - } else { - RECEIVER_ACCESS = 'N/A'; - } - - results.push({ - PROTOCOL, - ACTION_FUNCTION, - ACCOUNT_TYPE, - IS_DEPLOYED, - WITH_PAYMASTER, - RECEIVER_ACCESS, - GAS_USED, - FULL_LOG: line.trim() - }); - } + await runForgeTest(); + + const fileStream = fs.createReadStream(LOG_FILE); + const rl = readline.createInterface({ + input: fileStream, + crlfDelay: Infinity, + }); + + const results = []; + + console.log("๐Ÿ“„ Parsing log file, please wait..."); + for await (const line of rl) { + console.log(line); + if (line.includes("::")) { + const parts = line.split("::"); + const PROTOCOL = parts[0]; + const ACTION_FUNCTION = parts[1]; + let ACCOUNT_TYPE; + let IS_DEPLOYED; + if (line.includes("EOA")) { + ACCOUNT_TYPE = "EOA"; + IS_DEPLOYED = "False"; + } else if (line.includes("Nexus")) { + ACCOUNT_TYPE = "Smart Account"; + IS_DEPLOYED = "True"; + } else { + ACCOUNT_TYPE = "Smart Account"; + IS_DEPLOYED = "False"; + } + + const WITH_PAYMASTER = line.includes("WithPaymaster") ? "True" : "False"; + + const GAS_INFO = parts[4]; + const ACCESS_TYPE = GAS_INFO.split(": ")[0]; + const GAS_USED = GAS_INFO.split(": ")[1]; + + let RECEIVER_ACCESS; + if (ACCESS_TYPE === "ColdAccess") { + RECEIVER_ACCESS = "๐ŸงŠ ColdAccess"; + } else if (ACCESS_TYPE === "WarmAccess") { + RECEIVER_ACCESS = "๐Ÿ”ฅ WarmAccess"; + } else { + RECEIVER_ACCESS = "N/A"; + } + + results.push({ + PROTOCOL, + ACTION_FUNCTION, + ACCOUNT_TYPE, + IS_DEPLOYED, + WITH_PAYMASTER, + RECEIVER_ACCESS, + GAS_USED, + FULL_LOG: line.trim(), + }); } - - console.log('๐Ÿ”„ Sorting results...'); - // Custom sort: Group by protocol alphabetically, then by EOA first, Smart Account with Is Deployed=True next, then the rest - results.sort((a, b) => { - if (a.PROTOCOL < b.PROTOCOL) return -1; - if (a.PROTOCOL > b.PROTOCOL) return 1; - if (a.ACCOUNT_TYPE === 'EOA' && b.ACCOUNT_TYPE !== 'EOA') return -1; - if (a.ACCOUNT_TYPE !== 'EOA' && b.ACCOUNT_TYPE === 'EOA') return 1; - if (a.IS_DEPLOYED === 'True' && b.IS_DEPLOYED !== 'True') return -1; - if (a.IS_DEPLOYED !== 'True' && b.IS_DEPLOYED === 'True') return 1; - return 0; - }); - - console.log('๐Ÿ–‹๏ธ Writing report...'); - // Write the report - const outputStream = fs.createWriteStream(OUTPUT_FILE); - outputStream.write("# Gas Report\n"); - outputStream.write("| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Full Log** |\n"); - outputStream.write("|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:-------------:|\n"); - - results.forEach(result => { - outputStream.write(`| ${result.PROTOCOL} | ${result.ACTION_FUNCTION} | ${result.ACCOUNT_TYPE} | ${result.IS_DEPLOYED} | ${result.WITH_PAYMASTER} | ${result.RECEIVER_ACCESS} | ${result.GAS_USED} | ${result.FULL_LOG} |\n`); - }); - - console.log(`๐Ÿ“Š Gas report generated and saved to ${OUTPUT_FILE}`); + } + + console.log("๐Ÿ”„ Sorting results..."); + // Custom sort: Group by protocol alphabetically, then by EOA first, Smart Account with Is Deployed=True next, then the rest + results.sort((a, b) => { + if (a.PROTOCOL < b.PROTOCOL) return -1; + if (a.PROTOCOL > b.PROTOCOL) return 1; + if (a.ACCOUNT_TYPE === "EOA" && b.ACCOUNT_TYPE !== "EOA") return -1; + if (a.ACCOUNT_TYPE !== "EOA" && b.ACCOUNT_TYPE === "EOA") return 1; + if (a.IS_DEPLOYED === "True" && b.IS_DEPLOYED !== "True") return -1; + if (a.IS_DEPLOYED !== "True" && b.IS_DEPLOYED === "True") return 1; + return 0; + }); + + console.log("๐Ÿ–‹๏ธ Writing report..."); + // Write the report + const outputStream = fs.createWriteStream(OUTPUT_FILE); + outputStream.write("# Gas Report\n"); + outputStream.write( + "| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Full Log** |\n", + ); + outputStream.write( + "|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:-------------:|\n", + ); + + results.forEach((result) => { + outputStream.write( + `| ${result.PROTOCOL} | ${result.ACTION_FUNCTION} | ${result.ACCOUNT_TYPE} | ${result.IS_DEPLOYED} | ${result.WITH_PAYMASTER} | ${result.RECEIVER_ACCESS} | ${result.GAS_USED} | ${result.FULL_LOG} |\n`, + ); + }); + + console.log(`๐Ÿ“Š Gas report generated and saved to ${OUTPUT_FILE}`); } // Function to clean up temporary files function cleanUp() { - fs.unlink(LOG_FILE, (err) => { - if (err) console.error(`โŒ Error deleting ${LOG_FILE}: ${err}`); - else console.log(`๐Ÿ—‘๏ธ ${LOG_FILE} deleted successfully.`); - }); + fs.unlink(LOG_FILE, (err) => { + if (err) console.error(`โŒ Error deleting ${LOG_FILE}: ${err}`); + else console.log(`๐Ÿ—‘๏ธ ${LOG_FILE} deleted successfully.`); + }); } // Run the function to generate the report and then clean up -generateReport() - .then(cleanUp) - .catch(console.error); +generateReport().then(cleanUp).catch(console.error); diff --git a/test/foundry/fork/base/TestNexusSwapETH_Integration.t.sol b/test/foundry/fork/base/TestNexusSwapETH_Integration.t.sol index 00b442f4..1e5c40bc 100644 --- a/test/foundry/fork/base/TestNexusSwapETH_Integration.t.sol +++ b/test/foundry/fork/base/TestNexusSwapETH_Integration.t.sol @@ -208,46 +208,45 @@ contract TestNexusSwapETH_Integration is BaseSettings { } /// @notice Tests gas consumption for swapping ETH for USDC using a deployed Nexus account with Paymaster -function test_Gas_Swap_DeployedNexus_SwapEthForTokens_WithPaymaster() - public - checkERC20Balance(preComputedAddress, SWAP_AMOUNT) - checkPaymasterBalance(address(paymaster)) -{ - // Prepare the swap execution details - Execution[] memory executions = prepareSingleExecution( - address(uniswapV2Router), // Uniswap V2 Router address - SWAP_AMOUNT, // Amount of ETH to swap - abi.encodeWithSignature( - "swapExactETHForTokens(uint256,address[],address,uint256)", // Function signature - 0, // Minimum amount of tokens to receive (set to 0 for simplicity) - getPathForETHtoUSDC(), // Path for the swap (ETH to USDC) - preComputedAddress, // Recipient of the USDC - block.timestamp // Deadline for the swap - ) - ); - - // Deploy the Nexus account - Nexus deployedNexus = deployNexus(user, 100 ether, address(VALIDATOR_MODULE)); - - // Build the PackedUserOperation array - PackedUserOperation[] memory userOps = buildPackedUserOperation( - user, // Wallet initiating the operation - deployedNexus, // Deployed Nexus account - EXECTYPE_DEFAULT, // Execution type - executions, // Execution details - address(VALIDATOR_MODULE) // Validator module address - ); - - // Generate and sign paymaster data - userOps[0].paymasterAndData = generateAndSignPaymasterData(userOps[0], BUNDLER, paymaster); - - // Sign the entire user operation with the user's wallet - userOps[0].signature = signUserOp(user, userOps[0]); - - // Measure and log gas usage for the operation - measureAndLogGas("UniswapV2::swapExactETHForTokens::Nexus::WithPaymaster::N/A", userOps); -} + function test_Gas_Swap_DeployedNexus_SwapEthForTokens_WithPaymaster() + public + checkERC20Balance(preComputedAddress, SWAP_AMOUNT) + checkPaymasterBalance(address(paymaster)) + { + // Prepare the swap execution details + Execution[] memory executions = prepareSingleExecution( + address(uniswapV2Router), // Uniswap V2 Router address + SWAP_AMOUNT, // Amount of ETH to swap + abi.encodeWithSignature( + "swapExactETHForTokens(uint256,address[],address,uint256)", // Function signature + 0, // Minimum amount of tokens to receive (set to 0 for simplicity) + getPathForETHtoUSDC(), // Path for the swap (ETH to USDC) + preComputedAddress, // Recipient of the USDC + block.timestamp // Deadline for the swap + ) + ); + // Deploy the Nexus account + Nexus deployedNexus = deployNexus(user, 100 ether, address(VALIDATOR_MODULE)); + + // Build the PackedUserOperation array + PackedUserOperation[] memory userOps = buildPackedUserOperation( + user, // Wallet initiating the operation + deployedNexus, // Deployed Nexus account + EXECTYPE_DEFAULT, // Execution type + executions, // Execution details + address(VALIDATOR_MODULE) // Validator module address + ); + + // Generate and sign paymaster data + userOps[0].paymasterAndData = generateAndSignPaymasterData(userOps[0], BUNDLER, paymaster); + + // Sign the entire user operation with the user's wallet + userOps[0].signature = signUserOp(user, userOps[0]); + + // Measure and log gas usage for the operation + measureAndLogGas("UniswapV2::swapExactETHForTokens::Nexus::WithPaymaster::N/A", userOps); + } /// @notice Helper function to get the path for ETH to USDC swap /// @return path The array containing the swap path diff --git a/test/foundry/fork/base/TestNexusSwapWETH_Integration.t.sol b/test/foundry/fork/base/TestNexusSwapWETH_Integration.t.sol index 97f68e12..92a6fd6f 100644 --- a/test/foundry/fork/base/TestNexusSwapWETH_Integration.t.sol +++ b/test/foundry/fork/base/TestNexusSwapWETH_Integration.t.sol @@ -332,50 +332,43 @@ contract TestNexusSwapWETH_Integration is BaseSettings { } /// @notice Tests gas consumption for swapping WETH for USDC using a deployed Nexus account with Paymaster -function test_Gas_Swap_DeployedNexus_SwapWethForTokens_WithPaymaster() - public - checkERC20Balance(preComputedAddress) - checkPaymasterBalance(address(paymaster)) -{ - // Approve WETH transfer for precomputed address - vm.startPrank(preComputedAddress); - weth.approve(address(uniswapV2Router), SWAP_AMOUNT); - vm.stopPrank(); - - Execution[] memory executions = prepareSingleExecution( - address(uniswapV2Router), - 0, - abi.encodeWithSignature( - "swapExactTokensForTokens(uint256,uint256,address[],address,uint256)", - SWAP_AMOUNT, + function test_Gas_Swap_DeployedNexus_SwapWethForTokens_WithPaymaster() + public + checkERC20Balance(preComputedAddress) + checkPaymasterBalance(address(paymaster)) + { + // Approve WETH transfer for precomputed address + vm.startPrank(preComputedAddress); + weth.approve(address(uniswapV2Router), SWAP_AMOUNT); + vm.stopPrank(); + + Execution[] memory executions = prepareSingleExecution( + address(uniswapV2Router), 0, - getPathForWETHtoUSDC(), - preComputedAddress, - block.timestamp - ) - ); - - // Deploy the Nexus account - Nexus deployedNexus = deployNexus(user, 10 ether, address(VALIDATOR_MODULE)); - - // Build the PackedUserOperation array - PackedUserOperation[] memory userOps = buildPackedUserOperation( - user, - deployedNexus, - EXECTYPE_DEFAULT, - executions, - address(VALIDATOR_MODULE) - ); - - // Generate and sign paymaster data - userOps[0].paymasterAndData = generateAndSignPaymasterData(userOps[0], BUNDLER, paymaster); - - // Sign the user operation - userOps[0].signature = signUserOp(user, userOps[0]); - - measureAndLogGas("UniswapV2::swapExactTokensForTokens::Nexus::WithPaymaster::N/A", userOps); -} + abi.encodeWithSignature( + "swapExactTokensForTokens(uint256,uint256,address[],address,uint256)", + SWAP_AMOUNT, + 0, + getPathForWETHtoUSDC(), + preComputedAddress, + block.timestamp + ) + ); + + // Deploy the Nexus account + Nexus deployedNexus = deployNexus(user, 10 ether, address(VALIDATOR_MODULE)); + // Build the PackedUserOperation array + PackedUserOperation[] memory userOps = buildPackedUserOperation(user, deployedNexus, EXECTYPE_DEFAULT, executions, address(VALIDATOR_MODULE)); + + // Generate and sign paymaster data + userOps[0].paymasterAndData = generateAndSignPaymasterData(userOps[0], BUNDLER, paymaster); + + // Sign the user operation + userOps[0].signature = signUserOp(user, userOps[0]); + + measureAndLogGas("UniswapV2::swapExactTokensForTokens::Nexus::WithPaymaster::N/A", userOps); + } /// @notice Helper function to get the path for WETH to USDC swap /// @return path The array containing the swap path diff --git a/test/foundry/unit/concrete/fallback/TestNexus_FallbackFunction.t.sol b/test/foundry/unit/concrete/fallback/TestNexus_FallbackFunction.t.sol index 95eb7c3d..f8b68ffe 100644 --- a/test/foundry/unit/concrete/fallback/TestNexus_FallbackFunction.t.sol +++ b/test/foundry/unit/concrete/fallback/TestNexus_FallbackFunction.t.sol @@ -41,7 +41,7 @@ contract TestNexus_FallbackFunction is TestModuleManagement_Base { // Decode and verify the return data bytes32 result = abi.decode(returnData, (bytes32)); -assertEq(result, keccak256("SUCCESS")); + assertEq(result, keccak256("SUCCESS")); } /// @notice Tests successful single call through the fallback handler. From d8e1252e264234e12e2255cc60e17a4c117fe374 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Wed, 29 May 2024 18:42:39 +0400 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=94=92=20Improve=20security=20on=20fa?= =?UTF-8?q?llback=20handler=20installation=20process?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/base/ModuleManager.sol | 22 ++++++++- .../base/IModuleManagerEventsAndErrors.sol | 3 ++ .../TestModuleManager_FallbackHandler.t.sol | 46 +++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/contracts/base/ModuleManager.sol b/contracts/base/ModuleManager.sol index 198d37f7..1e6d5d61 100644 --- a/contracts/base/ModuleManager.sol +++ b/contracts/base/ModuleManager.sol @@ -213,11 +213,31 @@ contract ModuleManager is Storage, Receiver, IModuleManagerEventsAndErrors { /// @param handler The address of the fallback handler to install. /// @param params The initialization parameters including the selector and call type. function _installFallbackHandler(address handler, bytes calldata params) internal virtual { + // Extracting the function selector from the parameters bytes4 selector = bytes4(params[0:4]); + + // Extracting the call type from the parameters CallType calltype = CallType.wrap(bytes1(params[4])); + + // Extracting the initialization data from the parameters bytes memory initData = params[5:]; - if (_isFallbackHandlerInstalled(selector)) revert FallbackAlreadyInstalledForSelector(selector); + + // Revert if the selector is either `onInstall(bytes)` (0x6d61fe70) or `onUninstall(bytes)` (0x8a91b0e3) + // These selectors are forbidden as they can lead to security vulnerabilities + // and unexpected behavior during fallback handler installation. + if (selector == bytes4(0x6d61fe70) || selector == bytes4(0x8a91b0e3)) { + revert FallbackSelectorForbidden(); + } + + // Revert if a fallback handler is already installed for the given selector + if (_isFallbackHandlerInstalled(selector)) { + revert FallbackAlreadyInstalledForSelector(selector); + } + + // Store the fallback handler and its call type in the account storage _getAccountStorage().fallbacks[selector] = FallbackHandler(handler, calltype); + + // Invoke the `onInstall` function of the fallback handler with the provided initialization data IFallback(handler).onInstall(initData); } diff --git a/contracts/interfaces/base/IModuleManagerEventsAndErrors.sol b/contracts/interfaces/base/IModuleManagerEventsAndErrors.sol index a9926ada..bd205515 100644 --- a/contracts/interfaces/base/IModuleManagerEventsAndErrors.sol +++ b/contracts/interfaces/base/IModuleManagerEventsAndErrors.sol @@ -69,4 +69,7 @@ interface IModuleManagerEventsAndErrors { /// @dev Thrown when no fallback handler is available for a given selector. error MissingFallbackHandler(bytes4 selector); + + /// @dev Thrown when there is an attempt to install a forbidden selector as a fallback handler. + error FallbackSelectorForbidden(); } diff --git a/test/foundry/unit/concrete/modulemanager/TestModuleManager_FallbackHandler.t.sol b/test/foundry/unit/concrete/modulemanager/TestModuleManager_FallbackHandler.t.sol index f6225b9f..8c18a3ef 100644 --- a/test/foundry/unit/concrete/modulemanager/TestModuleManager_FallbackHandler.t.sol +++ b/test/foundry/unit/concrete/modulemanager/TestModuleManager_FallbackHandler.t.sol @@ -220,4 +220,50 @@ contract TestModuleManager_FallbackHandler is TestModuleManagement_Base { // Assert that the fetched handler address matches the expected handler module address assertEq(handlerAddress, address(HANDLER_MODULE), "getActiveHookHandlerBySelector returned incorrect handler address"); } + + /// @notice Tests reversion when attempting to install the forbidden onInstall selector as a fallback handler. + function test_RevertIf_InstallForbiddenOnInstallSelector() public { + bytes memory customData = abi.encode(bytes5(abi.encodePacked(bytes4(0x6d61fe70), CALLTYPE_SINGLE))); // onInstall selector + bytes memory callData = abi.encodeWithSelector( + IModuleManager.installModule.selector, + MODULE_TYPE_FALLBACK, + address(HANDLER_MODULE), + customData + ); + Execution[] memory execution = new Execution[](1); + execution[0] = Execution(address(BOB_ACCOUNT), 0, callData); + PackedUserOperation[] memory userOps = buildPackedUserOperation(BOB, BOB_ACCOUNT, EXECTYPE_DEFAULT, execution, address(VALIDATOR_MODULE)); + + // Expect UserOperationRevertReason event due to forbidden selector + bytes32 userOpHash = ENTRYPOINT.getUserOpHash(userOps[0]); + bytes memory expectedRevertReason = abi.encodeWithSignature("FallbackSelectorForbidden()"); + + vm.expectEmit(true, true, true, true); + emit UserOperationRevertReason(userOpHash, address(BOB_ACCOUNT), userOps[0].nonce, expectedRevertReason); + + ENTRYPOINT.handleOps(userOps, payable(address(BOB.addr))); + } + + /// @notice Tests reversion when attempting to install the forbidden onUninstall selector as a fallback handler. + function test_RevertIf_InstallForbiddenOnUninstallSelector() public { + bytes memory customData = abi.encode(bytes5(abi.encodePacked(bytes4(0x8a91b0e3), CALLTYPE_SINGLE))); // onUninstall selector + bytes memory callData = abi.encodeWithSelector( + IModuleManager.installModule.selector, + MODULE_TYPE_FALLBACK, + address(HANDLER_MODULE), + customData + ); + Execution[] memory execution = new Execution[](1); + execution[0] = Execution(address(BOB_ACCOUNT), 0, callData); + PackedUserOperation[] memory userOps = buildPackedUserOperation(BOB, BOB_ACCOUNT, EXECTYPE_DEFAULT, execution, address(VALIDATOR_MODULE)); + + // Expect UserOperationRevertReason event due to forbidden selector + bytes32 userOpHash = ENTRYPOINT.getUserOpHash(userOps[0]); + bytes memory expectedRevertReason = abi.encodeWithSignature("FallbackSelectorForbidden()"); + + vm.expectEmit(true, true, true, true); + emit UserOperationRevertReason(userOpHash, address(BOB_ACCOUNT), userOps[0].nonce, expectedRevertReason); + + ENTRYPOINT.handleOps(userOps, payable(address(BOB.addr))); + } } From 2ced21b0f5a9c0a5f35e2e0d70008ae4356a0ab7 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Wed, 29 May 2024 18:49:31 +0400 Subject: [PATCH 3/9] Update gas report file name to uppercase + run prettier --- scripts/foundry/generateGasReport.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/scripts/foundry/generateGasReport.js b/scripts/foundry/generateGasReport.js index 01bb4a96..06207b44 100644 --- a/scripts/foundry/generateGasReport.js +++ b/scripts/foundry/generateGasReport.js @@ -4,7 +4,7 @@ const { exec } = require("child_process"); // Define the log file and the output markdown file const LOG_FILE = "gas.log"; -const OUTPUT_FILE = "gas_report.md"; +const OUTPUT_FILE = "GAS_REPORT.md"; // Function to execute the `forge test` command function runForgeTest() { @@ -111,6 +111,19 @@ async function generateReport() { }); console.log(`๐Ÿ“Š Gas report generated and saved to ${OUTPUT_FILE}`); + + // Run prettier to format the generated markdown file + return new Promise((resolve, reject) => { + console.log("โœจ Running prettier to format the gas report..."); + exec(`npx prettier --write ${OUTPUT_FILE}`, (error, stdout, stderr) => { + if (error) { + console.error(`โŒ Prettier error: ${error}`); + reject(`prettier error: ${error}`); + } + console.log("โœ… Prettier formatting completed."); + resolve(stdout ? stdout : stderr); + }); + }); } // Function to clean up temporary files @@ -121,5 +134,7 @@ function cleanUp() { }); } -// Run the function to generate the report and then clean up -generateReport().then(cleanUp).catch(console.error); +// Run the function to generate the report, format it with prettier, and then clean up +generateReport() + .then(cleanUp) + .catch(console.error); From dd221600acecf185fe13039609e7074e8f862a6d Mon Sep 17 00:00:00 2001 From: aboudjem Date: Wed, 29 May 2024 18:56:31 +0400 Subject: [PATCH 4/9] feat: Update gas report file name to uppercase --- gas_report.md | 115 +++++++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 57 deletions(-) diff --git a/gas_report.md b/gas_report.md index 6d3aee37..e6b5767e 100644 --- a/gas_report.md +++ b/gas_report.md @@ -1,58 +1,59 @@ # Gas Report -| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Full Log** | -|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:-------------:| -| ERC20 | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 25221 | ERC20::transfer::EOA::Simple::WarmAccess: 25221 | -| ERC20 | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 49921 | ERC20::transfer::EOA::Simple::ColdAccess: 49921 | -| ERC20 | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 74855 | ERC20::transfer::Nexus::Deployed::WarmAccess: 74855 | -| ERC20 | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 91351 | ERC20::transfer::Nexus::WithPaymaster::WarmAccess: 91351 | -| ERC20 | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 94755 | ERC20::transfer::Nexus::Deployed::ColdAccess: 94755 | -| ERC20 | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 111250 | ERC20::transfer::Nexus::WithPaymaster::ColdAccess: 111250 | -| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 347244 | ERC20::transfer::Setup And Call::Using Pre-Funded Ether::WarmAccess: 347244 | -| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 299140 | ERC20::transfer::Setup And Call::UsingDeposit::WarmAccess: 299140 | -| ERC20 | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 315950 | ERC20::transfer::Setup And Call::WithPaymaster::WarmAccess: 315950 | -| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 367144 | ERC20::transfer::Setup And Call::Using Pre-Funded Ether::ColdAccess: 367144 | -| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 319039 | ERC20::transfer::Setup And Call::UsingDeposit::ColdAccess: 319039 | -| ERC20 | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 335849 | ERC20::transfer::Setup And Call::WithPaymaster::ColdAccess: 335849 | -| ERC721 | transferFrom | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28583 | ERC721::transferFrom::EOA::Simple::WarmAccess: 28583 | -| ERC721 | transferFrom | EOA | False | False | ๐ŸงŠ ColdAccess | 48483 | ERC721::transferFrom::EOA::Simple::ColdAccess: 48483 | -| ERC721 | transferFrom | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 78342 | ERC721::transferFrom::Nexus::Deployed::WarmAccess: 78342 | -| ERC721 | transferFrom | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94865 | ERC721::transferFrom::Nexus::WithPaymaster::WarmAccess: 94865 | -| ERC721 | transferFrom | Smart Account | True | False | ๐ŸงŠ ColdAccess | 98242 | ERC721::transferFrom::Nexus::Deployed::ColdAccess: 98242 | -| ERC721 | transferFrom | Smart Account | True | True | ๐ŸงŠ ColdAccess | 114765 | ERC721::transferFrom::Nexus::WithPaymaster::ColdAccess: 114765 | -| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345947 | ERC721::transferFrom::Setup And Call::Using Pre-Funded Ether::WarmAccess: 345947 | -| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297843 | ERC721::transferFrom::Setup And Call::UsingDeposit::WarmAccess: 297843 | -| ERC721 | transferFrom | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 314652 | ERC721::transferFrom::Setup And Call::WithPaymaster::WarmAccess: 314652 | -| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 365847 | ERC721::transferFrom::Setup And Call::Using Pre-Funded Ether::ColdAccess: 365847 | -| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 317743 | ERC721::transferFrom::Setup And Call::UsingDeposit::ColdAccess: 317743 | -| ERC721 | transferFrom | Smart Account | False | True | ๐ŸงŠ ColdAccess | 334552 | ERC721::transferFrom::Setup And Call::WithPaymaster::ColdAccess: 334552 | -| ETH | call | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | ETH::call::EOA::Simple::WarmAccess: 28201 | -| ETH | send | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | ETH::send::EOA::Simple::WarmAccess: 28201 | -| ETH | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28073 | ETH::transfer::EOA::Simple::WarmAccess: 28073 | -| ETH | call | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | ETH::call::EOA::Simple::ColdAccess: 53201 | -| ETH | send | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | ETH::send::EOA::Simple::ColdAccess: 53201 | -| ETH | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 53073 | ETH::transfer::EOA::Simple::ColdAccess: 53073 | -| ETH | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 77604 | ETH::transfer::Nexus::Deployed::WarmAccess: 77604 | -| ETH | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94089 | ETH::transfer::Nexus::WithPaymaster::WarmAccess: 94089 | -| ETH | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 102604 | ETH::transfer::Nexus::Deployed::ColdAccess: 102604 | -| ETH | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 119089 | ETH::transfer::Nexus::WithPaymaster::ColdAccess: 119089 | -| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345181 | ETH::transfer::Setup And Call::Using Pre-Funded Ether::WarmAccess: 345181 | -| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297076 | ETH::transfer::Setup And Call::UsingDeposit::WarmAccess: 297076 | -| ETH | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 313864 | ETH::transfer::Setup And Call::WithPaymaster::WarmAccess: 313864 | -| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 370181 | ETH::transfer::Setup And Call::Using Pre-Funded Ether::ColdAccess: 370181 | -| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 322076 | ETH::transfer::Setup And Call::UsingDeposit::ColdAccess: 322076 | -| ETH | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 338864 | ETH::transfer::Setup And Call::WithPaymaster::ColdAccess: 338864 | -| UniswapV2 | swapExactETHForTokens | EOA | False | False | N/A | 149263 | UniswapV2::swapExactETHForTokens::EOA::ETHtoUSDC::N/A: 149263 | -| UniswapV2 | swapExactTokensForTokens | EOA | False | False | N/A | 118252 | UniswapV2::swapExactTokensForTokens::EOA::WETHtoUSDC::N/A: 118252 | -| UniswapV2 | swapExactETHForTokens | Smart Account | True | False | N/A | 199230 | UniswapV2::swapExactETHForTokens::Nexus::Deployed::N/A: 199230 | -| UniswapV2 | swapExactETHForTokens | Smart Account | True | True | N/A | 215793 | UniswapV2::swapExactETHForTokens::Nexus::WithPaymaster::N/A: 215793 | -| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | True | False | N/A | 200205 | UniswapV2::approve+swapExactTokensForTokens::Nexus::Deployed::N/A: 200205 | -| UniswapV2 | swapExactTokensForTokens | Smart Account | True | False | N/A | 168209 | UniswapV2::swapExactTokensForTokens::Nexus::Deployed::N/A: 168209 | -| UniswapV2 | swapExactTokensForTokens | Smart Account | True | True | N/A | 184784 | UniswapV2::swapExactTokensForTokens::Nexus::WithPaymaster::N/A: 184784 | -| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 418733 | UniswapV2::swapExactETHForTokens::Setup And Call::UsingDeposit::N/A: 418733 | -| UniswapV2 | swapExactETHForTokens | Smart Account | False | True | N/A | 435614 | UniswapV2::swapExactETHForTokens::Setup And Call::WithPaymaster::N/A: 435614 | -| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 466838 | UniswapV2::swapExactETHForTokens::Setup And Call::Using Pre-Funded Ether::N/A: 466838 | -| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 419709 | UniswapV2::approve+swapExactTokensForTokens::Setup And Call::UsingDeposit::N/A: 419709 | -| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | True | N/A | 436780 | UniswapV2::approve+swapExactTokensForTokens::Setup And Call::WithPaymaster::N/A: 436780 | -| UniswapV2 | swapExactTokensForTokens | Smart Account | False | False | N/A | 387700 | UniswapV2::swapExactTokensForTokens::Setup And Call::UsingDeposit::N/A: 387700 | -| UniswapV2 | swapExactTokensForTokens | Smart Account | False | True | N/A | 404582 | UniswapV2::swapExactTokensForTokens::Setup And Call::WithPaymaster::N/A: 404582 | -| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 467815 | UniswapV2::approve+swapExactTokensForTokens::Setup And Call::Using Pre-Funded Ether::N/A: 467815 | + +| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Full Log** | +| :----------: | :------------------------------: | :--------------: | :-------------: | :-----------------: | :-----------------: | :----------: | :----------------------------------------------------------------------------------------------: | +| ERC20 | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 49921 | ERC20::transfer::EOA::Simple::ColdAccess: 49921 | +| ERC20 | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 25221 | ERC20::transfer::EOA::Simple::WarmAccess: 25221 | +| ERC20 | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 94767 | ERC20::transfer::Nexus::Deployed::ColdAccess: 94767 | +| ERC20 | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 111262 | ERC20::transfer::Nexus::WithPaymaster::ColdAccess: 111262 | +| ERC20 | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 74867 | ERC20::transfer::Nexus::Deployed::WarmAccess: 74867 | +| ERC20 | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 91363 | ERC20::transfer::Nexus::WithPaymaster::WarmAccess: 91363 | +| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 367156 | ERC20::transfer::Setup And Call::Using Pre-Funded Ether::ColdAccess: 367156 | +| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 319051 | ERC20::transfer::Setup And Call::UsingDeposit::ColdAccess: 319051 | +| ERC20 | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 335861 | ERC20::transfer::Setup And Call::WithPaymaster::ColdAccess: 335861 | +| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 347256 | ERC20::transfer::Setup And Call::Using Pre-Funded Ether::WarmAccess: 347256 | +| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 299152 | ERC20::transfer::Setup And Call::UsingDeposit::WarmAccess: 299152 | +| ERC20 | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 315962 | ERC20::transfer::Setup And Call::WithPaymaster::WarmAccess: 315962 | +| ERC721 | transferFrom | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28583 | ERC721::transferFrom::EOA::Simple::WarmAccess: 28583 | +| ERC721 | transferFrom | EOA | False | False | ๐ŸงŠ ColdAccess | 48483 | ERC721::transferFrom::EOA::Simple::ColdAccess: 48483 | +| ERC721 | transferFrom | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 78354 | ERC721::transferFrom::Nexus::Deployed::WarmAccess: 78354 | +| ERC721 | transferFrom | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94877 | ERC721::transferFrom::Nexus::WithPaymaster::WarmAccess: 94877 | +| ERC721 | transferFrom | Smart Account | True | False | ๐ŸงŠ ColdAccess | 98254 | ERC721::transferFrom::Nexus::Deployed::ColdAccess: 98254 | +| ERC721 | transferFrom | Smart Account | True | True | ๐ŸงŠ ColdAccess | 114777 | ERC721::transferFrom::Nexus::WithPaymaster::ColdAccess: 114777 | +| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345959 | ERC721::transferFrom::Setup And Call::Using Pre-Funded Ether::WarmAccess: 345959 | +| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297855 | ERC721::transferFrom::Setup And Call::UsingDeposit::WarmAccess: 297855 | +| ERC721 | transferFrom | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 314664 | ERC721::transferFrom::Setup And Call::WithPaymaster::WarmAccess: 314664 | +| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 365859 | ERC721::transferFrom::Setup And Call::Using Pre-Funded Ether::ColdAccess: 365859 | +| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 317755 | ERC721::transferFrom::Setup And Call::UsingDeposit::ColdAccess: 317755 | +| ERC721 | transferFrom | Smart Account | False | True | ๐ŸงŠ ColdAccess | 334564 | ERC721::transferFrom::Setup And Call::WithPaymaster::ColdAccess: 334564 | +| ETH | call | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | ETH::call::EOA::Simple::ColdAccess: 53201 | +| ETH | send | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | ETH::send::EOA::Simple::ColdAccess: 53201 | +| ETH | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 53073 | ETH::transfer::EOA::Simple::ColdAccess: 53073 | +| ETH | call | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | ETH::call::EOA::Simple::WarmAccess: 28201 | +| ETH | send | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | ETH::send::EOA::Simple::WarmAccess: 28201 | +| ETH | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28073 | ETH::transfer::EOA::Simple::WarmAccess: 28073 | +| ETH | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 102616 | ETH::transfer::Nexus::Deployed::ColdAccess: 102616 | +| ETH | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 119101 | ETH::transfer::Nexus::WithPaymaster::ColdAccess: 119101 | +| ETH | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 77616 | ETH::transfer::Nexus::Deployed::WarmAccess: 77616 | +| ETH | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94101 | ETH::transfer::Nexus::WithPaymaster::WarmAccess: 94101 | +| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 370193 | ETH::transfer::Setup And Call::Using Pre-Funded Ether::ColdAccess: 370193 | +| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 322088 | ETH::transfer::Setup And Call::UsingDeposit::ColdAccess: 322088 | +| ETH | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 338876 | ETH::transfer::Setup And Call::WithPaymaster::ColdAccess: 338876 | +| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345193 | ETH::transfer::Setup And Call::Using Pre-Funded Ether::WarmAccess: 345193 | +| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297088 | ETH::transfer::Setup And Call::UsingDeposit::WarmAccess: 297088 | +| ETH | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 313876 | ETH::transfer::Setup And Call::WithPaymaster::WarmAccess: 313876 | +| UniswapV2 | swapExactETHForTokens | EOA | False | False | N/A | 149263 | UniswapV2::swapExactETHForTokens::EOA::ETHtoUSDC::N/A: 149263 | +| UniswapV2 | swapExactTokensForTokens | EOA | False | False | N/A | 118252 | UniswapV2::swapExactTokensForTokens::EOA::WETHtoUSDC::N/A: 118252 | +| UniswapV2 | swapExactETHForTokens | Smart Account | True | False | N/A | 199242 | UniswapV2::swapExactETHForTokens::Nexus::Deployed::N/A: 199242 | +| UniswapV2 | swapExactETHForTokens | Smart Account | True | True | N/A | 215805 | UniswapV2::swapExactETHForTokens::Nexus::WithPaymaster::N/A: 215805 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | True | False | N/A | 200217 | UniswapV2::approve+swapExactTokensForTokens::Nexus::Deployed::N/A: 200217 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | True | False | N/A | 168221 | UniswapV2::swapExactTokensForTokens::Nexus::Deployed::N/A: 168221 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | True | True | N/A | 184796 | UniswapV2::swapExactTokensForTokens::Nexus::WithPaymaster::N/A: 184796 | +| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 418745 | UniswapV2::swapExactETHForTokens::Setup And Call::UsingDeposit::N/A: 418745 | +| UniswapV2 | swapExactETHForTokens | Smart Account | False | True | N/A | 435626 | UniswapV2::swapExactETHForTokens::Setup And Call::WithPaymaster::N/A: 435626 | +| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 466850 | UniswapV2::swapExactETHForTokens::Setup And Call::Using Pre-Funded Ether::N/A: 466850 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 419721 | UniswapV2::approve+swapExactTokensForTokens::Setup And Call::UsingDeposit::N/A: 419721 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | True | N/A | 436792 | UniswapV2::approve+swapExactTokensForTokens::Setup And Call::WithPaymaster::N/A: 436792 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | False | False | N/A | 387712 | UniswapV2::swapExactTokensForTokens::Setup And Call::UsingDeposit::N/A: 387712 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | False | True | N/A | 404594 | UniswapV2::swapExactTokensForTokens::Setup And Call::WithPaymaster::N/A: 404594 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 467827 | UniswapV2::approve+swapExactTokensForTokens::Setup And Call::Using Pre-Funded Ether::N/A: 467827 | From 6d09a7b781280595e25cda7b097c2294d5a6ac6b Mon Sep 17 00:00:00 2001 From: aboudjem Date: Wed, 29 May 2024 19:00:20 +0400 Subject: [PATCH 5/9] chore: Update CI workflow to trigger only on pull requests --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03af01ac..0648e5cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ name: Unified CI Workflow -on: [push, pull_request] +on: pull_request permissions: write-all From ae249db733f97d8d263755966dd9544d24584200 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Fri, 31 May 2024 18:58:44 +0400 Subject: [PATCH 6/9] chore: Improve fallback handler comments --- contracts/base/ModuleManager.sol | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/contracts/base/ModuleManager.sol b/contracts/base/ModuleManager.sol index 1e6d5d61..98564e2c 100644 --- a/contracts/base/ModuleManager.sol +++ b/contracts/base/ModuleManager.sol @@ -213,31 +213,37 @@ contract ModuleManager is Storage, Receiver, IModuleManagerEventsAndErrors { /// @param handler The address of the fallback handler to install. /// @param params The initialization parameters including the selector and call type. function _installFallbackHandler(address handler, bytes calldata params) internal virtual { - // Extracting the function selector from the parameters + // Extract the function selector from the provided parameters. bytes4 selector = bytes4(params[0:4]); - // Extracting the call type from the parameters + // Extract the call type from the provided parameters. CallType calltype = CallType.wrap(bytes1(params[4])); - // Extracting the initialization data from the parameters + // Extract the initialization data from the provided parameters. bytes memory initData = params[5:]; - // Revert if the selector is either `onInstall(bytes)` (0x6d61fe70) or `onUninstall(bytes)` (0x8a91b0e3) - // These selectors are forbidden as they can lead to security vulnerabilities - // and unexpected behavior during fallback handler installation. + // Revert if the selector is either `onInstall(bytes)` (0x6d61fe70) or `onUninstall(bytes)` (0x8a91b0e3). + // These selectors are explicitly forbidden to prevent security vulnerabilities. + // Allowing these selectors would enable unauthorized users to uninstall and reinstall critical modules. + // If a validator module is uninstalled and reinstalled without proper authorization, it can compromise + // the account's security and integrity. By restricting these selectors, we ensure that the fallback handler + // cannot be manipulated to disrupt the expected behavior and security of the account. if (selector == bytes4(0x6d61fe70) || selector == bytes4(0x8a91b0e3)) { revert FallbackSelectorForbidden(); } - // Revert if a fallback handler is already installed for the given selector + // Revert if a fallback handler is already installed for the given selector. + // This check ensures that we do not overwrite an existing fallback handler, which could lead to unexpected behavior. if (_isFallbackHandlerInstalled(selector)) { revert FallbackAlreadyInstalledForSelector(selector); } - // Store the fallback handler and its call type in the account storage + // Store the fallback handler and its call type in the account storage. + // This maps the function selector to the specified fallback handler and call type. _getAccountStorage().fallbacks[selector] = FallbackHandler(handler, calltype); - // Invoke the `onInstall` function of the fallback handler with the provided initialization data + // Invoke the `onInstall` function of the fallback handler with the provided initialization data. + // This step allows the fallback handler to perform any necessary setup or initialization. IFallback(handler).onInstall(initData); } From 9e25afd44c050f9b64f0d8a696e843d48c7d47b4 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Sat, 1 Jun 2024 19:04:44 +0400 Subject: [PATCH 7/9] refactor: Update gas report script paths and improve generation --- GAS_REPORT.md | 58 --------------------------------------------------- 1 file changed, 58 deletions(-) delete mode 100644 GAS_REPORT.md diff --git a/GAS_REPORT.md b/GAS_REPORT.md deleted file mode 100644 index 220a96e7..00000000 --- a/GAS_REPORT.md +++ /dev/null @@ -1,58 +0,0 @@ -# Gas Report -| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Gas Difference** | -|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:------------------:| -| ERC20 | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 49921 | 0 | -| ERC20 | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 25221 | 0 | -| ERC20 | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 94767 | 0 | -| ERC20 | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 74867 | 0 | -| ERC20 | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 335883 | 0 | -| ERC20 | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 315984 | 0 | -| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 319073 | 0 | -| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 299174 | 0 | -| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 367178 | 0 | -| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 347278 | 0 | -| ERC20 | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 111262 | 0 | -| ERC20 | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 91363 | 0 | -| ERC721 | transferFrom | EOA | False | False | ๐ŸงŠ ColdAccess | 48483 | 0 | -| ERC721 | transferFrom | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28583 | 0 | -| ERC721 | transferFrom | Smart Account | True | False | ๐ŸงŠ ColdAccess | 98254 | 0 | -| ERC721 | transferFrom | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 78354 | 0 | -| ERC721 | transferFrom | Smart Account | False | True | ๐ŸงŠ ColdAccess | 334585 | 0 | -| ERC721 | transferFrom | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 314685 | 0 | -| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 317777 | 0 | -| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297877 | 0 | -| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 365881 | 0 | -| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345981 | 0 | -| ERC721 | transferFrom | Smart Account | True | True | ๐ŸงŠ ColdAccess | 114777 | 0 | -| ERC721 | transferFrom | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94877 | 0 | -| ETH | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 53073 | 0 | -| ETH | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28073 | 0 | -| ETH | call | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | 0 | -| ETH | call | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | 0 | -| ETH | send | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | 0 | -| ETH | send | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | 0 | -| ETH | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 102616 | 0 | -| ETH | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 77616 | 0 | -| ETH | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 338898 | 0 | -| ETH | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 313898 | 0 | -| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 322110 | 0 | -| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297110 | 0 | -| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 370215 | 0 | -| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345215 | 0 | -| ETH | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 119101 | 0 | -| ETH | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94101 | 0 | -| UniswapV2 | swapExactETHForTokens | EOA | False | False | N/A | 149263 | 0 | -| UniswapV2 | swapExactETHForTokens | Smart Account | True | False | N/A | 199242 | 0 | -| UniswapV2 | swapExactETHForTokens | Smart Account | False | True | N/A | 435648 | 0 | -| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 418767 | 0 | -| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 466872 | 0 | -| UniswapV2 | swapExactETHForTokens | Smart Account | True | True | N/A | 215805 | 0 | -| UniswapV2 | swapExactTokensForTokens | EOA | False | False | N/A | 118252 | 0 | -| UniswapV2 | swapExactTokensForTokens | Smart Account | True | False | N/A | 168221 | 0 | -| UniswapV2 | swapExactTokensForTokens | Smart Account | False | True | N/A | 404616 | 0 | -| UniswapV2 | swapExactTokensForTokens | Smart Account | False | False | N/A | 387734 | 0 | -| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | True | False | N/A | 200217 | 0 | -| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | True | N/A | 436814 | 0 | -| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 419743 | 0 | -| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 467849 | 0 | -| UniswapV2 | swapExactTokensForTokens | Smart Account | True | True | N/A | 184796 | 0 | From c474f45c5509d892cf4350514eb409f5e8e81c7e Mon Sep 17 00:00:00 2001 From: aboudjem Date: Sat, 1 Jun 2024 21:37:39 +0400 Subject: [PATCH 8/9] feat: Update gas report script paths and improve generation --- GAS_REPORT.md | 58 ++++ previous_gas_report.json | 662 --------------------------------------- 2 files changed, 58 insertions(+), 662 deletions(-) create mode 100644 GAS_REPORT.md delete mode 100644 previous_gas_report.json diff --git a/GAS_REPORT.md b/GAS_REPORT.md new file mode 100644 index 00000000..220a96e7 --- /dev/null +++ b/GAS_REPORT.md @@ -0,0 +1,58 @@ +# Gas Report +| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Gas Difference** | +|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:------------------:| +| ERC20 | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 49921 | 0 | +| ERC20 | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 25221 | 0 | +| ERC20 | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 94767 | 0 | +| ERC20 | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 74867 | 0 | +| ERC20 | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 335883 | 0 | +| ERC20 | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 315984 | 0 | +| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 319073 | 0 | +| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 299174 | 0 | +| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 367178 | 0 | +| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 347278 | 0 | +| ERC20 | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 111262 | 0 | +| ERC20 | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 91363 | 0 | +| ERC721 | transferFrom | EOA | False | False | ๐ŸงŠ ColdAccess | 48483 | 0 | +| ERC721 | transferFrom | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28583 | 0 | +| ERC721 | transferFrom | Smart Account | True | False | ๐ŸงŠ ColdAccess | 98254 | 0 | +| ERC721 | transferFrom | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 78354 | 0 | +| ERC721 | transferFrom | Smart Account | False | True | ๐ŸงŠ ColdAccess | 334585 | 0 | +| ERC721 | transferFrom | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 314685 | 0 | +| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 317777 | 0 | +| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297877 | 0 | +| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 365881 | 0 | +| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345981 | 0 | +| ERC721 | transferFrom | Smart Account | True | True | ๐ŸงŠ ColdAccess | 114777 | 0 | +| ERC721 | transferFrom | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94877 | 0 | +| ETH | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 53073 | 0 | +| ETH | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28073 | 0 | +| ETH | call | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | 0 | +| ETH | call | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | 0 | +| ETH | send | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | 0 | +| ETH | send | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | 0 | +| ETH | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 102616 | 0 | +| ETH | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 77616 | 0 | +| ETH | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 338898 | 0 | +| ETH | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 313898 | 0 | +| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 322110 | 0 | +| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297110 | 0 | +| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 370215 | 0 | +| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345215 | 0 | +| ETH | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 119101 | 0 | +| ETH | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94101 | 0 | +| UniswapV2 | swapExactETHForTokens | EOA | False | False | N/A | 149263 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | True | False | N/A | 199242 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | False | True | N/A | 435648 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 418767 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 466872 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | True | True | N/A | 215805 | 0 | +| UniswapV2 | swapExactTokensForTokens | EOA | False | False | N/A | 118252 | 0 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | True | False | N/A | 168221 | 0 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | False | True | N/A | 404616 | 0 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | False | False | N/A | 387734 | 0 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | True | False | N/A | 200217 | 0 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | True | N/A | 436814 | 0 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 419743 | 0 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 467849 | 0 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | True | True | N/A | 184796 | 0 | diff --git a/previous_gas_report.json b/previous_gas_report.json deleted file mode 100644 index 04089706..00000000 --- a/previous_gas_report.json +++ /dev/null @@ -1,662 +0,0 @@ -[ - { - "NUMBER": 1, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 49921, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 2, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 25221, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 3, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 94767, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 4, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 74867, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 5, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 335883, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 6, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 315984, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 7, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 319073, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 8, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 299174, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 9, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 367178, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 10, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 347278, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 11, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 111262, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 12, - "PROTOCOL": "ERC20", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 91363, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 13, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 48483, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 14, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 28583, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 15, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 98254, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 16, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 78354, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 17, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 334585, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 18, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 314685, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 19, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 317777, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 20, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 297877, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 21, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 365881, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 22, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 345981, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 23, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 114777, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 24, - "PROTOCOL": "ERC721", - "ACTION_FUNCTION": "transferFrom", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 94877, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 25, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 53073, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 26, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 28073, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 27, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "call", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 53201, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 28, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "call", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 28201, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 29, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "send", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 53201, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 30, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "send", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 28201, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 31, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 102616, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 32, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 77616, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 33, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 338898, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 34, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 313898, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 35, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 322110, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 36, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 297110, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 37, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 370215, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 38, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 345215, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 39, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐ŸงŠ ColdAccess", - "GAS_USED": 119101, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 40, - "PROTOCOL": "ETH", - "ACTION_FUNCTION": "transfer", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "๐Ÿ”ฅ WarmAccess", - "GAS_USED": 94101, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 41, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactETHForTokens", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 149263, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 42, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactETHForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 199242, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 43, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactETHForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 435648, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 44, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactETHForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 418767, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 45, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactETHForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 466872, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 46, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactETHForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 215805, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 47, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactTokensForTokens", - "ACCOUNT_TYPE": "EOA", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 118252, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 48, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactTokensForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 168221, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 49, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactTokensForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 404616, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 50, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactTokensForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 387734, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 51, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "approve+swapExactTokensForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 200217, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 52, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "approve+swapExactTokensForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 436814, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 53, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "approve+swapExactTokensForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 419743, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 54, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "approve+swapExactTokensForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "False", - "WITH_PAYMASTER": "False", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 467849, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - }, - { - "NUMBER": 55, - "PROTOCOL": "UniswapV2", - "ACTION_FUNCTION": "swapExactTokensForTokens", - "ACCOUNT_TYPE": "Smart Account", - "IS_DEPLOYED": "True", - "WITH_PAYMASTER": "True", - "RECEIVER_ACCESS": "N/A", - "GAS_USED": 184796, - "GAS_DIFF": 0, - "GAS_DIFF_EMOJI": "" - } -] \ No newline at end of file From 4e554b4a635cbd732082e63de2d8c61532103583 Mon Sep 17 00:00:00 2001 From: aboudjem Date: Sat, 1 Jun 2024 22:00:57 +0400 Subject: [PATCH 9/9] refactor: Update gas report script paths and improve generation --- .github/gas_report.json | 2 +- GAS_REPORT.md | 61 ++++++++++- scripts/foundry/compareGasReports.js | 72 ------------- scripts/foundry/generateGasReport.js | 148 ++++++++++++++++----------- 4 files changed, 146 insertions(+), 137 deletions(-) delete mode 100644 scripts/foundry/compareGasReports.js diff --git a/.github/gas_report.json b/.github/gas_report.json index af0c4982..758ccb7c 100644 --- a/.github/gas_report.json +++ b/.github/gas_report.json @@ -549,4 +549,4 @@ "RECEIVER_ACCESS": "N/A", "GAS_USED": 184796 } -] \ No newline at end of file +] diff --git a/GAS_REPORT.md b/GAS_REPORT.md index a8908f81..383453be 100644 --- a/GAS_REPORT.md +++ b/GAS_REPORT.md @@ -1,3 +1,60 @@ # Gas Report Comparison -| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Gas Difference** | -|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:------------------:| \ No newline at end of file + +| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Gas Difference** | +| :--------------------------------: | :------------------------------: | :--------------: | :-------------: | :-----------------: | :-----------------: | :----------: | :----------------: | +| ERC20 | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 49921 | 0 | +| ERC20 | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 25221 | 0 | +| ERC20 | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 94767 | 0 | +| ERC20 | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 74867 | 0 | +| ERC20 | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 335883 | 0 | +| ERC20 | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 315984 | 0 | +| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 319073 | 0 | +| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 299174 | 0 | +| ERC20 | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 367178 | 0 | +| ERC20 | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 347278 | 0 | +| ERC20 | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 111262 | 0 | +| ERC20 | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 91363 | 0 | +| ERC721 | transferFrom | EOA | False | False | ๐ŸงŠ ColdAccess | 48483 | 0 | +| ERC721 | transferFrom | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28583 | 0 | +| ERC721 | transferFrom | Smart Account | True | False | ๐ŸงŠ ColdAccess | 98254 | 0 | +| ERC721 | transferFrom | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 78354 | 0 | +| ERC721 | transferFrom | Smart Account | False | True | ๐ŸงŠ ColdAccess | 334585 | 0 | +| ERC721 | transferFrom | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 314685 | 0 | +| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 317777 | 0 | +| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297877 | 0 | +| ERC721 | transferFrom | Smart Account | False | False | ๐ŸงŠ ColdAccess | 365881 | 0 | +| ERC721 | transferFrom | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345981 | 0 | +| ERC721 | transferFrom | Smart Account | True | True | ๐ŸงŠ ColdAccess | 114777 | 0 | +| ERC721 | transferFrom | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94877 | 0 | +| ETH | transfer | EOA | False | False | ๐ŸงŠ ColdAccess | 53073 | 0 | +| ETH | transfer | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28073 | 0 | +| ETH | call | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | 0 | +| ETH | call | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | 0 | +| ETH | send | EOA | False | False | ๐ŸงŠ ColdAccess | 53201 | 0 | +| ETH | send | EOA | False | False | ๐Ÿ”ฅ WarmAccess | 28201 | 0 | +| ETH | transfer | Smart Account | True | False | ๐ŸงŠ ColdAccess | 102616 | 0 | +| ETH | transfer | Smart Account | True | False | ๐Ÿ”ฅ WarmAccess | 77616 | 0 | +| ETH | transfer | Smart Account | False | True | ๐ŸงŠ ColdAccess | 338898 | 0 | +| ETH | transfer | Smart Account | False | True | ๐Ÿ”ฅ WarmAccess | 313898 | 0 | +| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 322110 | 0 | +| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 297110 | 0 | +| ETH | transfer | Smart Account | False | False | ๐ŸงŠ ColdAccess | 370215 | 0 | +| ETH | transfer | Smart Account | False | False | ๐Ÿ”ฅ WarmAccess | 345215 | 0 | +| ETH | transfer | Smart Account | True | True | ๐ŸงŠ ColdAccess | 119101 | 0 | +| ETH | transfer | Smart Account | True | True | ๐Ÿ”ฅ WarmAccess | 94101 | 0 | +| UniswapV2 | swapExactETHForTokens | EOA | False | False | N/A | 149263 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | True | False | N/A | 199242 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | False | True | N/A | 435648 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 418767 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | False | False | N/A | 466872 | 0 | +| UniswapV2 | swapExactETHForTokens | Smart Account | True | True | N/A | 215805 | 0 | +| UniswapV2 | swapExactTokensForTokens | EOA | False | False | N/A | 118252 | 0 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | True | False | N/A | 168221 | 0 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | False | True | N/A | 404616 | 0 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | False | False | N/A | 387734 | 0 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | True | False | N/A | 200217 | 0 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | True | N/A | 436814 | 0 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 419743 | 0 | +| UniswapV2 | approve+swapExactTokensForTokens | Smart Account | False | False | N/A | 467849 | 0 | +| UniswapV2 | swapExactTokensForTokens | Smart Account | True | True | N/A | 184796 | 0 | +| No differences found in gas usage. | diff --git a/scripts/foundry/compareGasReports.js b/scripts/foundry/compareGasReports.js deleted file mode 100644 index 4fff352a..00000000 --- a/scripts/foundry/compareGasReports.js +++ /dev/null @@ -1,72 +0,0 @@ -const fs = require('fs'); - -function compareGasReports(prevFile, currFile) { - if (!fs.existsSync(prevFile)) { - console.error('No previous gas report found.'); - return 'No previous gas report found. Skipping comparison.'; - } - - const prevData = fs.readFileSync(prevFile, 'utf8'); - const currData = fs.readFileSync(currFile, 'utf8'); - - const prevLines = prevData.split('\n'); - const currLines = currData.split('\n'); - - const diffLines = [ - '# Gas Report Comparison', - '| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Gas Difference** |', - '|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:------------------:|' - ]; - - const prevResults = parseGasReport(prevLines); - const currResults = parseGasReport(currLines); - - currResults.forEach(curr => { - const prev = prevResults.find(prev => prev.NUMBER === curr.NUMBER); - let gasDiff = '0'; - let gasDiffEmoji = ''; - - if (prev) { - const diff = curr.GAS_USED - prev.GAS_USED; - gasDiff = diff.toString(); - gasDiffEmoji = diff > 0 ? '๐Ÿฅต' : (diff < 0 ? '๐Ÿฅณ' : ''); - } - - diffLines.push(`| ${curr.PROTOCOL} | ${curr.ACTION_FUNCTION} | ${curr.ACCOUNT_TYPE} | ${curr.IS_DEPLOYED} | ${curr.WITH_PAYMASTER} | ${curr.RECEIVER_ACCESS} | ${curr.GAS_USED} | ${gasDiffEmoji} ${gasDiff} |`); - }); - - return diffLines.join('\n'); -} - -function parseGasReport(lines) { - const results = []; - for (const line of lines) { - if (line.startsWith('|')) { - const parts = line.split('|').map(part => part.trim()); - if (parts.length === 9 && !parts[0].includes('**')) { - results.push({ - PROTOCOL: parts[1], - ACTION_FUNCTION: parts[2], - ACCOUNT_TYPE: parts[3], - IS_DEPLOYED: parts[4], - WITH_PAYMASTER: parts[5], - RECEIVER_ACCESS: parts[6], - GAS_USED: parseInt(parts[7], 10), - NUMBER: parseInt(parts[7], 10) - }); - } - } - } - return results; -} - -if (process.argv.length !== 4) { - console.error('Usage: node compareGasReports.js '); - process.exit(1); -} - -const previousFile = process.argv[2]; -const currentFile = process.argv[3]; - -const comparison = compareGasReports(previousFile, currentFile); -console.log(comparison); diff --git a/scripts/foundry/generateGasReport.js b/scripts/foundry/generateGasReport.js index 06e032c2..ae119a7c 100644 --- a/scripts/foundry/generateGasReport.js +++ b/scripts/foundry/generateGasReport.js @@ -2,35 +2,49 @@ const fs = require("fs"); const readline = require("readline"); const { exec } = require("child_process"); -const LOG_FILE = 'gas.log'; -const OUTPUT_FILE = 'GAS_REPORT.md'; -const CURRENT_REPORT_FILE = '.github/gas_report.json'; +const LOG_FILE = "gas.log"; +const OUTPUT_FILE = "GAS_REPORT.md"; +const CURRENT_REPORT_FILE = ".github/gas_report.json"; -const REPORT_FILES = [ - '.github/gas_report.json', -]; +const REPORT_FILES = [".github/gas_report.json"]; +/** + * Execute a shell command and return it as a Promise. + * @param {string} command - Command to execute + * @returns {Promise} - Promise resolving to the command output + */ function execPromise(command) { return new Promise((resolve, reject) => { exec(command, (error, stdout, stderr) => { if (error) { reject(error); } else { - resolve(stdout ? stdout : stderr); + resolve(stdout || stderr); } }); }); } +/** + * Run forge test and log results to a file. + * @returns {Promise} - Promise resolving when the test completes + */ function runForgeTest() { + console.log("๐Ÿงช Running forge tests, this may take a few minutes..."); return execPromise("forge test -vv --mt test_Gas > gas.log"); } +/** + * Checkout the gas report file from the dev branch. + * @returns {Promise} - Promise resolving to the file path or null if not found + */ async function checkoutDevBranchAndGetReport() { for (const file of REPORT_FILES) { try { console.log(`๐Ÿ”„ Checking out ${file} from dev branch...`); - await execPromise(`git fetch origin dev && git checkout origin/dev -- ${file}`); + await execPromise( + `git fetch origin dev && git checkout origin/dev -- ${file}`, + ); if (fs.existsSync(file)) { console.log(`โœ… Fetched ${file} from dev branch.`); return file; @@ -42,6 +56,10 @@ async function checkoutDevBranchAndGetReport() { return null; } +/** + * Generate gas report from the test log. + * @returns {Promise} - Promise resolving to the current gas report results + */ async function generateReport() { await runForgeTest(); @@ -52,104 +70,110 @@ async function generateReport() { }); const results = []; + console.log("๐Ÿ“„ Parsing log file, please wait..."); - console.log('๐Ÿ“„ Parsing log file, please wait...'); for await (const line of rl) { - if (line.includes('::')) { - const parts = line.split('::'); - const number = parseInt(parts[0], 10); - const PROTOCOL = parts[1]; - const ACTION_FUNCTION = parts[2]; - const GAS_INFO = parts[parts.length - 1]; - const ACCESS_TYPE = GAS_INFO.split(': ')[0]; - const GAS_USED = parseInt(GAS_INFO.split(': ')[1], 10); - - let ACCOUNT_TYPE; - let IS_DEPLOYED; - if (line.includes('EOA')) { - ACCOUNT_TYPE = 'EOA'; - IS_DEPLOYED = 'False'; - } else if (line.includes('Nexus')) { - ACCOUNT_TYPE = 'Smart Account'; - IS_DEPLOYED = 'True'; - } else { - ACCOUNT_TYPE = 'Smart Account'; - IS_DEPLOYED = 'False'; - } - - const WITH_PAYMASTER = line.includes('WithPaymaster') ? 'True' : 'False'; - - let RECEIVER_ACCESS; - if (ACCESS_TYPE === "ColdAccess") { - RECEIVER_ACCESS = "๐ŸงŠ ColdAccess"; - } else if (ACCESS_TYPE === "WarmAccess") { - RECEIVER_ACCESS = "๐Ÿ”ฅ WarmAccess"; - } else { - RECEIVER_ACCESS = "N/A"; - } + if (line.includes("::")) { + const [number, PROTOCOL, ACTION_FUNCTION, , , GAS_INFO] = + line.split("::"); + const ACCESS_TYPE = GAS_INFO.split(": ")[0]; + const GAS_USED = parseInt(GAS_INFO.split(": ")[1], 10); + + const ACCOUNT_TYPE = line.includes("EOA") ? "EOA" : "Smart Account"; + const IS_DEPLOYED = line.includes("Nexus") ? "True" : "False"; + const WITH_PAYMASTER = line.includes("WithPaymaster") ? "True" : "False"; + const RECEIVER_ACCESS = + ACCESS_TYPE === "ColdAccess" + ? "๐ŸงŠ ColdAccess" + : ACCESS_TYPE === "WarmAccess" + ? "๐Ÿ”ฅ WarmAccess" + : "N/A"; results.push({ - NUMBER: number, + NUMBER: parseInt(number, 10), PROTOCOL, ACTION_FUNCTION, ACCOUNT_TYPE, IS_DEPLOYED, WITH_PAYMASTER, RECEIVER_ACCESS, - GAS_USED + GAS_USED, }); } } - console.log('๐Ÿ”„ Sorting results...'); + console.log("๐Ÿ”„ Sorting results..."); results.sort((a, b) => a.NUMBER - b.NUMBER); fs.writeFileSync(CURRENT_REPORT_FILE, JSON.stringify(results, null, 2)); - console.log(`๐Ÿ“Š Current gas report generated and saved to ${CURRENT_REPORT_FILE}`); + console.log( + `๐Ÿ“Š Current gas report generated and saved to ${CURRENT_REPORT_FILE}`, + ); return results; } +/** + * Compare the current gas report with the previous report from the dev branch. + * @returns {Promise} - Promise resolving when the comparison is complete + */ async function compareReports() { const previousReportFile = await checkoutDevBranchAndGetReport(); if (!previousReportFile) { - console.error('โŒ No previous gas report found in dev branch.'); + console.error("โŒ No previous gas report found in dev branch."); return; } - const prevData = fs.readFileSync(previousReportFile, 'utf8'); + const prevData = fs.readFileSync(previousReportFile, "utf8"); const prevResults = JSON.parse(prevData); - const currResults = JSON.parse(fs.readFileSync(CURRENT_REPORT_FILE, 'utf8')); + const currResults = JSON.parse(fs.readFileSync(CURRENT_REPORT_FILE, "utf8")); const diffLines = [ - '# Gas Report Comparison', - '| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Gas Difference** |', - '|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:------------------:|' + "# Gas Report Comparison", + "| **Protocol** | **Actions / Function** | **Account Type** | **Is Deployed** | **With Paymaster?** | **Receiver Access** | **Gas Used** | **Gas Difference** |", + "|:------------:|:---------------------:|:----------------:|:--------------:|:-------------------:|:-------------------:|:------------:|:------------------:|", ]; let hasDiff = false; - currResults.forEach(curr => { - const prev = prevResults.find(prev => prev.NUMBER === curr.NUMBER); + currResults.forEach((curr) => { + const prev = prevResults.find((prev) => prev.NUMBER === curr.NUMBER); if (prev) { const diff = curr.GAS_USED - prev.GAS_USED; + const gasDiff = + diff > 0 ? `๐Ÿฅต +${diff}` : diff < 0 ? `๐Ÿฅณ -${Math.abs(diff)}` : "0"; + diffLines.push( + `| ${curr.PROTOCOL} | ${curr.ACTION_FUNCTION} | ${curr.ACCOUNT_TYPE} | ${curr.IS_DEPLOYED} | ${curr.WITH_PAYMASTER} | ${curr.RECEIVER_ACCESS} | ${curr.GAS_USED} | ${gasDiff} |`, + ); if (diff !== 0) { hasDiff = true; - const gasDiff = diff > 0 ? `๐Ÿฅต +${diff}` : `๐Ÿฅณ ${diff}`; - diffLines.push(`| ${curr.PROTOCOL} | ${curr.ACTION_FUNCTION} | ${curr.ACCOUNT_TYPE} | ${curr.IS_DEPLOYED} | ${curr.WITH_PAYMASTER} | ${curr.RECEIVER_ACCESS} | ${curr.GAS_USED} | ${gasDiff} |`); - console.log(`๐Ÿ” ${curr.ACTION_FUNCTION} (${curr.ACCOUNT_TYPE}, ${curr.IS_DEPLOYED}, ${curr.WITH_PAYMASTER}): ${prev.GAS_USED} -> ${curr.GAS_USED} (${gasDiff})`); + console.log( + `๐Ÿ” ${curr.PROTOCOL} - ${curr.ACTION_FUNCTION} (${curr.ACCOUNT_TYPE}, Deployed: ${curr.IS_DEPLOYED}, Paymaster: ${curr.WITH_PAYMASTER}): ${prev.GAS_USED} -> ${curr.GAS_USED} (${gasDiff})`, + ); } } }); - fs.writeFileSync(OUTPUT_FILE, diffLines.join('\n')); - console.log('๐Ÿ“Š Gas report comparison generated and saved to GAS_REPORT.md'); - - if (hasDiff) { - console.log('๐Ÿ“ˆ Differences found and reported.'); + if (!hasDiff) { + diffLines.push("| No differences found in gas usage. |"); + console.log("๐Ÿ“‰ No differences found."); } else { - console.log('๐Ÿ“‰ No differences found.'); + console.log("๐Ÿ“ˆ Differences found and reported."); } + + fs.writeFileSync(OUTPUT_FILE, diffLines.join("\n")); + console.log("๐Ÿ“Š Gas report comparison generated and saved to GAS_REPORT.md"); + + // Format with Prettier + execPromise(`yarn prettier --write ${OUTPUT_FILE}`).then(() => { + console.log("โœจ Prettier formatting completed for GAS_REPORT.md"); + }); + + // Clean up + fs.unlink(LOG_FILE, (err) => { + if (err) console.error(`โŒ Error deleting ${LOG_FILE}: ${err}`); + else console.log(`๐Ÿ—‘๏ธ ${LOG_FILE} deleted successfully.`); + }); } async function main() {