Address Contract Partially Verified
Address
0xd8Ba9D1a99Fc21f0ECA24e9b85737c28A194a4E2
Balance
0 ETH
Nonce
3
Code Size
1498 bytes
Creator
0x21A2c6c7...Ad36 at tx 0x9bd985f6...1540f5
Indexed Transactions
0
Contract Bytecode
1498 bytes
0x60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009257806385cf97ab146100bd578063a49a7c90146100dd575b600080fd5b34801561005057600080fd5b5061007d61005f36600461045a565b6001600160a01b031660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b6100a56100a0366004610483565b6100fd565b6040516001600160a01b039091168152602001610089565b3480156100c957600080fd5b506100a56100d8366004610483565b61037d565b3480156100e957600080fd5b506100a56100f83660046104ff565b610400565b600083606081901c331461018c5760405162461bcd60e51b815260206004820152604560248201527f496e76616c69642073616c74202d206669727374203230206279746573206f6660448201527f207468652073616c74206d757374206d617463682063616c6c696e67206164646064820152643932b9b99760d91b608482015260a4015b60405180910390fd5b600084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051949550933093508a92506101dc91508590602001610521565b604051602081830303815290604052805190602001206040516020016102049392919061055c565b60408051601f1981840301815291815281516020928301206001600160a01b03811660009081529283905291205490915060ff16156102ab5760405162461bcd60e51b815260206004820152603f60248201527f496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e7460448201527f726163742068617320616c7265616479206265656e206465706c6f7965642e006064820152608401610183565b81602001825188818334f595505050806001600160a01b0316846001600160a01b0316146103505760405162461bcd60e51b815260206004820152604660248201527f4661696c656420746f206465706c6f7920636f6e7472616374207573696e672060448201527f70726f76696465642073616c7420616e6420696e697469616c697a6174696f6e6064820152651031b7b2329760d11b608482015260a401610183565b5050506001600160a01b0381166000908152602081905260409020805460ff191660011790559392505050565b600030848484604051602001610394929190610594565b604051602081830303815290604052805190602001206040516020016103bc9392919061055c565b60408051601f1981840301815291815281516020928301206001600160a01b03811660009081529283905291205490915060ff16156103f9575060005b9392505050565b60003083836040516020016104179392919061055c565b60408051601f1981840301815291815281516020928301206001600160a01b03811660009081529283905291205490915060ff1615610454575060005b92915050565b60006020828403121561046c57600080fd5b81356001600160a01b03811681146103f957600080fd5b60008060006040848603121561049857600080fd5b83359250602084013567ffffffffffffffff808211156104b757600080fd5b818601915086601f8301126104cb57600080fd5b8135818111156104da57600080fd5b8760208285010111156104ec57600080fd5b6020830194508093505050509250925092565b6000806040838503121561051257600080fd5b50508035926020909101359150565b6000825160005b818110156105425760208186018101518583015201610528565b81811115610551576000828501525b509190910192915050565b6001600160f81b0319815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b818382376000910190815291905056fea264697066735822122071837362387dee8d4174be8dd789dd7e368abe135dae9de372f270815533d8ef64736f6c634300080d0033
Verified Source Code Partial Match
Compiler: v0.8.13+commit.abaa5c0e
EVM: petersburg
Optimization: Yes (200 runs)
ImmutableCreate2Factory.sol 203 lines
// SPDX-License-Identifier: MIT
pragma solidity >= 0.8.0; // optimization enabled, 99999 runs, evm: petersburg
/**
* @title Immutable Create2 Contract Factory
* @author 0age
* @notice This contract provides a safeCreate2 function that takes a salt value
* and a block of initialization code as arguments and passes them into inline
* assembly. The contract prevents redeploys by maintaining a mapping of all
* contracts that have already been deployed, and prevents frontrunning or other
* collisions by requiring that the first 20 bytes of the salt are equal to the
* address of the caller (this can be bypassed by setting the first 20 bytes to
* the null address). There is also a view function that computes the address of
* the contract that will be created when submitting a given salt or nonce along
* with a given block of initialization code.
* @dev This contract has not yet been fully tested or audited - proceed with
* caution and please share any exploits or optimizations you discover.
*/
contract ImmutableCreate2Factory {
// mapping to track which addresses have already been deployed.
mapping(address => bool) private _deployed;
/**
* @dev Create a contract using CREATE2 by submitting a given salt or nonce
* along with the initialization code for the contract. Note that the first 20
* bytes of the salt must match those of the calling address, which prevents
* contract creation events from being submitted by unintended parties.
* @param salt bytes32 The nonce that will be passed into the CREATE2 call.
* @param initializationCode bytes The initialization code that will be passed
* into the CREATE2 call.
* @return deploymentAddress Address of the contract that will be created, or the null address
* if a contract already exists at that address.
*/
function safeCreate2(
bytes32 salt,
bytes calldata initializationCode
) external payable containsCaller(salt) returns (address deploymentAddress) {
// move the initialization code from calldata to memory.
bytes memory initCode = initializationCode;
// determine the target address for contract deployment.
address targetDeploymentAddress = address(
uint160( // downcast to match the address type.
uint256( // convert to uint to truncate upper digits.
keccak256( // compute the CREATE2 hash using 4 inputs.
abi.encodePacked( // pack all inputs to the hash together.
hex"ff", // start with 0xff to distinguish from RLP.
address(this), // this contract will be the caller.
salt, // pass in the supplied salt value.
keccak256( // pass in the hash of initialization code.
abi.encodePacked(
initCode
)
)
)
)
)
)
);
// ensure that a contract hasn't been previously deployed to target address.
require(
!_deployed[targetDeploymentAddress],
"Invalid contract creation - contract has already been deployed."
);
// using inline assembly: load data and length of data, then call CREATE2.
assembly { // solhint-disable-line
let encoded_data := add(0x20, initCode) // load initialization code.
let encoded_size := mload(initCode) // load the init code's length.
deploymentAddress := create2( // call CREATE2 with 4 arguments.
callvalue(), // forward any attached value.
encoded_data, // pass in initialization code.
encoded_size, // pass in init code's length.
salt // pass in the salt value.
)
}
// check address against target to ensure that deployment was successful.
require(
deploymentAddress == targetDeploymentAddress,
"Failed to deploy contract using provided salt and initialization code."
);
// record the deployment of the contract to prevent redeploys.
_deployed[deploymentAddress] = true;
}
/**
* @dev Compute the address of the contract that will be created when
* submitting a given salt or nonce to the contract along with the contract's
* initialization code. The CREATE2 address is computed in accordance with
* EIP-1014, and adheres to the formula therein of
* `keccak256( 0xff ++ address ++ salt ++ keccak256(init_code)))[12:]` when
* performing the computation. The computed address is then checked for any
* existing contract code - if so, the null address will be returned instead.
* @param salt bytes32 The nonce passed into the CREATE2 address calculation.
* @param initCode bytes The contract initialization code to be used.
* that will be passed into the CREATE2 address calculation.
* @return deploymentAddress Address of the contract that will be created, or the null address
* if a contract has already been deployed to that address.
*/
function findCreate2Address(
bytes32 salt,
bytes calldata initCode
) external view returns (address deploymentAddress) {
// determine the address where the contract will be deployed.
deploymentAddress = address(
uint160( // downcast to match the address type.
uint256( // convert to uint to truncate upper digits.
keccak256( // compute the CREATE2 hash using 4 inputs.
abi.encodePacked( // pack all inputs to the hash together.
hex"ff", // start with 0xff to distinguish from RLP.
address(this), // this contract will be the caller.
salt, // pass in the supplied salt value.
keccak256( // pass in the hash of initialization code.
abi.encodePacked(
initCode
)
)
)
)
)
)
);
// return null address to signify failure if contract has been deployed.
if (_deployed[deploymentAddress]) {
return address(0);
}
}
/**
* @dev Compute the address of the contract that will be created when
* submitting a given salt or nonce to the contract along with the keccak256
* hash of the contract's initialization code. The CREATE2 address is computed
* in accordance with EIP-1014, and adheres to the formula therein of
* `keccak256( 0xff ++ address ++ salt ++ keccak256(init_code)))[12:]` when
* performing the computation. The computed address is then checked for any
* existing contract code - if so, the null address will be returned instead.
* @param salt bytes32 The nonce passed into the CREATE2 address calculation.
* @param initCodeHash bytes32 The keccak256 hash of the initialization code
* that will be passed into the CREATE2 address calculation.
* @return deploymentAddress Address of the contract that will be created, or the null address
* if a contract has already been deployed to that address.
*/
function findCreate2AddressViaHash(
bytes32 salt,
bytes32 initCodeHash
) external view returns (address deploymentAddress) {
// determine the address where the contract will be deployed.
deploymentAddress = address(
uint160( // downcast to match the address type.
uint256( // convert to uint to truncate upper digits.
keccak256( // compute the CREATE2 hash using 4 inputs.
abi.encodePacked( // pack all inputs to the hash together.
hex"ff", // start with 0xff to distinguish from RLP.
address(this), // this contract will be the caller.
salt, // pass in the supplied salt value.
initCodeHash // pass in the hash of initialization code.
)
)
)
)
);
// return null address to signify failure if contract has been deployed.
if (_deployed[deploymentAddress]) {
return address(0);
}
}
/**
* @dev Determine if a contract has already been deployed by the factory to a
* given address.
* @param deploymentAddress address The contract address to check.
* @return True if the contract has been deployed, false otherwise.
*/
function hasBeenDeployed(
address deploymentAddress
) external view returns (bool) {
// determine if a contract has been deployed to the provided address.
return _deployed[deploymentAddress];
}
/**
* @dev Modifier to ensure that the first 20 bytes of a submitted salt match
* those of the calling account. This provides protection against the salt
* being stolen by frontrunners or other attackers. The protection can also be
* bypassed if desired by setting each of the first 20 bytes to zero.
* @param salt bytes32 The salt value to check against the calling address.
*/
modifier containsCaller(bytes32 salt) {
// prevent contract submissions from being stolen from tx.pool by requiring
// that the first 20 bytes of the submitted salt match msg.sender.
require(
address(bytes20(salt)) == msg.sender,
"Invalid salt - first 20 bytes of the salt must match calling address."
);
_;
}
}
Read Contract
findCreate2Address 0x85cf97ab → address
findCreate2AddressViaHash 0xa49a7c90 → address
hasBeenDeployed 0x08508b8f → bool
Write Contract 1 functions
These functions modify contract state and require a wallet transaction to execute.
safeCreate2 0x64e03087
bytes32 salt
bytes initializationCode
returns: address
Recent Transactions
No transactions found for this address