7Block Labs
Security

ByAUJay

Web3 Application Penetration Testing: Securing Smart Contracts and Frontends

Why pen‑test Web3 differently in 2025

Over the last couple of years, the biggest risks we've seen didn’t just come from on-chain logic; they were also tied to UI and software supply chain issues:

  • The npm package for Ledger Connect Kit got hijacked after someone compromised a maintainer's session, which led to tons of dapp frontends being armed with a drainer payload in just a few hours. You can read more about it here.
  • Big-name crypto sites like CoinMarketCap and Cointelegraph faced front-end code injections that created fake wallet prompts--no protocol bugs were involved. Check out the details here.
  • Phishing and drainer operations really took off; Scam Sniffer reported around ~$494M stolen through wallet-drainer campaigns just in 2024! You can find more info here.

Meanwhile, the base layer has gone through some changes: Dencun (EIP‑4844) has revamped how L2 data gets published; EIP‑6780 has put some boundaries on SELFDESTRUCT behavior; the Solidity compilers have upped their game with better performance and safety features; and fresh account-abstraction patterns (like ERC‑4337 and the EIP‑7702 proposal) have broadened the attack surface. Make sure your pen test takes these updates into account. (eips.ethereum.org)


What changed technically--and why it affects your test scope

  • EIP‑4844 (proto‑danksharding) has shifted rollup data to these “blobs” that are super affordable and get pruned after about 18 days; just keep in mind that the EVM can’t actually read what's inside those blobs. While this is fantastic for keeping fees low, it does change some of the assumptions around data availability and how your app behaves in the mempool. It’s a good idea to run some pen tests to make sure you’re not depending on blob persistence or EVM access. (eips.ethereum.org)
  • EIP‑6780 has made some changes to SELFDESTRUCT: unless you're doing "create-and-destroy in the same transaction," it won’t delete any code or storage anymore--now it just transfers ETH. This tweak breaks the older “metamorphic” patterns and could impact how you handle upgrades and downgrades, so make sure your tests take this into account. (eips.ethereum.org)
  • For Solidity versions 0.8.25-0.8.29, the compiler and EVM tweaks are pretty significant for your security and performance tests--MCOPY is introduced in 0.8.25 to speed up byte handling, there are new custom errors in require, some serious performance improvements in the big IR pipeline (0.8.26-0.8.28), plus an experimental EOF backend in 0.8.29. Make sure to double-check your build settings, optimizer, and EVM target in CI; it’s a good move to fuzz test under those specific settings. (soliditylang.org)
  • When it comes to account abstraction, ERC‑4337 is pretty much everywhere now (think smart accounts, paymasters, and bundlers), but it also opens up new doors for DoS and griefing attacks. EIP‑7702 is currently being discussed as a potential way for EOAs to temporarily behave like smart wallets--definitely consider its implications (and current status) when you're updating your threat models. (docs.erc4337.io)

A Web3 pen‑testing scope that actually maps to real risk

We break assessments down into three key areas:

  1. On-chain contracts (using Solidity, Vyper, or Rust on EVM, Layer 2s, or alternative Layer 1s)
  2. Frontend and build supply chain (think npm, CI/CD, scripts, and CSP)
  3. Off-chain crypto plumbing (like AA wallets, relayers/paymasters, oracles, indexers, and bridges/L2 messaging)

The key lies in exploring the gaps between these areas, as that's where most incidents tend to start.


Smart contracts: tests and checks that catch today’s failures

  1. Upgradeability and Storage Layout
  • For UUPS/Transparent/Diamond proxies, make sure to check the authorizeUpgrade controls, EIP‑1967 slots, and storage gaps while also preventing any re-entrancy issues with initializers. It’s a good idea to run a storage-collision comparison between versions. Don’t forget to ensure that there's no unintentional dependence on SELFDESTRUCT-based redeploy patterns that might be messed up by EIP‑6780. You can dive into more details here.

Example: Hardened UUPS Gate

