{"id":11965,"date":"2025-01-22T06:28:44","date_gmt":"2025-01-22T06:28:44","guid":{"rendered":"https:\/\/metaschool.so\/articles\/?p=11965"},"modified":"2025-01-27T06:55:34","modified_gmt":"2025-01-27T06:55:34","slug":"gas-optimization-techniques-in-solidity","status":"publish","type":"post","link":"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/","title":{"rendered":"Gas Optimization Techniques in Solidity: Comprehensive Guide with Code Examples 2025"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_56_1 ez-toc-wrap-left counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title \" >Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Understanding_Gas_Mechanics\" title=\"Understanding Gas Mechanics\">Understanding Gas Mechanics<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Basic_Optimization_Techniques\" title=\"Basic Optimization Techniques\">Basic Optimization Techniques<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Storage_Optimization\" title=\"Storage Optimization\">Storage Optimization<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Memory_vs_Calldata\" title=\"Memory vs Calldata\">Memory vs Calldata<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Variable_Packing\" title=\"Variable Packing\">Variable Packing<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Intermediate_level_Optimization_Techniques\" title=\"Intermediate level Optimization Techniques\">Intermediate level Optimization Techniques<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Inline_Assembly\" title=\"Inline Assembly\">Inline Assembly<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Minimizing_External_Calls\" title=\"Minimizing External Calls\">Minimizing External Calls<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Loops_Optimization\" title=\"Loops Optimization\">Loops Optimization<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Advanced_Optimization_Techniques\" title=\"Advanced Optimization Techniques\">Advanced Optimization Techniques<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Short-circuiting_in_Conditionals\" title=\"Short-circuiting in Conditionals\">Short-circuiting in Conditionals<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Bitmap_Pattern_for_Multiple_Booleans\" title=\"Bitmap Pattern for Multiple Booleans\">Bitmap Pattern for Multiple Booleans<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Fixed-size_Arrays_Over_Dynamic_Arrays\" title=\"Fixed-size Arrays Over Dynamic Arrays\">Fixed-size Arrays Over Dynamic Arrays<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Ordering_of_Function_Input_Validation\" title=\"Ordering of Function Input Validation\">Ordering of Function Input Validation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Optimized_Error_Handling\" title=\"Optimized Error Handling\">Optimized Error Handling<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Event_Parameter_Packing\" title=\"Event Parameter Packing\">Event Parameter Packing<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Function_Modifiers_vs_Internal_Functions\" title=\"Function Modifiers vs. Internal Functions\">Function Modifiers vs. Internal Functions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Merkle_Proofs_for_Large_Datasets\" title=\"Merkle Proofs for Large Datasets\">Merkle Proofs for Large Datasets<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Gas_Optimization_Tools\" title=\"Gas Optimization Tools\">Gas Optimization Tools<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Hardhat_Gas_Reporter\" title=\"Hardhat Gas Reporter\">Hardhat Gas Reporter<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Remix_Analyser\" title=\"Remix Analyser\">Remix Analyser<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Real-World_Optimisation_Example\" title=\"Real-World Optimisation Example\">Real-World Optimisation Example<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Best_Practices_and_Recommendations\" title=\"Best Practices and Recommendations\">Best Practices and Recommendations<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/metaschool.so\/articles\/gas-optimization-techniques-in-solidity\/#Conclusion\" title=\"Conclusion\">Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n\n<p>Smart contract development on Ethereum requires a delicate balance between functionality and efficiency. Gas optimization is crucial not just for cost reduction, but also for ensuring your contracts remain viable during periods of network congestion. This article explores advanced gas optimization techniques that can significantly reduce the operational costs of your smart contracts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Understanding_Gas_Mechanics\"><\/span>Understanding Gas Mechanics<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Every single operation in EVM consumes a certain amount of gas. The price of gas is not established arbitrarily but is done to have an idea of the costs of each operation with respect to computational and storage resources. Understanding these charges is key to writing efficient smart contracts.<\/p>\n\n\n\n<p>The EVM offers different pricing for various operations. In general, the most expensive operations involve storage, where SSTORE costs 20,000 gas for setting up and 5,000 gas for updates.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Memory operations are relatively cheap but scale quadratically with size<\/li>\n\n\n\n<li>Computational operations like addition, 3 gas and multiplication, 5 gas are the cheap operations<\/li>\n\n\n\n<li>External calls have a base cost of 700 gas plus additional data transfer costs<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Basic_Optimization_Techniques\"><\/span>Basic Optimization Techniques<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Storage_Optimization\"><\/span>Storage Optimization<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Storage is the most expensive resource in Ethereum. Each storage slot (256 bits) costs 20,000 gas to initialize and 5,000 gas to update. By optimizing how we use storage, we can significantly reduce transaction costs. The key is to minimize storage operations and maximize storage slot usage. Below is an inefficient versus optimized example of storage usage:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:100%\">\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient Implementation\ncontract Inefficient {\n    uint256[] public values;\n    \n    function processValues(uint256[] memory newValues) public {\n        for (uint256 i = 0; i &lt; newValues.length; i++) {\n            values.push(newValues[i]); \/\/ Each iteration performs a storage write\n        }\n    }\n}\n\n\/\/ Optimized Implementation\ncontract Optimized {\n    uint256[] public values;\n    \n    function processValues(uint256[] memory newValues) public {\n        uint256[] storage cachedValues = values;\n        uint256 originalLength = cachedValues.length;\n        cachedValues.length = originalLength + newValues.length;\n        \n        for (uint256 i = 0; i &lt; newValues.length; i++) {\n            cachedValues[originalLength + i] = newValues[i];\n        }\n    }\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient Implementation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Inefficient<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">processValues<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">newValues<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">newValues<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">push<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">newValues<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">]); <\/span><span style=\"color: #6A9955\">\/\/ Each iteration performs a storage write<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized Implementation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Optimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">processValues<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">newValues<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">storage<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">cachedValues<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">originalLength<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">cachedValues<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">cachedValues<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">originalLength<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">newValues<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">newValues<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">cachedValues<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">originalLength<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #9CDCFE\">newValues<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Memory_vs_Calldata\"><\/span>Memory vs Calldata<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The choice between memory and calldata for function parameters can significantly impact gas costs. Call data is a read-only area where function arguments are stored, while memory is a temporary storage area that can be modified. Using call data for read-only array arguments saves gas by avoiding unnecessary data copying. Thus for functions that receive arrays or strings as parameters, using <code>calldata<\/code> instead of <code>memory<\/code> can save significant gas:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Expensive: Copies array to memory\nfunction processArray(uint256[] memory data) external {\n    \/\/ Process array\n}\n\n\/\/ Cheaper: Uses calldata directly\nfunction processArray(uint256[] calldata data) external {\n    \/\/ Process array\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Expensive: Copies array to memory<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">processArray<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #6A9955\">\/\/ Process array<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Cheaper: Uses calldata directly<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">processArray<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">calldata<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #6A9955\">\/\/ Process array<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Variable_Packing\"><\/span>Variable Packing<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The EVM operates with 32-byte storage slots. Multiple smaller variables can be packed into a single slot, reducing storage costs. This is particularly effective for variables that are frequently updated together.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: Uses 3 storage slots\ncontract Inefficient {\n    uint256 a; \/\/ 32 bytes\n    uint8 b;   \/\/ 1 byte\n    uint8 c;   \/\/ 1 byte\n}\n\n\/\/ Optimized: Uses 2 storage slots\ncontract Optimized {\n    uint256 a; \/\/ 32 bytes\n    uint8 b;   \/\/ 1 byte, packed with c\n    uint8 c;   \/\/ 1 byte, packed with b\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: Uses 3 storage slots<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Inefficient<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">a<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #6A9955\">\/\/ 32 bytes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint8<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">b<\/span><span style=\"color: #D4D4D4\">;   <\/span><span style=\"color: #6A9955\">\/\/ 1 byte<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint8<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #D4D4D4\">;   <\/span><span style=\"color: #6A9955\">\/\/ 1 byte<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: Uses 2 storage slots<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Optimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">a<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #6A9955\">\/\/ 32 bytes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint8<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">b<\/span><span style=\"color: #D4D4D4\">;   <\/span><span style=\"color: #6A9955\">\/\/ 1 byte, packed with c<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint8<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #D4D4D4\">;   <\/span><span style=\"color: #6A9955\">\/\/ 1 byte, packed with b<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Intermediate_level_Optimization_Techniques\"><\/span>Intermediate level Optimization Techniques<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Inline_Assembly\"><\/span>Inline Assembly<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Inline assembly provides direct access to EVM opcodes, allowing for more gas-efficient operations in performance-critical code. While it sacrifices readability and safety checks, it can provide significant gas savings for specific operations like low-level memory management or bit manipulation. For performance-critical operations,the  inline assembly can save significant gas:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Traditional Solidity\nfunction getFirst(uint256[] memory arr) public pure returns (uint256) {\n    require(arr.length &gt; 0, &quot;Empty array&quot;);\n    return arr[0];\n}\n\n\/\/ Assembly\nfunction getFirstAssembly(uint256[] memory arr) public pure returns (uint256 result) {\n    assembly {\n\/\/ Check if array is empty\n        if iszero(mload(arr)) {\n            revert(0, 0)\n        }\n        \/\/ Load first element\n        result := mload(add(arr, 0x20))\n}\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Traditional Solidity<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">getFirst<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">arr<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">pure<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">arr<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Empty array&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">arr<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Assembly<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">getFirstAssembly<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">arr<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">pure<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">assembly<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Check if array is empty<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">iszero<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">mload<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">arr<\/span><span style=\"color: #D4D4D4\">)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">revert<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Load first element<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C8C8C8\">result<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #DCDCAA\">mload<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">arr<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0x20<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Minimizing_External_Calls\"><\/span>Minimizing External Calls<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>External calls are expensive because they require the EVM to load another contract&#8217;s code and execute it in a new context. Batching multiple operations into a single call can significantly reduce gas costs by sharing the base call cost across multiple operations thus they need to be optimized<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: Multiple external calls\ncontract Inefficient {\n    IERC20 token;\n\n    function transferMultiple(address[] memory recipients, uint256 amount) external {\n        for (uint256 i = 0; i < recipients.length; i++) {\ntoken.transfer(recipients[i], amount); \/\/ External call in loop\n        }\n    }\n}\n\n\/\/ Optimized: Batched external calls\ncontract Optimized {\n    IERC20 token;\n\n    function transferMultiple(\n        address[] memory recipients,\nuint256[] memory amounts\n    ) external returns (bool) {\n        bytes memory data = abi.encodeWithSignature(\n            &quot;transferMultiple(address[],uint256[])&quot;,\n            recipients,\n            amounts\n);\n        (bool success, ) = address(token).call(data); \/\/ Single external call\n        return success;\n    }\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: Multiple external calls<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Inefficient<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4FC1FF\">IERC20<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">transferMultiple<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">recipients<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">recipients<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">transfer<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">recipients<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">], <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">); <\/span><span style=\"color: #6A9955\">\/\/ External call in loop<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: Batched external calls<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Optimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4FC1FF\">IERC20<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">transferMultiple<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">recipients<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amounts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bytes<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">abi<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">encodeWithSignature<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #CE9178\">&quot;transferMultiple(address[],uint256[])&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">recipients<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">amounts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        (<\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">success<\/span><span style=\"color: #D4D4D4\">, ) = <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">call<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\">); <\/span><span style=\"color: #6A9955\">\/\/ Single external call<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">success<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Loops_Optimization\"><\/span>Loops Optimization<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Loops are a common source of high gas consumption. Key optimization strategies include caching array lengths, using unchecked math where safe, and minimizing storage access within loops.The following are the most important optimization techniques:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Looser version\nfunction sumArray(uint256[] memory values) public pure returns (uint256) {\nuint256 sum = 0;\n    for (uint256 i = 0; i < values.length; i++) {\n        sum += values[i];\n        \/\/ Accessing length in every iteration\n        \/\/ Using memory variable for accumulation\n    }\n    return sum;\n}\n\n\/\/ Optimized loop\nfunction sumArrayOptimized(uint256[] memory values) public pure returns (uint256) {\n    uint256 sum;\n    uint256 len = values.length;\n    unchecked {\n        \/\/ Using unchecked for gas optimization since overflow is impossible\n        for (uint256 i; i < len; ++i) {\nsum += values[i];\n        }\n    }\n    return sum;\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Looser version<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">sumArray<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">pure<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sum<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">sum<\/span><span style=\"color: #D4D4D4\"> += <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Accessing length in every iteration<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Using memory variable for accumulation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sum<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized loop<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">sumArrayOptimized<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">pure<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sum<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">len<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">unchecked<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Using unchecked for gas optimization since overflow is impossible<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">len<\/span><span style=\"color: #D4D4D4\">; ++<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">sum<\/span><span style=\"color: #D4D4D4\"> += <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sum<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Advanced_Optimization_Techniques\"><\/span>Advanced Optimization Techniques<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Short-circuiting_in_Conditionals\"><\/span>Short-circuiting in Conditionals<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>In Solidity, when evaluating logical expressions with AND (&amp;&amp;) or OR (||) operators, the second condition is only evaluated if necessary based on the first condition&#8217;s result. By ordering conditions strategically &#8211; placing cheaper checks first and more expensive operations last &#8211; we can save gas by avoiding unnecessary evaluations. Save gas in conditional statements by ordering the conditions appropriately:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: Always evaluates both conditions\nfunction processTransaction(uint256 amount, address recipient) external {\n    require(recipient!= address(0) &amp;&amp; amount &gt; 0, &quot;Invalid input&quot;);\n}\n\n\/\/ Optimized: Short-circuits on first failure\nfunction processTransaction(uint256 amount, address recipient) external {\n    require(amount &gt; 0, &quot;Invalid amount&quot;); \/\/ Cheaper check first\n    require(recipient != address(0), &quot;Invalid recipient&quot;);\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: Always evaluates both conditions<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">processTransaction<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">recipient<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">recipient<\/span><span style=\"color: #D4D4D4\">!= <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) &amp;&amp; <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Invalid input&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: Short-circuits on first failure<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">processTransaction<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">recipient<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Invalid amount&quot;<\/span><span style=\"color: #D4D4D4\">); <\/span><span style=\"color: #6A9955\">\/\/ Cheaper check first<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">recipient<\/span><span style=\"color: #D4D4D4\"> != <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #CE9178\">&quot;Invalid recipient&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Bitmap_Pattern_for_Multiple_Booleans\"><\/span>Bitmap Pattern for Multiple Booleans<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Storing multiple boolean values as individual state variables is inefficient because each boolean uses a full storage slot (256 bits). By using a bitmap pattern, we can pack multiple flags into a single uint256, potentially storing up to 256 boolean values in the same storage slot. Instead of declaring multiple booleans, especially if used together to enable\/disable functionalities, better use a bitmap:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: Multiple storage slots\ncontract Inefficient {\n    bool public isActive;\n    bool public isPaused;\nbool public isFinalized;\n    bool public isArchived;\n\n    function setFlags(bool _active, bool _paused, bool _finalized, bool _archived) external {\n        isActive = _active;\n        isPaused = _paused;\n        isFinalized = _finalized;\nisArchived = _archived;\n    }\n}\n\n\/\/ Optimized: storage slot size optimisation via bitmap\ncontract Optimized {\n    uint8 private flags;\n\n    \/\/ positions for flags in that array\n    uint8 private constant IS_ACTIVE = 1;\n    uint8 private constant IS_PAUSED = 1 << 1;\nuint8 private constant IS_FINALIZED = 1 << 2;\n    uint8 private constant IS_ARCHIVED = 1 << 3;\n\n    function setFlags(bool _active, bool _paused, bool _finalized, bool _archived) external {\n        flags = (_active? IS_ACTIVE : 0) |\n(_paused? IS_PAUSED : 0) |\n                (_finalized? IS_FINALIZED : 0) |\n                (_archived? IS_ARCHIVED : 0);\n    }\nfunction isActive() external view returns (bool) {\n        return flags &amp; IS_ACTIVE!= 0;\n    }\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: Multiple storage slots<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Inefficient<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">isActive<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">isPaused<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">isFinalized<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">isArchived<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">setFlags<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_active<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_paused<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_finalized<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_archived<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">isActive<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_active<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">isPaused<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_paused<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">isFinalized<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_finalized<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">isArchived<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_archived<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: storage slot size optimisation via bitmap<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Optimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint8<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">flags<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #6A9955\">\/\/ positions for flags in that array<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint8<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">constant<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">IS_ACTIVE<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint8<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">constant<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">IS_PAUSED<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> &lt;&lt; <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">uint8<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">constant<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">IS_FINALIZED<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> &lt;&lt; <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint8<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">constant<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">IS_ARCHIVED<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> &lt;&lt; <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">setFlags<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_active<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_paused<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_finalized<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_archived<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">flags<\/span><span style=\"color: #D4D4D4\"> = (<\/span><span style=\"color: #9CDCFE\">_active<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #4FC1FF\">IS_ACTIVE<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_paused<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #4FC1FF\">IS_PAUSED<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                (<\/span><span style=\"color: #9CDCFE\">_finalized<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #4FC1FF\">IS_FINALIZED<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                (<\/span><span style=\"color: #9CDCFE\">_archived<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #4FC1FF\">IS_ARCHIVED<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">isActive<\/span><span style=\"color: #D4D4D4\">() <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">view<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">flags<\/span><span style=\"color: #D4D4D4\"> &amp; <\/span><span style=\"color: #4FC1FF\">IS_ACTIVE<\/span><span style=\"color: #D4D4D4\">!= <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Fixed-size_Arrays_Over_Dynamic_Arrays\"><\/span>Fixed-size Arrays Over Dynamic Arrays<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Dynamic arrays in Solidity incur additional gas costs for length management and storage operations. When the array size is known at compile time, using fixed-size arrays eliminates these overhead costs and provides better gas predictability. The storage layout is also more efficient since slot locations can be computed directly. When the size is fixed, fixed-size arrays are more gas-efficient:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: Dynamic array\ncontract Inefficient {\n    uint256[] private values;\n\n    function initialize() external {\n\/\/ Always adds exactly 3 values\n        values.push(1);\n        values.push(2);\n        values.push(3);\n    }\n}\n\n\/\/ Optimized: Fixed-size array\ncontract Optimized {\n    uint256[3] private values;\n\n    function initialize() external {\nvalues[0] = 1;\n        values[1] = 2;\n        values[2] = 3;\n    }\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: Dynamic array<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Inefficient<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">initialize<\/span><span style=\"color: #D4D4D4\">() <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Always adds exactly 3 values<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">push<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">push<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">push<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: Fixed-size array<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Optimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">] <\/span><span style=\"color: #9CDCFE\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">initialize<\/span><span style=\"color: #D4D4D4\">() <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Ordering_of_Function_Input_Validation\"><\/span>Ordering of Function Input Validation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The order of input validations can significantly impact gas consumption, especially in functions that fail frequently. By performing cheaper validations first (like zero checks), we can fail fast and avoid unnecessary expensive computations (like signature verification) when basic validations fail. Order function input validation to minimize gas spent in case of a failure:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: expensive checks first, cheap checks last\nfunction processPurchase(uint256 amount, bytes calldata data) external {\nrequire(verify(data), &quot;Invalid signature&quot;); \/\/ Expensive\n    require(amount &gt; 0, &quot;Invalid amount&quot;); \/\/ Cheap check\n    require(amount <= address(this).balance, &quot;Insufficient balance&quot;);\n}\n\n\/\/ Optimized: Check cheaper checks first, then more expensive ones.\nfunction processPurchase(uint256 amount, bytes calldata data) external {\n    require(amount &gt; 0, &quot;Invalid amount&quot;); \/\/ First check most likely cheap one.\n    require(amount <= address(this).balance, &quot;Insufficient balance&quot;);\nrequire(verify(data), &quot;Invalid signature&quot;); \/\/ Expensive operation last\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: expensive checks first, cheap checks last<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">processPurchase<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">bytes<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">calldata<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">verify<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #CE9178\">&quot;Invalid signature&quot;<\/span><span style=\"color: #D4D4D4\">); <\/span><span style=\"color: #6A9955\">\/\/ Expensive<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Invalid amount&quot;<\/span><span style=\"color: #D4D4D4\">); <\/span><span style=\"color: #6A9955\">\/\/ Cheap check<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &lt;= <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">this<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #9CDCFE\">balance<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Insufficient balance&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: Check cheaper checks first, then more expensive ones.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">processPurchase<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">bytes<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">calldata<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Invalid amount&quot;<\/span><span style=\"color: #D4D4D4\">); <\/span><span style=\"color: #6A9955\">\/\/ First check most likely cheap one.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &lt;= <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">this<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #9CDCFE\">balance<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Insufficient balance&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">verify<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #CE9178\">&quot;Invalid signature&quot;<\/span><span style=\"color: #D4D4D4\">); <\/span><span style=\"color: #6A9955\">\/\/ Expensive operation last<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Optimized_Error_Handling\"><\/span>Optimized Error Handling<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Custom errors, introduced in Solidity 0.8.4, are more gas-efficient than revert\/require strings because they avoid storing error messages in contract bytecode. They also provide better debugging capabilities by allowing dynamic error data to be passed along with the revert. Using custom errors instead of requiring statements with strings:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: String error messages\ncontract Inefficient {\n    function withdraw(uint256 amount) external {\n        require(amount &gt; 0, &quot;Amount must be greater than 0&quot;);\n        require(amount <= address(this).balance, &quot;Insufficient balance&quot;);\n    }\n}\n\n\/\/ Optimized: Custom errors\ncontract Optimized {\n    error InvalidAmount();\n    error InsufficientBalance(uint256 requested, uint256 available);\n\n    function withdraw(uint256 amount) external {\n        if (amount == 0) revert InvalidAmount();\n        if (amount &gt; address(this).balance)\n            revert InsufficientBalance(amount, address(this).balance);\n}\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: String error messages<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Inefficient<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">withdraw<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Amount must be greater than 0&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &lt;= <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">this<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #9CDCFE\">balance<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Insufficient balance&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: Custom errors<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Optimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InvalidAmount<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InsufficientBalance<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">requested<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">available<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">withdraw<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InvalidAmount<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">this<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #9CDCFE\">balance<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InsufficientBalance<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">this<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #9CDCFE\">balance<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Event_Parameter_Packing\"><\/span>Event Parameter Packing<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The gas cost of emitting events depends on how parameters are organized between indexed and non-indexed fields. Indexed parameters (topics) are stored separately and cost more gas, while non-indexed parameters are ABI-encoded together in the data field, allowing for more efficient packing. Order event parameters to optimize for gas cost efficiency:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: Unoptimized parameter ordering\ncontract Inefficient {\n    event Transfer(\n        address indexed from,\n        address indexed to,\n        uint256 amount,\n        string memo,\n        uint256 timestamp\n    );\n}\n\n\/\/ Optimized: Parameters packed efficiently\ncontract Optimized {\n    event Transfer(\n        address indexed from,\n        address indexed to,\n        string memo, \/\/ Non-indexed parameters grouped together\n        uint256 amount,\n        uint256 timestamp\n    );\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: Unoptimized parameter ordering<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Inefficient<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">event<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">Transfer<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">indexed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">from<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">indexed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">memo<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">timestamp<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: Parameters packed efficiently<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Optimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">event<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">Transfer<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">indexed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">from<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">indexed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">memo<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #6A9955\">\/\/ Non-indexed parameters grouped together<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">timestamp<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Function_Modifiers_vs_Internal_Functions\"><\/span>Function Modifiers vs. Internal Functions<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>While modifiers improve code reusability, they can be less gas-efficient than internal functions because they inject code into each function they modify. Internal functions provide better gas efficiency through compiler optimization and give more control over execution flow. Replace modifiers with internal functions when possible:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: Using modifier\ncontract Inefficient {\n    modifier validateInput(uint256 amount) {\n        require(amount &gt; 0, &quot;Invalid amount&quot;);\n        require(amount &lt;= address(this).balance, &quot;Insufficient balance&quot;);\n        _;\n    }\n    \n    function withdraw(uint256 amount) external validateInput(amount) {\n        \/\/ Process withdrawal\n    }\n}\n\n\/\/ Optimized: Using internal function\ncontract Optimized {\n    function _validateInput(uint256 amount) internal view {\n        if (amount == 0) revert InvalidAmount();\n        if (amount &gt; address(this).balance) revert InsufficientBalance();\n    }\n    \n    function withdraw(uint256 amount) external {\n        _validateInput(amount);\n        \/\/ Process withdrawal\n    }\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: Using modifier<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Inefficient<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">modifier<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">validateInput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Invalid amount&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &lt;= <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">this<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #9CDCFE\">balance<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Insufficient balance&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">_<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">withdraw<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">validateInput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Process withdrawal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: Using internal function<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Optimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">_validateInput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">internal<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">view<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InvalidAmount<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">this<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #9CDCFE\">balance<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InsufficientBalance<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">withdraw<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">_validateInput<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Process withdrawal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Merkle_Proofs_for_Large_Datasets\"><\/span>Merkle Proofs for Large Datasets<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>For large datasets that need verification (like whitelists or airdrops), storing all data on-chain is prohibitively expensive. Merkle trees allow storing just a single root hash on-chain while keeping the data off-chain. Users prove their inclusion by providing a Merkle proof, which is validated against the root hash. For large data sets, it is much more gas-efficient to pass the Merkle proof rather than the full array of data:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Inefficient: Storing full array\nInefficient Contract {\n    address[] public whitelist;\n\n    function isWhitelisted(address account) public view returns (bool) {\n        for (uint256 i = 0; i < whitelist.length; i++) {\n            if (whitelist[i] == account) return true;\n        }\nreturn false;\n    }\n}\n\n\/\/ Optimized: Using Merkle proof\ncontract Optimized {\n    bytes32 public immutable merkleRoot;\n\n    constructor(bytes32 _merkleRoot) {\n        merkleRoot = _merkleRoot;\n    }\n\n    function isWhitelisted(\n        address account,\nbytes32[] calldata proof\n    ) public view returns (bool) {\n        bytes32 leaf = keccak256(abi.encodePacked(account));\n        return verifyMerkleProof(proof, merkleRoot, leaf);\n    }\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Inefficient: Storing full array<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">Inefficient<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Contract<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">whitelist<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">isWhitelisted<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">account<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">view<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">whitelist<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">whitelist<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">] == <\/span><span style=\"color: #9CDCFE\">account<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Optimized: Using Merkle proof<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Optimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">bytes32<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">immutable<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">merkleRoot<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">constructor<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">bytes32<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_merkleRoot<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">merkleRoot<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_merkleRoot<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">isWhitelisted<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">account<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">bytes32<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">calldata<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">proof<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">view<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bytes32<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">leaf<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">keccak256<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">abi<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">encodePacked<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">account<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">verifyMerkleProof<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">proof<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">merkleRoot<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">leaf<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Gas_Optimization_Tools\"><\/span>Gas Optimization Tools<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Hardhat_Gas_Reporter\"><\/span>Hardhat Gas Reporter<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Hardhat Gas Reporter is a must-have tool for tracking gas consumption while developing. Add it to your Hardhat config:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"require(&quot;hardhat-gas-reporter&quot;);\n\nmodule.exports = {\n  gasReporter: {\n    enabled: true,\ncurrency: 'USD',\n    gasPrice: 21,\n    coinmarketcap: process.env.COINMARKETCAP_API_KEY\n  }\n};\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;hardhat-gas-reporter&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4EC9B0\">module<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">exports<\/span><span style=\"color: #D4D4D4\"> = {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">gasReporter:<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">enabled:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">currency:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;USD&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">gasPrice:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">21<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">coinmarketcap:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">process<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">env<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4FC1FF\">COINMARKETCAP_API_KEY<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">};<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Remix_Analyser\"><\/span>Remix Analyser<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The<a href=\"https:\/\/remix.ethereum.org\/\" data-type=\"link\" data-id=\"https:\/\/remix.ethereum.org\/\" target=\"_blank\" rel=\"noopener\"> Remix IDE <\/a>has a native analyzer that is able to highlight some common gas optimizations. These often include, but are not limited to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Functions can have state mutability restricted to pure\/view<\/li>\n\n\n\n<li>Consider making variable x a storage variable<\/li>\n\n\n\n<li>Inefficient loop<\/li>\n\n\n\n<li>Unused variable<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Real-World_Optimisation_Example\"><\/span>Real-World Optimisation Example<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Here&#8217;s a complete example, with optimization for a token vesting contract:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ Before optimization\ncontract TokenVesting {\n    struct Vesting {\n        uint256 amount;\n        uint256 startTime;\n        uint256 duration;\n        uint256 released;\n        bool revocable;\n        bool revoked;\n    }\n    \n    mapping(address =&gt; Vesting) public vestings;\n    IERC20 public token;\n    \n    function createVesting(\n        address beneficiary,\n        uint256 amount,\n        uint256 duration,\n        bool revocable\n    ) external {\n        require(beneficiary != address(0), &quot;Invalid beneficiary&quot;);\n        require(amount &gt; 0, &quot;Invalid amount&quot;);\n        require(duration &gt; 0, &quot;Invalid duration&quot;);\n        \n        vestings[beneficiary] = Vesting({\n            amount: amount,\n            startTime: block.timestamp,\n            duration: duration,\n            released: 0,\n            revocable: revocable,\n            revoked: false\n        });\n        \n        token.transferFrom(msg.sender, address(this), amount);\n    }\n    \n    function release(address beneficiary) external {\n        Vesting storage vesting = vestings[beneficiary];\n        require(vesting.amount &gt; 0, &quot;No vesting found&quot;);\n        require(!vesting.revoked, &quot;Vesting revoked&quot;);\n        \n        uint256 releasable = calculateReleasable(vesting);\n        require(releasable &gt; 0, &quot;Nothing to release&quot;);\n        \n        vesting.released += releasable;\n        token.transfer(beneficiary, releasable);\n    }\n    \n    function calculateReleasable(Vesting memory vesting) internal view returns (uint256) {\n        if (block.timestamp &lt; vesting.startTime) {\n            return 0;\n        }\n        \n        uint256 timeElapsed = block.timestamp - vesting.startTime;\n        if (timeElapsed &gt;= vesting.duration) {\n            return vesting.amount - vesting.released;\n        }\n        \n        return (vesting.amount * timeElapsed \/ vesting.duration) - vesting.released;\n    }\n}\n\n\/\/ After optimization\ncontract TokenVestingOptimized {\n    \/\/ Pack related variables together\n    struct Vesting {\n        uint96 amount;     \/\/ Reduced from uint256 since 96 bits is usually sufficient\n        uint48 startTime;  \/\/ Reduced from uint256, sufficient until year 2083\n        uint48 duration;   \/\/ Reduced from uint256\n        uint48 released;   \/\/ Packed in same slot as flags\n        bool revocable;    \/\/ Packed with released\n        bool revoked;      \/\/ Packed with released\n    }\n    \n    mapping(address =&gt; Vesting) public vestings;\n    IERC20 public immutable token; \/\/ Made immutable\n    \n    constructor(IERC20 _token) {\n        token = _token;\n    }\n    \n    function createVesting(\n        address beneficiary,\n        uint96 amount,\n        uint48 duration,\n        bool revocable\n    ) external {\n        if (beneficiary == address(0)) revert InvalidBeneficiary();\n        if (amount == 0) revert InvalidAmount();\n        if (duration == 0) revert InvalidDuration();\n        \n        \/\/ Use assembly for efficient storage writes\n        assembly {\n            mstore(0x00, beneficiary)\n            mstore(0x20, vestings.slot)\n            let slot := keccak256(0x00, 0x40)\n            \n            \/\/ Pack values into a single storage write\n            sstore(\n                slot,\n                or(\n                    or(\n                        shl(160, amount),\n                        shl(64, timestamp())\n                    ),\n                    or(\n                        shl(16, duration),\n                        revocable\n                    )\n                )\n            )\n        }\n        \n        \/\/ Single external call\n        if (!token.transferFrom(msg.sender, address(this), amount)) revert TransferFailed();\n    }\n    \n    function release(address beneficiary) external {\n        Vesting storage vesting = vestings[beneficiary];\n        if (vesting.amount == 0) revert NoVesting();\n        if (vesting.revoked) revert VestingRevoked();\n        \n        uint256 releasable;\n        \n        \/\/ Optimized calculation using assembly\n        assembly {\n            let timeElapsed := sub(timestamp(), sload(add(vesting.slot, 1)))\n            let duration := sload(add(vesting.slot, 2))\n            \n            switch gt(timeElapsed, duration)\n            case 0 {\n                \/\/ Not fully vested\n                releasable := div(mul(sload(vesting.slot), timeElapsed), duration)\n            }\n            default {\n                \/\/ Fully vested\n                releasable := sload(vesting.slot)\n            }\n            \n            \/\/ Subtract already released amount\n            releasable := sub(releasable, sload(add(vesting.slot, 3)))\n        }\n        \n        if (releasable == 0) revert NothingToRelease();\n        \n        \/\/ Update released amount\n        vesting.released += uint48(releasable);\n        \n        \/\/ Single external call\n        if (!token.transfer(beneficiary, releasable)) revert TransferFailed();\n    }\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ Before optimization<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">TokenVesting<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">struct<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Vesting<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">startTime<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">released<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">revocable<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">revoked<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">mapping<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Vesting<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vestings<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4FC1FF\">IERC20<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">createVesting<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">revocable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\"> != <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #CE9178\">&quot;Invalid beneficiary&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Invalid amount&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Invalid duration&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">vestings<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">Vesting<\/span><span style=\"color: #D4D4D4\">({<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">amount:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">startTime:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">block<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">timestamp<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">duration:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">released:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">revocable:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">revocable<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">revoked:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        });<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">transferFrom<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">msg<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">sender<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">this<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">release<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">Vesting<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">storage<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">vestings<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;No vesting found&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(!<\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">revoked<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Vesting revoked&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">releasable<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">calculateReleasable<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">releasable<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Nothing to release&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">released<\/span><span style=\"color: #D4D4D4\"> += <\/span><span style=\"color: #9CDCFE\">releasable<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">transfer<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">releasable<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">calculateReleasable<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">Vesting<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">internal<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">view<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">block<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">timestamp<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">startTime<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">timeElapsed<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">block<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">timestamp<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">startTime<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">timeElapsed<\/span><span style=\"color: #D4D4D4\"> &gt;= <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">released<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #9CDCFE\">timeElapsed<\/span><span style=\"color: #D4D4D4\"> \/ <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">) - <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">released<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ After optimization<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">TokenVestingOptimized<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #6A9955\">\/\/ Pack related variables together<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">struct<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Vesting<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint96<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">;     <\/span><span style=\"color: #6A9955\">\/\/ Reduced from uint256 since 96 bits is usually sufficient<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint48<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">startTime<\/span><span style=\"color: #D4D4D4\">;  <\/span><span style=\"color: #6A9955\">\/\/ Reduced from uint256, sufficient until year 2083<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint48<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">;   <\/span><span style=\"color: #6A9955\">\/\/ Reduced from uint256<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint48<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">released<\/span><span style=\"color: #D4D4D4\">;   <\/span><span style=\"color: #6A9955\">\/\/ Packed in same slot as flags<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">revocable<\/span><span style=\"color: #D4D4D4\">;    <\/span><span style=\"color: #6A9955\">\/\/ Packed with released<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">revoked<\/span><span style=\"color: #D4D4D4\">;      <\/span><span style=\"color: #6A9955\">\/\/ Packed with released<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">mapping<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Vesting<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vestings<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4FC1FF\">IERC20<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">immutable<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #6A9955\">\/\/ Made immutable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">constructor<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4FC1FF\">IERC20<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_token<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_token<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">createVesting<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint96<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint48<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">revocable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InvalidBeneficiary<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InvalidAmount<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InvalidDuration<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Use assembly for efficient storage writes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">assembly<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">mstore<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0x00<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">mstore<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0x20<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">vestings<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">slot<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">let<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">slot<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #4EC9B0\">keccak256<\/span><span style=\"color: #D4D4D4\">(0x00, 0x40)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #6A9955\">\/\/ Pack values into a single storage write<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">sstore<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">slot<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #DCDCAA\">or<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #DCDCAA\">or<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #DCDCAA\">shl<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">160<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #DCDCAA\">shl<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">64<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">timestamp<\/span><span style=\"color: #D4D4D4\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #DCDCAA\">or<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #DCDCAA\">shl<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">16<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #9CDCFE\">revocable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Single external call<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">transferFrom<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">msg<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">sender<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">this<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">)) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">TransferFailed<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">release<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">external<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">Vesting<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">storage<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">vestings<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">NoVesting<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">revoked<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">VestingRevoked<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">releasable<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Optimized calculation using assembly<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">assembly<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">let<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">timeElapsed<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #4EC9B0\">sub<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">timestamp<\/span><span style=\"color: #D4D4D4\">(), <\/span><span style=\"color: #4EC9B0\">sload<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">slot<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">)))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">let<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #4EC9B0\">sload<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">slot<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">switch<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">gt<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">timeElapsed<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">case<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #6A9955\">\/\/ Not fully vested<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C8C8C8\">releasable<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #DCDCAA\">div<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">mul<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">sload<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">slot<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #9CDCFE\">timeElapsed<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #9CDCFE\">duration<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">default<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #6A9955\">\/\/ Fully vested<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C8C8C8\">releasable<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #DCDCAA\">sload<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">slot<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #6A9955\">\/\/ Subtract already released amount<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C8C8C8\">releasable<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #DCDCAA\">sub<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">releasable<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">sload<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">slot<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">)))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">releasable<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">NothingToRelease<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Update released amount<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">vesting<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">released<\/span><span style=\"color: #D4D4D4\"> += <\/span><span style=\"color: #DCDCAA\">uint48<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">releasable<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Single external call<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">transfer<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">beneficiary<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">releasable<\/span><span style=\"color: #D4D4D4\">)) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">TransferFailed<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Best_Practices_and_Recommendations\"><\/span>Best Practices and Recommendations<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Always batch operations to minimize storage writes and external calls<\/li>\n\n\n\n<li>Use appropriate variable sizes and pack them efficiently<\/li>\n\n\n\n<li>Use <code>unchecked<\/code> blocks where overflow\/underflow cannot happen<\/li>\n\n\n\n<li>Reduce SLOADs by caching storage in memory<\/li>\n\n\n\n<li>Define and use custom errors instead of revert strings<\/li>\n\n\n\n<li>Less loops &#8211; if possible, find gas efficient alternatives<\/li>\n\n\n\n<li>Assembly for complex logic\/ critical paths<\/li>\n\n\n\n<li>Profile gas regularly during development<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Gas optimization is an iterative process that needs to take into consideration the specific requirements and usage patterns of your contract. Some optimizations may seem minor in isolation, but taken together can make a big difference in operational costs. Always measure the impact of optimizations and ensure they do not compromise on readability or security in your contract. Try out our gas tracker tool to check the amount of gas consumption by your smart contract <a href=\"https:\/\/metaschool.so\/gastracker\" data-type=\"link\" data-id=\"https:\/\/metaschool.so\/gastracker\">here<\/a>.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":24,"featured_media":12042,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[17],"tags":[],"class_list":["post-11965","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blockchain"],"_links":{"self":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts\/11965","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/users\/24"}],"replies":[{"embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/comments?post=11965"}],"version-history":[{"count":4,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts\/11965\/revisions"}],"predecessor-version":[{"id":12043,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts\/11965\/revisions\/12043"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/media\/12042"}],"wp:attachment":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/media?parent=11965"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/categories?post=11965"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/tags?post=11965"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}