In decentralized finance, the mempool is a transparent auction house. Every pending transaction broadcasts its intent, allowing sophisticated actors to observe and exploit price movements before they settle. This transparency creates a class of attacks known collectively as MEV (Maximal Extractable Value) exploits, among which the sandwich attack remains one of the most mechanically elegant—and damaging—strategies. Immute addresses this attack vector directly through a per-address buy-lock mechanism implemented at the smart contract level. This article dissects how that mechanism works, why it prevents same-block sandwich attempts, and how builders can verify its behavior on the current Sepolia testnet deployment before mainnet launch.
Understanding the Sandwich Attack Vector
A sandwich attack exploits the sequential execution of transactions within a single block. The attacker monitors the mempool for a large pending trade—typically a swap on an AMM or a bonding curve interaction. When detected, the attacker positions two transactions around the victim's trade: a front-run buy that inflates the asset price, and a back-run sell that captures the spread once the victim's order executes [3][4].
The mechanics are straightforward. Transaction A (front-run) purchases the target asset, driving up its price on the curve. The victim's transaction B then executes at this elevated price, receiving fewer assets than they would have without interference. Finally, Transaction C (back-run) sells the accumulated asset immediately after, pocketing the difference [3][4]. This three-step sequence extracts value directly from the victim without requiring any deception—the attacker's profitability depends entirely on predictable blockchain execution order.
The profitability of sandwich attacks hinges on two constraints: the attack must occur within the same block, and the directional reversal (buy then sell, or sell then buy) must execute rapidly enough to capture the spread before the price reverts. Disrupt either constraint, and the attack becomes unviable.
Immute's Per-Address Buy-Lock Mechanism
Immute implements a directional cooldown system using two core state variables: lockedUntil (a mapping of addresses to block numbers) and isLocked (a boolean flag activated upon purchase). When an address acquires IMT tokens, the contract immediately sets lockedUntil[address] to the current block number plus a configurable cooldown period, and toggles isLocked[address] to true [1][5].
This check executes on every sell attempt. Before any transfer that would reduce an address's IMT balance, the contract verifies whether isLocked[msg.sender] is true and whether the current block number is less than lockedUntil[msg.sender]. If either condition indicates an active lock, the transaction reverts [1][5].
The mechanism's elegance lies in its simplicity: it doesn't attempt to identify attackers or analyze transaction patterns. Instead, it enforces a universal constraint—after buying, you cannot sell within the cooldown window. This makes directional reversal within the same block (or the configured number of subsequent blocks) structurally impossible.
Blocking Same-Block and Delayed Sandwich Attempts
The per-address lock prevents sandwich attacks at multiple temporal scales. Same-block sandwich attempts fail because the back-running sell transaction (Transaction C) cannot execute while the lock remains active. The front-running buy (Transaction A) triggers the lock, so the attacker's own sell order reverts regardless of whether it appears in the same block [5].
More subtly, the mechanism also disrupts delayed sandwich strategies. An attacker might attempt to spread the attack across multiple blocks—buying in block N, waiting for the victim's transaction in block N+1, then selling in block N+2. If the cooldown period exceeds one block, the sell transaction still reverts. The lock persists until the current block exceeds lockedUntil[address] [1].
The attacker's fallback option—using a different address for the back-run—also fails if the attacker bought on any address. The lock is per-address, but the attacker cannot effectively front-run and back-run from separate addresses because the back-run address must already hold the asset to sell it. Purchasing on Address A and attempting to sell from Address B requires transferring the asset between addresses, which itself may trigger additional checks or incur costs that eliminate the profit margin [5].
Implementation Details: Configurable Cooldown
The cooldown period k is a configurable parameter set at contract deployment. This flexibility allows the system to tune protection based on empirical observation. A longer cooldown provides stronger guarantees against sandwich attempts but introduces friction for legitimate users who wish to trade rapidly. A shorter cooldown reduces friction but may allow sophisticated attackers to exploit timing within the block ordering [1][5].
Immute's approach prioritizes structural impossibility over probabilistic deterrence. Rather than relying on monitoring or reactive measures—which can be bypassed through transaction ordering or flashbots-style private transaction routing—the contract enforces the constraint at execution time [2]. There is no mempool state an attacker can manipulate to bypass the lock; the check is deterministic and on-chain.
Testing the Mechanism on Sepolia
Immute is currently live on Sepolia testnet (chainId 11155111), enabling developers and sophisticated users to verify the mechanism's behavior without financial risk. The IMT V8 contract at 0xB575A8760c66F09a26A03bc215D612EA2486373C implements the buy-lock logic, and the FeederV9 contract at 0xa87e7c25c2f754C7D6bFc9b4472E0c36096E4bF6 routes purchases through the bonding curve while maintaining the same protective constraints.
Builders can test the mechanism by acquiring free Sepolia ETH from a faucet such as https://sepolia-faucet.pk910.de/ or https://www.alchemy.com/faucets/ethereum-sepolia, connecting a wallet to https://immute.io, and executing a buy followed immediately by a sell attempt. The sell transaction should revert if attempted within the lock window. By varying the timing across blocks, testers can confirm the exact cooldown behavior and verify that the mechanism performs as specified.
Mainnet launch is coming soon, after testnet validation completes. The current testnet deployment serves as a proving ground for these security mechanisms, ensuring that the per-address lock functions correctly under realistic conditions before exposing the system to mainnet economic activity.
Conclusion: Structural Protection Over Probabilistic Defense
Smart contract sandwich attack prevention requires mechanisms that make the attack vector structurally impossible, not merely economically unattractive. Immute's per-address buy-lock implementation achieves this by enforcing a directional cooldown that prevents same-block and delayed sandwich attempts alike. The isLocked() and lockedUntil() checks operate deterministically at execution time, leaving no flexibility for attackers to manipulate timing or ordering.
For builders evaluating Immute's security architecture, the testnet deployment provides a verifiable implementation. Review the contract code on Sepolia Etherscan, execute test transactions to confirm the lock behavior, and assess whether the mechanism meets your requirements for MEV-resistant token mechanics.
The fight against sandwich attacks is ultimately a fight against information asymmetry in the mempool. By moving protection from the mempool layer to the contract layer, Immute eliminates the attack surface entirely—regardless of what transaction ordering the block producer chooses.
References
[1] https://www.sciencedirect.com/science/article/abs/pii/S0167739X25003711
[2] https://www.guardrail.ai/common-attack-vectors/front-running-sandwich-attacks
[3] https://www.zealynx.io/glossary/sandwich-attack
[4] https://trustwallet.com/blog/security/what-are-sandwich-attacks-in-defi
[5] https://dspace.networks.imdea.org/bitstream/handle/20.500.12761/2038/poster.pdf?sequence=1
Top comments (0)