The Hardened UUPS Gate is a smart contract upgrade mechanism which enhances the security of the upgradeable proxy patterns. It’s built to prevent certain potential vulnerabilities that can arise when using the traditional UUPS (Universal Upgradeable Proxy Standard) model.

Here’s a quick rundown of its benefits:

  • Enhanced Security: By solidifying the upgrade process, it reduces risks associated with unauthorized upgrades.
  • Easier Upgrades: Developers can upgrade contracts smoothly while maintaining a higher security posture.
  • Compatibility: Works seamlessly with existing UUPS setups, making it an easy plug-and-play solution.

To implement a hardened UUPS gate, you’ll want to follow some best practices:

  1. Audit Your Contracts: Always have your contracts audited by a trusted third party.
  2. Use Multi-Sig for Upgrades: Incorporate multi-signature wallets to add an extra layer of security for upgrade proposals.
  3. Set Time Delays: Introduce time delays for upgrades to give stakeholders a chance to react if something seems off.

Here’s a basic structure of a hardened UUPS gate in Solidity:

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";

contract MyContract is UUPSUpgradeable {
    function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}

    // Your contract logic here
}

With these precautions in place, you’ll help ensure that your upgradeable contracts are both flexible and secure. For more details, check out the OpenZeppelin documentation.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {UUPSUpgradeable} from "openzeppelin-contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {AccessControlUpgradeable} from "openzeppelin-contracts-upgradeable/access/AccessControlUpgradeable.sol";

contract Treasury is UUPSUpgradeable, AccessControlUpgradeable {
    bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");
    uint256 public reserveCap;
    uint256[49] private __gap; // storage gap

    function initialize(address admin, uint256 cap) public initializer {
        __UUPSUpgradeable_init();
        __AccessControl_init();
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(UPGRADER_ROLE, admin);
        reserveCap = cap;
    }

    function _authorizeUpgrade(address newImpl)
        internal
        override
        onlyRole(UPGRADER_ROLE)
    {}
}

2) ERC‑4337 Smart Accounts and Paymasters

  • Make sure to check the determinism and gas limits of validateUserOp(). Don't forget to test for griefing on paymaster deposits by using deliberately invalid operations. Run some bundler simulations and explore those PostOp edge cases. It’s also a good idea to include some fuzzing around timeouts and nonce management. You can dive deeper into the specifics here.

3) Permits and Approvals (EIP‑2612, Permit2)

  • Replay protection: Make sure to check out the domain separator strategy (this includes things like changes in chainId and the chances of forks), use per-owner nonces, and set clear deadlines. It’s a good idea to simulate front-running scenarios for permit() relays and see how they affect user experience. When working with Permit2 integrations, ensure that the signer prompts on the UI are user-friendly and that the max allowance duration logic checks out. Don't forget to include penetration tests that mimic phishing attempts, which can mislead users into approving off-chain requests. (eips.ethereum.org)

4) L2 Semantics, Bridges, and Cross-Domain Messages

  • On the OP Stack, make sure to test out the two-step withdrawals (the whole prove/finalize process), Superchain pause hooks, and check how message replay/versioning works, especially when messengers are paused. Don't forget to validate the token bridges' limits like fee-on-transfer and rebasing. (optimism.io)
  • Run some adversarial tests to challenge your app’s assumptions about message finality windows and replay across different versions. Go through the known types of bridge failures highlighted in recent SoK research to make sure you’ve got solid defenses in place. (arxiv.org)

5) Fuzzing, Invariants, and Scalable Formal Verification

  • Foundry Fuzz/Invariants: Get creative with stateful fuzz harnesses that test out multi-call sequences--think deposit → borrow → liquidate → reenter. You’ll want to also keep an eye on invariants like total supply conservation and solvency. Check out some public examples to kickstart your own testing! (github.com)
  • Formal Methods: Bring in Certora Prover in your CI pipeline to solidify those protocol invariants--like making sure there’s “no unauthorized minting” and “reserves never go negative.” Certora released the Prover as open source in 2025, so be sure to run it every time you make a change. (certora.com)
  1. Maturity with Compiler/EVM Changes
  • Make sure to compile and fuzz with your production compiler version (like 0.8.28 or 0.8.29). Check if MCOPY is available and take note of any changes in gas and memory usage. These factors can have a big impact on DoS costs, loop limits, and the overall economics on-chain. You can read more about it here.

