In ERC725XCore.sol, the _deployCreate2() function uses Openzeppelin’s Create2.deploy() to deploy new contracts:
function _deployCreate2(
uint256 value,
bytes memory creationCode
) internal virtual returns (bytes memory newContract) {
if (creationCode.length == 0) {
revert ERC725X_NoContractBytecodeProvided();
}
bytes32 salt = BytesLib.toBytes32(creationCode, creationCode.length - 32);
bytes memory bytecode = BytesLib.slice(creationCode, 0, creationCode.length - 32);
address contractAddress = Create2.deploy(value, salt, bytecode);
newContract = abi.encodePacked(contractAddress);
emit ContractCreated(OPERATION_2_CREATE2, contractAddress, value, salt);
}
Openzeppelin’s Create2.deploy() then deploys the contract using CREATE2 with the given salt and bytecode:
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
As seen from above, the address of the newly deployed contract solely relies on the provided salt and bytecode, which both come from _deployCreate2()'s creationCode parameter.
This becomes a problem when an LSP0 account is used alongside a LSP6 Key Manager, and multiple users are given the DEPLOY permission. Once a user’s transaction to deploy a contract using CREATE2 is broadcasted, the creationCode parameter can be viewed by anyone watching the public mempool.
This creates two issues:
* An attacker sees these pending transactions and front-runs them to deploy a contract for himself using CREATE2 with the same creationCode.
* The contract is deployed for the attacker first. As the same creationCode was used, this contract is deployed at the address the user had computed beforehand.
* The user's CREATE2 transaction reverts, but his second transaction that deposits LYX and adds permissions gets executed successfully.
* The attacker-controlled contract now has LYX and permissions from the user; he can then abuse this to perform malicious actions.
Multiple users with DEPLOY permission in an LSP0 account can front-run each other to:
Consider including caller-specific data in the salt passed to Create2.deploy() to prevent different users from being able to deploy contracts to the same address.
This is usually done by including msg.sender in the salt. However, for LSP0 accounts, this is not possible as msg.sender might be the LSP6KeyManager contract.
Other
The text was updated successfully, but these errors were encountered:
All reactions