Create3Factory

Git Source

Title: Dotns CREATE3 Factory

Permissionless wrapper around Solady's audited CREATE3 library.

Anyone may call @custom:function deploy. CREATE3 addresses are a pure function of (factory_address, salt) — the caller never enters the derivation — so caller-gating would not strengthen address determinism. Salt-squatting griefing is in-scope for the caller, not the factory: salts in the DotNS namespace (CREATE3_SALT_NAMESPACE in BaseDeployer) get bumped end-to-end if a slot is ever found occupied. Keeping the factory permissionless removes the cross-chain ownership-coordination burden and lets CI keys, ops keys, and recovery flows all coexist without ownership transfers.

Note: security-contact: admin@parity.io

Functions

receive

Accepts native transfers so callers can pre-fund the factory if they want constructors that take msg.value.

The dotNS pipeline never forwards native value; this exists purely so the factory is compatible with payable-constructor callers from other consumers.

receive() external payable;

deploy

Deploys initCode at the deterministic address derived from salt.

Permissionless: any caller may invoke. The deployed address is CREATE3.predictDeterministicAddress(salt) and is independent of msg.sender. The call reverts if initCode is empty (@custom:reverts EmptyInitCode) or if the predicted slot is already occupied (Solady raises its own revert on collision). Emits

Note: emits: Deployed on success. Native value attached to the call is forwarded to the new contract's constructor.

function deploy(
    bytes32 salt,
    bytes calldata initCode
)
    external
    payable
    returns (address deployed);

Parameters

NameTypeDescription
saltbytes32CREATE3 salt; combined with this factory's address to derive the target.
initCodebytesConcatenation of creation bytecode and ABI-encoded constructor args.

Returns

NameTypeDescription
deployedaddressAddress of the newly deployed contract.

predict

Returns the address that @custom:function deploy would target for salt.

Pure projection of (factory_address, salt) — does not check whether the address is currently occupied. Callers that need occupancy info should follow up with an addr.code.length check.

function predict(bytes32 salt) external view returns (address predicted);

Parameters

NameTypeDescription
saltbytes32CREATE3 salt to look up.

Returns

NameTypeDescription
predictedaddressAddress at which a @custom:function deploy call with this salt would instantiate.

Events

Deployed

Emitted on every successful CREATE3 deployment through this factory.

salt and deployed are indexed so consumers can filter by either. initCodeHash is published alongside the deployment so downstream tooling can pin codehash expectations against the on-chain artefact without re-fetching bytecode.

event Deployed(
    bytes32 indexed salt, address indexed deployed, bytes32 initCodeHash, uint256 value
);

Parameters

NameTypeDescription
saltbytes32The CREATE3 salt used to derive the deployed address.
deployedaddressAddress at which the contract was instantiated.
initCodeHashbytes32keccak256 of the init code passed to @custom:function deploy.
valueuint256Native value forwarded to the constructor (zero for the dotNS pipeline).

Errors

EmptyInitCode

Thrown when @custom:function deploy is called with an empty initCode blob.

CREATE3 with empty init code would deploy a zero-byte contract at the predicted address; the factory rejects the call early so callers fail fast on a malformed artefact lookup rather than land a useless deployment.

error EmptyInitCode();