Frontend and supply chain: what to actually test now

Recent events have shown that just one compromised npm dependency or ad script can really take a toll on users, even if your contracts are top-notch.

Actionable Test Cases:

When it comes to software testing, having clear and actionable test cases is crucial. Here’s a quick rundown on how to create and use them effectively.

What are Actionable Test Cases?

Actionable test cases are specific scenarios designed to verify that your application behaves as expected. They should be straightforward, easy to understand, and provide a clear path to follow during the testing process.

How to Write Actionable Test Cases

  1. Be Clear and Concise: Use simple language. Avoid jargon unless it’s industry-standard.
  2. Define Preconditions: Make sure to specify any setup that needs to happen before running the test.
  3. Include Steps to Execute: Clearly outline the steps testers need to perform. Number them for easier following.
  4. Specify Expected Results: Describe what the expected outcome should be after executing the steps.
  5. Add Postconditions: If necessary, mention what should be true after the test is complete.

Example of an Actionable Test Case

Here’s a little example to illustrate:

Test Case ID: TC-001
Description: Login functionality for registered users.
Preconditions: User must have a valid account.

Steps to Execute:

  1. Open the login page.
  2. Enter a valid username.
  3. Enter the corresponding password.
  4. Click on the "Login" button.

Expected Result: User is redirected to the homepage and sees a welcome message.

Postconditions: User remains logged in until they log out or the session expires.

Tips for Creating Effective Test Cases

  • Prioritize Test Cases: Focus on the most critical functionalities first.
  • Review Regularly: Keep your test cases updated as the application evolves.
  • Involve the Team: Collaborate with developers and stakeholders to ensure comprehensive coverage.

Tools for Managing Test Cases

Here are some popular tools that can help you manage your test cases:

By following these guidelines, you’ll ensure your test cases are not just actionable but also effective in catching issues and guiding your testing efforts.

  • Malicious package injection: Try mimicking what happened with the Ledger Connect Kit by swapping out a transitive dependency during the build process. Make sure to check that SRI checks and lockfiles are doing their job to stop any tampered bundles from being shipped. Also, ensure that your CI pipeline fails if there are any integrity mismatches. (ledger.com)
  • Third-party script abuse: Simulate some in-page script injection through a CDN or CMS slot, then check that your Content Security Policy (CSP) blocks any inline script execution. It’s also important to restrict the connect-src to known RPC/wallet endpoints. To step it up, enforce Trusted Types to cut down on those DOM-XSS vulnerabilities. (developer.mozilla.org)
  • Malvertising and embeddables: Make sure that wallet connect prompts can’t be triggered from third-party iframes or ads. Try replicating the types of popups seen on CoinMarketCap or Cointelegraph against your own site, and verify that they don’t get through under your CSP or reporting. (coindesk.com)
  • Email and analytics vendors: Run through what your post-breach communications would look like and how you’d detect a list-provider compromise, similar to the incident that happened with CoinGecko and GetResponse. This will help minimize the impact of any phishing attempts. (coingecko.com)
  • Ad networks on explorers: Implement a "no-click" control and a denylist for script sources. This will help secure users who visit your site from any compromised ad slots (like the multiple campaigns targeting Etherscan). (getblock.net)

