Can a contract which is going to be deployed by another contract be hijacked?

Let's say I have a contract function that deploys other contracts. E.g.

mapping(address => address) tokens;
 
function deployToken(string memory name, string memory symbol) external onlyGovernance {
  Token token = new Token(name, symbol);
  tokens[token] = token;
}

My understanding is that if the above token was deployed to an address where a contract was already deployed, the new Token() call would fail leading to the entire transaction failing.

Assuming my above understanding is correct, is it possible for an unsavoury character to work out the address of the new Token() contract and be able to deploy their malicious contract to the same location ahead of my deployToken being called?

Lets assume that my deployToken may be called intermittently through the use of some kind of governance timelock. If the new contract address is determined by the timelock address and the address' nonce, wouldn't the attacker be able to easily determine the address of any token contracted deployed by my deployToken function?

If this is indeed the case, how would one mitigate this issue? A salt?

When a contract is created using new SomeContract(), the CREATE opcode is used to create the new contract. In this case the address is calculated by hashing together the deploying address and nonce.

When creating a contract with the CREATE2 opcode, the address is calculated by hashing together the deploying address, the hash of the bytecode to be deployed and a user provided salt (this allows you to predict the address of contracts not deployed yet).

It's very unlikely to find a collision

1 Like

Thanks for the explanation. How you explained it was how I thought it might work so it's great to clarify that.

My understanding with newer versions of solidity is that the salt can be added to the new SomeContract(), e,g new SomeContract{salt: someSalt}()? I'm assuming this informs the compiler to call the CREATE2 opcode instead of CREATE?

Lastly, what is best practice for defining a salt in solidity? Is it common practice to hard code some kind of predefined value (E.g. 0x123) or should there be some randomness to the generation of the salt? It seems most examples just hard code a value.

Wasn't aware that this was now supported in solidity new SomeContract{salt: someSalt}() apparently uses CREATE2 instead of CREATE.

The salted method allows you deterministic control over the address. That's how uniswapV2 calculates/creates contracts for new trade pairs (UniswapV2Pair). Check here. It's also a good example on how to generate a unique salt

1 Like

Okay that example is perfect, thanks. It was actually how I was thinking to do it and makes perfect sense.