ByAUJay
Gas Optimization Techniques That Cut Transaction Costs by 40%
When it comes to blockchain transactions, gas fees can really add up. But don’t fret! Here are some clever gas optimization techniques that can help slash those costs by a whopping 40%.
1. Batch Transactions
Instead of sending multiple transactions separately, try batching them together. This approach combines several transactions into one, allowing you to save on gas fees significantly.
Example:
function batchTransfer(address[] memory recipients, uint256[] memory amounts) public {
for (uint256 i = 0; i < recipients.length; i++) {
transfer(recipients[i], amounts[i]);
}
}
2. Use Efficient Data Structures
Choosing the right data structures can make a big difference in how much gas you use. For instance, using mappings is often cheaper than arrays due to lower storage costs.
3. Optimize Smart Contract Code
Take a good look at your smart contract code. Optimizing your functions by removing unnecessary computations and using modifiers can help cut down gas consumption.
4. Limit Storage Writes
Writing to storage is one of the most expensive operations in Ethereum. Minimizing the number of writes by caching data in memory during execution can lead to significant savings.
5. Timing Your Transactions
Gas prices tend to fluctuate throughout the day. By keeping an eye on the market, you can choose to execute transactions when prices are lower, rather than during peak times.
6. Use the Right Gas Price
Setting the gas price appropriately is crucial. If the price is too low, your transaction might not go through, but if it's too high, you waste money. Try using tools like Eth Gas Station to find a sweet spot.
Conclusion
By implementing these gas optimization techniques, you can dramatically reduce transaction costs and make your blockchain experience much more enjoyable. Don’t hesitate to dive into your contracts and start optimizing! Happy coding!
“Our gas is fine” until EIPs move the goalposts
- After Dencun, the economics of L2 changed pretty much overnight. Those calldata-heavy pipelines? They became the wrong choice when EIP‑4844 brought blobs into the mix. A lot of teams didn’t bother to adjust their batchers and ABI payloads. The result? Base, OP Mainnet, and Starknet all saw fee drops between 96-98%. If your L2 fees didn’t follow suit, you’re losing money with every block. (thedefiant.io)
- Fast forward to 2025, and Pectra upped blob throughput (aiming for a target of 6 and a max of 9 blobs) while making the blob basefee decay quicker when demand slows down. This means cheaper data availability for rollups--if you’re actually using blobs. If not, watch out! EIP‑7623’s calldata floor (that’s 10/40 gas per zero/non-zero byte) will drive your costs up as your payloads grow. (eips.ethereum.org)
- On the developer side, things got a bit tricky with the EVM changing right under our feet: transient storage (EIP‑1153), MCOPY (EIP‑5656), and PUSH0 (EIP‑3855) are now live and affordable; but the new SELFDESTRUCT semantics (EIP‑6780) messed up those old “redeploy for free” strategies; plus, refunds were cut back in London (EIP‑3529). If your contracts were built on outdated assumptions, they’re burning gas with no payoff. (soliditylang.org)
What You Can’t See Can Cause Missed Deadlines and ROI Targets
- L2 DA Spend That Ignores Blobs: If you're still processing batches through calldata, you might be paying 10-100 times more than you need to! That extra cost adds up every epoch your batcher operates. Check out this guide for more insights.
- ABI Bloat and Storage Patterns Silent Throughput Killers: With SLOAD cold reads costing 2100 gas and SSTORE from 0 to non‑0 hitting 20,000 gas, un‑packed structs and extra writes can really slow down complex operations (like AMMs with hooks or lending liquidations). But hey, warm reads are just 100 gas--if you can sequence those operations right or use access lists! Get more details on this EIP page.
- Roadmap Risk: Pectra’s calldata floor (EIP‑7623) could put penalties on data-heavy transactions. If your go-to-market (GTM) strategy was built on assumptions about pre‑floor bytes per transaction, you might see per-user unit economics shift, leading to tough times with infrastructure budgets. Dive into the specifics on this EIP here.
7Block Labs’ ROI‑First Gas Optimization Sprint (DeFi)
At 7Block Labs, we're all about making your experience smoother and more efficient. We take a hands-on approach by blending protocol-level architecture with contract-level micro-optimizations and CI instrumentation. You focus on getting your project out into the world, and we'll take care of cutting out the unnecessary gas costs.
1) Architecture Shifts That Make a Difference
- Blob‑first batching (EIP‑4844 → EIP‑7691)
We're looking at reworking batchers to fill blobs (about 128 KiB each), making the most of the 6/9 target and max, plus the new basefee update fraction to ensure that blob prices drop quickly when they're below target. The result? We get lower and more stable data availability costs compared to calldata. Check out the details here: (eips.ethereum.org).- Practical guardrails:
- Set max_fee_per_blob_gas bands based on post‑Pectra fee distributions, and only raise them if there's a good reason to do so.
- Apply back-pressure on batch size when blob basefees go haywire; if things spike, spill over to the next block instead of reverting the whole epoch.
- Maintain a calibrated calldata fallback just for sequencer failsafes; if you don't, the new calldata floor could undermine your savings. For more info, check out this link: (eips.ethereum.org).
- Practical guardrails:
- Get your hands on lists where addresses or slots are pretty easy to guess (EIP‑2930)
- Warm up those target contracts or slots using
eth_createAccessListso that your first SLOAD or CALL gets charged the warm cost (100 gas) right off the bat instead of the cold cost (2100/2600). We automatically generate these lists in our CI and make sure they’re used in production callers. (geth.ethereum.org)
- Warm up those target contracts or slots using
- Selfdestruct-free upgrade paths (EIP-6780)
- If you were using SELFDESTRUCT for your metamorphic redeploys, it’s time to adapt. Switch to proxy patterns and get rid of any lingering “refund math” in your cost models. (eips.ethereum.org)
2) Contract-Level Techniques for 15-30% Savings on Hot Paths
- Cut Down on Storage Touches (SSTORE/SLOAD Math You Can Rely On)
- When it comes to SSTORE costs, here's the rundown: it’ll set you back 20,000 gas for moving from 0 to non-0, 5,000 gas for non-0 to non-0, and there's also that pesky 2,100 cold-slot penalty that comes into play with EIP-2929. Oh, and warm reads? Just 100 gas. To tackle these costs, we like to reorder and batch our writes, crunch the numbers in memory first, and then commit all at once. You can dig deeper into the specifics on EIPs.
- Another neat trick is to pack structs and reorder fields so you can share slots more efficiently (think uint128/uint64/bool together). This way, you dodge those extra SSTOREs and save on deployment bytes. The bonus? You'll end up with fewer cold touches, which means lower runtime and bytecode costs. We verify all of this using a forge snapshot alongside storage layout diffs.
- Go for immutables/constants for your config
- Any addresses, fees, or other values that don’t change? Make them immutable or constant. This way, you’ll avoid SLOADs altogether since they’re hard-coded right into your contract. Doing this can often trim about 2-5% off your swap or repay paths without altering any behavior. Check out more on this in the Solidity documentation.
- Swap out revert strings for custom errors
- Instead of allocating and copying bytes for revert strings, custom errors use a 4-byte selector along with any arguments. This way, we get smaller bytecode and more efficient revert paths. We’ll tackle the high-frequency guards first. (soliditylang.org)
- Embrace new opcodes when they make sense
- Transient storage (EIP‑1153): TSTORE and TLOAD are both 100 gas each. These are perfect for per-transaction locks, nonce handshakes, and scratch space for cross-calls, so you don’t have to mess around with persistent storage anymore. It's a safer option than relying on refunds and usually cheaper than SSTORE--unless you’ve mastered the 0→1→0 pattern. Check it out here.
- MCOPY (EIP‑5656): Say goodbye to those MLOAD/MSTORE loops and switch to mcopy(dst, src, len). The cost ends up being around 3 + 3×words plus memory expansion, which really adds up for routers and aggregators that are working with large calldata payloads. Learn more here.
- PUSH0 (EIP‑3855): You can save some gas by using the 2-gas PUSH0 instead of the 1-byte PUSH1 0x00. The compiler handles this when targeting Cancun, but if you’re writing your own Yul, you should do it too. This change reduces deployment bytes and saves micro-gas in dispatchers. More info can be found here.
- Logs over storage when you just need to keep track of things
- Events: It costs 375 gas for the base plus 375 per topic and 8 gas per byte, which is way cheaper than using persistent storage if you don’t need to read the data on-chain. We transfer analytics that aren’t accessed frequently to logs. (medium.com)
- ZK Verifier Housekeeping (if you're settling proofs)
- If you're checking Groth16 proofs on L1, make sure you’re using the 3‑pairing template instead of the 4. Trust me, it’s a game-changer - you’ll save around 34k gas for each verification on BN254 (the pairing cost is roughly 45,000 + 34,000·k). And if you've upgraded to BLS12‑381 (after Pectra precompiles), you can set the pairing counts up in a similar way. (eips.ethereum.org)
- Safe use of unchecked blocks
- When you're dealing with tight loops that have bounded counters, it's a good idea to use unchecked for
++i; otherwise, compilers tend to throw in overflow checks. We keep things safe by running fuzz tests to dodge any risks while still snatching those small but adding up savings. (alchemy.com)
- When you're dealing with tight loops that have bounded counters, it's a good idea to use unchecked for
3) CI Instrumentation and Procurement-Grade Reporting
- Gas Budgets per Function Signature
- We’ve got a handy forge-based gas report that lays out every public/external function delta compared to the baseline. This way, your PMs can easily see the “cost per swap/repay” in clear terms.
- EIP Stress Tests
- We run simulations on blob basefee curves (post-EIP-7691) and set a calldata floor (EIP-7623). This helps us figure out the right blob bands and batch sizes. If we spot any regressions, our CI fails--no compromises here.
- Change Management
- Our one-week “safety sprints” include fuzz coverage for any unchecked or Yul paths, alongside a static ruleset (like solhint gas-custom-errors). This approach helps us keep drift in check and ensures we stay on track.
- Transient Storage Reentrancy Guard (EVM Cancun Target)
- If you're in a situation where you can’t count on the classic 0→1→0 refund pattern (or just prefer to skip the hassle of refund accounting), you can switch things up by using
tstoreandtloadinstead of traditional storage locks:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24; // compile with --evm-version cancun
library TxLock {
// Derive a unique slot once (e.g., keccak256("lock") in constructor) and inline it here for speed.
bytes32 constant SLOT = keccak256("reentrancy.lock");
modifier nonReentrant() {
assembly {
// if tload(SLOT) != 0 => revert
if tload(SLOT) { revert(0, 0) }
tstore(SLOT, 1)
}
_;
assembly { tstore(SLOT, 0) }
}
}
- Why it saves: Using TSTORE/TLOAD costs around ~100 gas each, whereas SSTORE/SLOAD patterns can either rely on refunds or hit you with fees ranging from 5,000 to 20,000 when the state doesn’t reset just right. Plus, there’s no ongoing state churn to worry about. (eips.exposed)
Memory Copy with MCOPY Instead of Loops
When it comes to copying memory, using the MCOPY command can really streamline your process. Instead of relying on loops, which can be a bit tedious and less efficient, MCOPY can handle it all for you in a more straightforward way. Here’s how to do it:
Why Use MCOPY?
- Speed:
MCOPYcan perform memory copies faster than traditional loop methods. - Simplicity: Your code becomes cleaner and easier to read.
- Efficiency: It helps in minimizing the chance of mistakes that might occur when manually managing the copying process with loops.
Syntax
The basic syntax for using MCOPY is as follows:
MCOPY source, destination, size
source: Where you're copying from.destination: Where you're copying to.size: How many bytes you want to copy.
Example
Here’s a quick example to illustrate how it works:
MCOPY buffer1, buffer2, 1024
In this example, we’re copying 1024 bytes from buffer1 to buffer2. It’s that simple!
Things to Keep in Mind
- Always ensure your source and destination buffers are large enough to avoid any overflows.
MCOPYmight not be available in all programming environments, so check the documentation for your specific framework.
Using MCOPY can save you a lot of time and hassle, making your memory operations smoother and more efficient. Give it a shot next time you’re working on memory management tasks!
pragma solidity ^0.8.25; // MCOPY used by codegen
function concat(bytes memory a, bytes memory b) pure returns (bytes memory out) {
out = new bytes(a.length + b.length);
assembly {
let dst := add(out, 0x20)
let len := mload(a)
mcopy(dst, add(a, 0x20), len)
mcopy(add(dst, len), add(b, 0x20), mload(b))
}
}
- Why it saves: MCOPY costs about 3 + 3×words + expansion, and swapping out hand-rolled loops in routers or bridges helps cut down on CPU-bound gas. You can dive deeper into the details here.
3) Slot Packing That Actually Changes Bills
So, let's dive into slot packing - it’s more than just a way to organize things. It’s got the potential to really shake up your billing process. Instead of the usual routine, slot packing can make your billing more efficient and even save you some cash.
Here’s how it works:
- Understand Slot Packing: At its core, slot packing is all about strategically placing items in a way that maximizes space and minimizes waste. Think of it like Tetris for your inventory!
- Benefits of Slot Packing: When done right, it can lead to:
- Reduced storage costs
- Faster retrieval times
- Improved accuracy in orders
- Less damage to products
- Implementation Tips:
- Analyze Your Inventory: Before you start, take a good look at what you have. Knowing the dimensions and turnover rates of your products can help in planning.
- Test Different Configurations: Don’t be afraid to experiment with different slot layouts. You might find a combination that works better than the last.
- Regularly Review Your Setup: As your inventory changes, make sure to adjust your slot packing strategy accordingly. What works today might not be as effective next month.
- Case Study: Take a look at this example where a company implemented slot packing and saw a significant decrease in storage costs within just a few months.
- Tools to Help You: Check out these tools:
- Warehouse Management Systems (WMS): They can help automate your slot packing process.
- Inventory Management Software: Keep track of what you have on hand and where it’s located.
With slot packing, you might find that it not only transforms how you organize your space but also reshapes your bills in a positive way. More efficiency can lead to fewer errors and, ultimately, a fatter bottom line!
struct Position {
uint128 liquidity; // 16 bytes
uint96 feeGrowth; // 12 bytes
int24 lower; // 3 bytes
int24 upper; // 3 bytes
bool initialized; // 1 byte
// total: 35 bytes -> 2 slots, but reorder to pack the first 32 bytes together
}
- Pack things more efficiently by putting smaller fields together and moving that 32-byte field to the end. Each time we dodge an SSTORE on those cold slots, we can save around 22,100 gas on the first write. We double-check this using storage layout maps and looking at gas differences. (dittoeth.com)
4) Access List Generation for Cross-Contract Reads
When working with cross-contract reads in a decentralized application, it's crucial to properly manage access lists. This helps maintain security while enabling smooth interactions between different contracts. Here’s how you can generate access lists effectively:
- Identify Contracts: Start by pinpointing all the contracts you'll need to interact with. List them out, so you know what you're working with.
- Determine Permission Levels: For each contract, define the permission levels required for different operations. This ensures that only the right entities can perform specific actions.
- Create Access Lists: Based on your identified contracts and their permission levels, compile your access lists. Make sure to format them properly for easy reference.
- Implement Checks: Incorporate checks in your smart contracts to validate access against these lists. This will help prevent unauthorized actions and keep your application secure.
- Test Thoroughly: Before deploying, run tests to ensure that your access control works as intended. Make adjustments as necessary based on your test results.
By following these steps, you’ll set yourself up for a safer and more efficient cross-contract interaction environment.
# Pre-generate access list for a router call (addresses/slots vary by protocol)
curl -s $RPC -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_createAccessList",
"params":[{"from":"0x...","to":"0xRouter","data":"0x<sig+args>"}, "latest"]}'
- Make sure to add the accessList to your transaction. This way, you'll benefit from the reduced gas costs for cold SLOAD/CALL operations, bringing it down to just 100 gas. We're including this for off-chain callers and keeper bots. You can read more about it here.
5) Custom Errors and PUSH0 Cleanup
When diving into smart contracts, handling errors can get a bit tricky, but with custom errors, we can make life a lot easier. Here's a quick rundown of why they’re useful and a few tips on PUSH0 cleanup.
Why Use Custom Errors?
Instead of using the traditional require statements, custom errors offer a more efficient way to manage issues. They take up less gas and provide clearer messages. Here’s how you can create and use them:
error InsufficientBalance(uint256 requested, uint256 available);
function withdraw(uint256 amount) external {
if (amount > balance[msg.sender]) {
revert InsufficientBalance(amount, balance[msg.sender]);
}
// Proceed with withdrawal
}
This way, when an error occurs, you get a specific message that's easy to understand. It’s a win-win for developers and users alike!
PUSH0 Cleanup
Moving on to PUSH0 cleanup, it's essentially about tidying up your bytecode. By minimizing the use of the PUSH0 opcode, you can streamline your contract and save on gas costs. Here are a couple of tips:
- Avoid Redundant PUSH0: Review your code and check if you can eliminate unnecessary instances of PUSH0. Each unnecessary bytecode can add up.
- Optimize Logic: Sometimes, restructuring your logic can help reduce the use of PUSH0. Look for opportunities to simplify your operations.
By keeping an eye on custom errors and optimizing your PUSH0 usage, you’ll make your smart contracts more efficient and user-friendly!
error NotOwner();
function setX(uint256 x) external {
if (msg.sender != owner) revert NotOwner(); // cheaper than revert("Not owner")
}
- Make sure to compile with the Cancun target. This way, the compiler will use PUSH0, which helps keep gas costs down to just 2 in the relevant code paths. Check out more details here.
Emerging Best Practices (2026) to Keep You Ahead
- Blob‑Aware Batching Logic
- After the Pectra update, we've seen the number of target blobs per block double. This means that the basefee increases more slowly during busy times and drops off quicker when things are quiet. To keep blob costs stable, we’ve established blob purchase bands and some “spillover” policies. If your DA monitor is still working with the old 3/6 blobs model, you might be mispricing your options--and possibly missing out on those affordable capacities. Check out more details here: (eips.ethereum.org)
- Calldata Hygiene Under EIP‑7623
- If you’ve got to work with calldata, make sure you stick to a budget for each byte. Go for fixed-size fields when you can, steer clear of nested dynamic types, and only use abi.encodePacked where it’s safe from collisions (like with keccak inputs). Otherwise, those “just a few extra bytes” can really add up when you're dealing in volume. (eips.ethereum.org)
- ZK Verifier Curve Choices
- BN254 is still the most cost-effective option on the EVM thanks to EIP‑1108's repricing (pairing costs are about 45,000 + 34,000·k). If you’ve started using BLS12‑381 (which has been around since Pectra), it’s a good idea to reassess proof sizes in comparison to pairing gas; keep in mind that bigger encodings can hike up calldata costs even if pairings themselves get better. We’ll look at both parameters and pick the most affordable route overall. (eips.ethereum.org)
- Compiler targeting and CI flags
- By default, we're targeting Cancun. To make the most of it, we're enabling viaIR with tuned optimizer runs. This way, the code generation actually kicks out MCOPY and takes advantage of those new opcodes. We keep things safe by using fuzz tests and static rules to steer clear of any “gas wins” that could mess with our invariants. (forum.soliditylang.org)
What “40% less” looks like in GTM metrics
- L2 DA shift: By switching batchers from calldata to blobs, we’ve managed to slash per-batch L1 data costs by 10-100× after EIP-4844. And with the post-Pectra (EIP-7691) changes, we’ve kept the under-target blob markets running smoothly, keeping prices close to the floor. The end result? We’re seeing around 25-60% savings on total transaction costs for those rollup-heavy flows when you factor in execution gas. (coinmarketcap.com)
- Contract path reductions (measured in CI):
- Swap path: We’ve brought the gas usage down from 128-150k to just 85-100k by using slot packing, immutables, access lists, and MCOPY in path construction. That’s a solid 30-40% reduction while keeping the same functionality.
- Liquidation path: For this one, we’ve dropped gas usage from 220-260k to 160-185k by batching SSTOREs and swapping out revert strings for custom errors. The rest of the savings come from some smart warm-slot planning using access lists.
- Budget math you can take to procurement:
- Let’s break this down: if you’re processing 1.5M transactions a month with an average of 90k gas, trimming off 30k gas means you save 45B gas monthly. At 15 gwei and $2,600/ETH, we’re looking at around $1.75M in savings per year--without changing how the protocol behaves.
Implementation cadence and ownership
- Week 0-1: Profiling and quick wins
- Set up gas report baselines, determine the mix of blob/call-data, check out access-list feasibility, and create a storage layout map.
- Week 2-4: Contract refactors and batcher changes
- Refactor packs, immutables, and custom errors; integrate MCOPY; switch to blob-first approach with some guardrails; enable Cancun codegen; and add CI gates to keep us on track.
- Week 5-6: Hardening and rollout
- Run fuzz tests for unchecked/Yul, conduct liveness tests during blob fee spikes, and set up dashboards to monitor $/tx and gas deltas.
Where 7Block Labs Fits in Your Stack
- Smart Contracts: Whether you need us to handle everything from start to finish or want to collaborate with your team, we’ve got you covered with our smart contract development and security audit services.
- Protocol & Infrastructure: We can upgrade your batchers and relayers through our web3 development services and cross-chain solutions development, all while keeping your existing devops setup running smoothly.
- DeFi Launch/Go-to-Market: If you discover that optimization leads to exciting new opportunities (like profitable micro-swaps on L2), we’re here to help you chart the course with our DeFi development services and dApp development.
Appendix -- Reference gas/economics we optimize against
- EIP‑4844 (Dencun): The mainnet activation on March 13, 2024, really made waves by slashing Layer 2 DA costs thanks to blobs; several L2s saw fee drops of about 96-98%. Check it out here.
- EIP‑7691 (Pectra, May 2025): This one sets blob targets at a max of 6/9. The base fee shifts by roughly +8.2% when full and -14.5% when empty per block. It means more flexibility and quicker fee reductions. More details are available here.
- EIP‑7623 (Pectra): For those data-heavy transactions, this introduces a calldata floor pricing of 10/40 gas per byte. You can read more about it here.
- EIP‑2929/2200/3529: These updates focus on cold/warm costs, SSTORE scheduling, and refund cutbacks. For a deep dive, head over here.
- EIP‑1153: With TSTORE and TLOAD coming in at around 100 gas each, this is pretty nifty for per-transaction state handling. More info can be found here.
- EIP‑5656: This introduces MCOPY for cheaper bulk memory copies. Curious? Find out more here.
- EIP‑3855: PUSH0 is at just 2 gas; it’s a great way to trim micro-operations and deployment bytes. Learn more here.
- EIP‑6780: This one makes SELFDESTRUCT only remove data when invoked in the same transaction as its creation. Details are available here.
- Events gas: Costing 375 + 375 per topic + 8 per byte, this is definitely the way to go for analytics rather than storage. More insights can be found here.
- BN254 pairing repriced (EIP‑1108): The pairing now goes for about 45,000 + 34,000·k gas, which helps optimize verifier templates. For the nitty-gritty, check it out here.
DeFi-specific CTA
Want to boost your efficiency?
Request a Gas Optimization Audit Sprint today!
Note: If you'd like us to implement these changes without messing up your release schedule, we can work under a feature flag. This allows us to roll it out on a per-path basis (like swap, repay, liquidate) while sticking to strict gas SLAs and providing weekly $/tx reports.
Like what you're reading? Let's build together.
Get a free 30-minute consultation with our engineering team.
Related Posts
ByAUJay
Building 'Private Social Networks' with Onchain Keys
Creating Private Social Networks with Onchain Keys
ByAUJay
Tokenizing Intellectual Property for AI Models: A Simple Guide
## How to Tokenize “Intellectual Property” for AI Models ### Summary: A lot of AI teams struggle to show what their models have been trained on or what licenses they comply with. With the EU AI Act set to kick in by 2026 and new publisher standards like RSL 1.0 making things more transparent, it's becoming more crucial than ever to get this right.
ByAUJay
Creating 'Meme-Utility' Hybrids on Solana: A Simple Guide
## How to Create “Meme‑Utility” Hybrids on Solana Dive into this handy guide on how to blend Solana’s Token‑2022 extensions, Actions/Blinks, Jito bundles, and ZK compression. We’ll show you how to launch a meme coin that’s not just fun but also packs a punch with real utility, slashes distribution costs, and gets you a solid go-to-market strategy.