Supply Chain Hardening Steps to Verify:

  1. Vendor Assessment
    Make sure you’re vetting your suppliers. Look at their security practices, financial stability, and past performance. It’s all about knowing who you’re working with!
  2. Risk Management
    Identify potential risks in your supply chain and figure out how to mitigate them. This might mean diversifying your suppliers or creating contingency plans when things go south.
  3. Regular Audits
    Conduct thorough audits on a regular basis. This helps you spot any vulnerabilities in your supply chain before they become big headaches down the road.
  4. Data Encryption
    Don’t skimp on data protection! Encrypt sensitive information both in transit and at rest to keep your business and client data secure.
  5. Access Controls
    Implement strict access controls. It’s crucial to ensure that only the right people can access sensitive supply chain information.
  6. Incident Response Plan
    Have a solid incident response plan in place so you can react quickly if something goes wrong. Practice makes perfect, so make sure your team is familiar with the steps to take.
  7. Continuous Monitoring
    Keep an eye on your supply chain. Continuous monitoring allows you to detect and respond to threats as they happen.
  8. Collaboration with Partners
    Work closely with your suppliers and partners to share information on risks and best practices. Teamwork truly makes the dream work!
  9. Training and Awareness
    Don’t forget about training your staff! Make sure everyone understands the importance of supply chain security and knows how to spot potential threats.
  10. Compliance Checks
    Stay updated with industry regulations and compliance requirements. Regular checks will help ensure that your supply chain remains compliant and secure.

By following these steps, you can bolster your supply chain against potential threats and protect your business!

  • Make sure to enforce strict lockfiles and checksum verification using npm, pnpm, or yarn. It’s also a good idea to require two-factor authentication for maintainers and to adopt provenance/signing methods like Sigstore in your CI process. Don’t forget to test that any tampered artifacts actually fail the pipeline. You can read more about it here!
  • Implement Subresource Integrity for any scripts you host on a CDN, and be sure to check how your browser handles failures. It might be helpful to run a red-team drill where the CDN serves up a modified hash just to see how things go. For more details, check out this guide on MDN.
  • Turn on Content Security Policy (CSP) with require-trusted-types-for 'script' and make sure your Trusted Types policies are audited. To keep everything in check, run a Chrome Lighthouse “Trusted Types” audit as a gate. You can get more insights on that here.

Off‑chain crypto plumbing: wallets, relayers, and simulations

  • Transaction simulation in the UI is a must-have: Make sure to integrate Tenderly simulations or something similar, so users can see how their balances and approvals change before they hit that sign button. Don’t forget to run penetration tests to ensure that any shady transactions get flagged by the simulator and that the user experience is designed to block them. Check it out here: (docs.tenderly.co)
  • Operational reality check: If you’re using OpenZeppelin Defender for your monitors and relayers, it’s time to start planning for migration. They stopped accepting new sign-ups on June 30, 2025, and the final shutdown is set for July 1, 2026. We’ll need to confirm that observability and auto-pauses still function smoothly after you migrate. More info can be found here: (docs.openzeppelin.com)
  • Wallet prompts: It’s important to avoid using raw eth_sign. Instead, go for EIP-712 typed data, and make sure to display the spender, chainId, and expiry in a way anyone can read. Your app should also never ask for unlimited allowances without clear communication. It might be a good idea to include some phishing-style tests around Permit2 signature prompts and to have solid explainers to guide users through the process. Get the details here: (eips.ethereum.org)

Account Abstraction specifics: what we break on purpose

  • Paymaster griefing: We take a proactive approach by flooding your paymaster with invalid userOps. This helps us probe for any potential deposit drain and ensures that validatePaymasterUserOp() is consistent, adheres to gas limits, and is secured by staking slashing incentives. Plus, we double-check postOp() paths to catch any revert-loops and unexpected gas spikes. You can dive deeper into this here.
  • Session keys/delegation: We push the limits by trying to escalate scope (like sneaking past validUntil or target restrictions) and checking out the revocation user experience. If you’re looking into EIP‑7702 patterns, we make sure to validate the chain-specific rules, storage side effects, and how resistant those delegation updates are to front-running. Get all the details here.
  • Bundler ecosystem: We make sure that off-chain simulations match on-chain behavior across various networks, especially L2s with different gas accounting setups. We also put our skills to the test by trying to poison simulation caches and changing up mempool conditions.

