top of page

Front running mechanism in WEB3

Case Study: The $15 Attack That Could Block a Multi-Chain Protocol


Blockchain technologies are different narrative and need to be looked from different angle to bring best value and contribute to safer environment.


The Silent Threat Hiding in Plain Sight

Centrifuge Protocol had ambitious plans. As a decentralized finance protocol

managing real-world assets, they were preparing to expand across multiple EVM

chains—Ethereum, Plume, and beyond. Their deployment strategy was elegant: use

CreateX, a universal factory contract, to deploy their contracts at the same

predictable addresses on every chain.

There was just one problem. Someone could get there first.

The Discovery

During a routine security review, a vulnerability emerged in an unlikely

place: not in the smart contracts themselves, but in the deployment scripts.

The protocol's generateSalt() function—a small utility buried in their

deployment infrastructure—was computing deployment addresses using only two

inputs:

function generateSalt(string memory contractName) internal view returns

(bytes32) {

return keccak256(abi.encodePacked(contractName, version));

}

Contract name: "wormholeAdapter" — public, visible in GitHub.

Version: "3" — public, visible in GitHub.

That's it. No secret. No deployer signature. No protection.

The Attack Vector

CreateX is a permissionless factory. Anyone can call deployCreate3() with any

salt and deploy any bytecode. The salt determines the address.

The math was simple:

1. Read Centrifuge's public GitHub repository

2. Extract contract names and version numbers

3. Compute the exact salts Centrifuge would use

4. Deploy garbage contracts to those addresses first

5. Wait

When Centrifuge's deployment scripts ran, they would encounter addresses

already occupied. The transactions would revert. The expansion would halt.

Cost to the attacker: ~$15-50 in gas per chain.

Cost to the protocol: Blocked deployments, broken cross-chain consistency,

emergency coordination, redeployment with new parameters, multisig

transactions across every existing chain.

The Proof

The vulnerability wasn't theoretical. A working proof-of-concept demonstrated

the attack in three tests:

Every core component—Root, Gateway, Guardian, Hub, Spoke, adapters—could be

blocked before Centrifuge even announced their deployment plans.

The Fix

The solution was straightforward. CreateX's own documentation recommends

including msg.sender in the first 20 bytes of the salt:

function generateSalt(string memory contractName) internal view returns

(bytes32) {

return keccak256(abi.encodePacked(msg.sender, contractName, version));

}

With this change, only the authorized deployer can occupy the intended

addresses. The attack window closes.

The Lesson

This vulnerability wasn't in complex cryptography or intricate DeFi logic. It

was in a deployment script—infrastructure code that often escapes security

review because "it's not on-chain."

But deployment scripts interact with on-chain systems. They compute salts.

They call factories. They set initial state. A vulnerability here can be just

as devastating as one in the protocol itself.

Centrifuge acknowledged the finding and confirmed the fix was already in

progress.

What This Means For Your Protocol

If your deployment uses:

- CREATE2 or CREATE3 for deterministic addresses

- Public deployment scripts in your repository

- Predictable inputs for address computation

...you may be vulnerable to address squatting.

The attack is cheap. The impact is operational paralysis. The fix is often

simple—but only if you know to look.

Before You Deploy, Get Audited

Security isn't just about your smart contracts. It's about your entire

deployment pipeline—the scripts, the salts, the factories, the assumptions.

One overlooked function. One missing parameter. One blocked deployment.

Don't let a $15 attack halt your protocol.





Other auditor findings can be found on - https://cantina.xyz/u/erike123 AND https://codependent.com/@erike1

 
 
 

Comments


bottom of page