L2 and bridge testing: assumptions are where bugs hide

  • OP Stack bridge: We’re all about validating the prove/finalize flow, checking out replay protection, and making sure those pause mechanisms are on point (including any pauses across the Superchain). Plus, we take some time to run through our incident playbooks that utilize these tools. We simulate paused messengers to ensure that deposits and withdrawals degrade safely. You can learn more about it on optimism.io.
  • “EVM equivalence” expectations: We do some regression testing for any historical divergences (like those pesky SELFDESTRUCT semantics) to ensure that your contracts aren’t relying on any undefined behavior between L1 and L2. Check out the details over on github.com.
  • Cross‑chain design: We break down your architecture against a list of potential bridge design flaws. This way, we can test for things like signature verification bypass, state verification gaps, centralized validator sets, and risks tied to operator keys using our SoK-derived checklists. Dive deeper into this on arxiv.org.

Red‑teaming the frontend like attackers did

We mimic real-world attacker TTPs:

  • So, there’s this DNS registrar social engineering thing that can lead to a subdomain takeover and then, boom, you get a malicious WalletConnect prompt--like what happened in Balancer’s 2023 incident. We make sure to double-check registrar lock settings, enable 2FA, and put in some solid registry guardrails. You can read more about it here: (cointelegraph.com).
  • Then there’s ad-script malvertising on popular sites, which can result in those sketchy fake airdrop banners popping up. Your Content Security Policy (CSP) should take care of blocking those, while your client-side detectors should be on high alert to flag them. Plus, your incident banner needs to direct users to safety in no time flat. We validate all those steps to keep things secure. Check out this article for details: (coindesk.com).
  • We’ve also got GTM/script-tag injections that can swap out approval targets, like what happened in KyberSwap’s 2022 UI exploit. We ensure that Subresource Integrity (SRI) breaks the load, and that your build doesn’t allow inline script execution. More info here: (blog.kyberswap.com).
  • And don’t forget about npm maintainer/session compromises, like the one Ledger faced in 2023. We check to see if a compromised dependency can actually make its way into production, or if your pipeline’s provenance, SBOM, and integrity gates are doing their job to block it. You can read Ledger’s insights here: (ledger.com).

  • Add simulation to approval flows:

    • Whenever you’re approving a token (including Permit2), let’s show a quick summary before you sign. It should include the spender, the allowance, the expiry, and the chainId. If the simulation reveals any transfers you didn't kick off, just reject the signatures. We’ll back this up with a Tenderly single-transaction simulation. (docs.tenderly.co)
  • Harden CSP and Trusted Types:

    • Let’s tighten up our security with this Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.youcontrol/ 'strict-dynamic'; require-trusted-types-for 'script'; trusted-types appPolicy; connect-src 'self' https://mainnet.infura.io ...
    • Be sure to add SRI (Subresource Integrity) to any CDN script and set it up so that builds fail if the hashes don’t match. (developer.chrome.com)
  • Approvals safety:

    • It’s always safer to go for bounded allowances and approvals that expire. Use EIP‑2612 with nonces and a deadline; also make sure to cache the domain separator properly to dodge any cross-chain replay during forks. (eips.ethereum.org)
  • Compiler pinning & test realism:

    • Stick to your production compiler version (like 0.8.28 or 0.8.29), turn on via-IR, and run fuzz tests and invariants after every update; don’t forget to keep an eye on the Dencun/Cancun EVM targets. (soliditylang.org)

Tooling upgrades worth making this quarter

  • Slither‑MCP: Enhance your code review process with the latest Slither and LLM‑assisted workflows. This combo helps you catch variant bugs earlier in your CI. We’ll throw in some detectors and even train prompts tailored to your codebase. Check it out! (trailofbits.com)
  • Formal proofs in CI: Give a go to the now‑open‑source Certora Prover, focusing on the crucial invariants that matter most for your protocol (like solvency and one‑way upgrades). Think of proofs as build gates for those high‑risk pathways. Dive into it here! (github.com)
  • Simulations everywhere: Integrate Tenderly RPC/API into your staging and production UIs and keep an eye on asset deltas for every transaction. If a simulation throws up any unexpected side effects, make sure to fail closed. You can learn more in the docs! (docs.tenderly.co)

A concise 2‑week pen‑test plan we run for startups and enterprises

  • Day 1-2: We’ll kick things off with an architecture review and some threat modeling. We’ll dive into contracts, AA flows, L2 bridges, frontends, and CI/CD processes. By the end, you’ll have a comprehensive threat map that connects attack trees to their potential business impact.
  • Day 3-6: Time for some on-chain testing! We'll conduct static analysis, use Foundry for fuzzing and invariants, and do some targeted manual reviews based on your specific compiler and EVM settings. We’ll also run formal checks on the critical invariants to ensure everything’s in good shape.
  • Day 5-8: Next up, we’ll focus on frontend and supply-chain exercises. This includes validating CSP, Trusted Types, and SRI, as well as running npm tamper drills. We'll also walk through a malvertising and popup phishing playbook to strengthen your defenses.
  • Day 7-10: We’ll shift gears to off-chain plumbing. Expect to dive into bundler/paymaster griefing, ensure simulation parity, and work on bridge proving, finalizing, and pause drills. Plus, we’ll conduct some cross-chain replay tests to round it all out.
  • Day 11-12: During these days, we’ll reproduce any exploits and quantify risks using business metrics. This includes defining loss ceilings, mapping exploit paths, and assessing blast radius by user cohort.
  • Day 13-14: Finally, we’ll wrap things up with a fix-oriented report and retest. Your team will get PR-level patches or policy diffs that you can merge right away!

Emerging best practices (2025) to institutionalize

  • Treat blob data (EIP‑4844) as temporary and not tied to the EVM--don’t create user experiences or proofs that rely on blobs being around for the long haul or accessible via the EVM. Make sure to pen-test for failures when blobs run out. (eips.ethereum.org)
  • Assume wallet drainer campaigns are always happening: make sure to simulate and provide human-readable typed data for every signature flow; steer clear of using eth_sign. Keep an eye on phishing stats as a key indicator. (drops.scamsniffer.io)
  • Get incident response levers approved on L2s: ensure that Superchain-pause paths, messenger pauses, and withdrawal halts are properly verified to work from start to finish, with governance giving their thumbs up. (gov.optimism.io)
  • Stay updated with compilers and the EVM: plan for quarterly re-tests after any compiler or EVM upgrades (0.8.29’s EOF is still experimental but already alters assumptions in assembly-heavy code). (soliditylang.org)

Bottom line for decision‑makers

  • These days, the biggest Web3 losses often happen outside your contracts. It’s crucial that your pen test hits the frontend, the vendor chain, wallet prompts, and bridge assumptions with the same intensity as it does with your Solidity audits.
  • Time to modernize your security stack! Think about adding simulations right in the UI, strong CSP/Trusted Types/SRI measures, hardening AA/paymasters, conducting L2 bridge drills, and creating formal proofs for your critical invariants, along with safe storage upgrades.
  • Make this a continuous effort: connect these controls to your CI, freeze builds if there are any integrity or proof failures, and be sure to set aside a budget for re-testing after any protocol or compiler updates.

If you're looking for a pen test that really reflects how attackers will work in 2025--and gives you actionable patches and policies--you've come to the right place. At 7Block Labs, we’ll tailor our engagement to fit the specific risks of your protocol, ensuring you get practical solutions, not just a list of issues.

Get a free security quick-scan of your smart contracts

Submit your contracts and our engineer will review them for vulnerabilities, gas issues and architecture risks.

7BlockLabs

Full-stack blockchain product studio: DeFi, dApps, audits, integrations.

7Block Labs is a trading name of JAYANTH TECHNOLOGIES LIMITED.

Registered in England and Wales (Company No. 16589283).

Registered Office address: Office 13536, 182-184 High Street North, East Ham, London, E6 2JA.

© 2026 7BlockLabs. All rights reserved.