Source Code
Overview
MNT Balance
MNT Value
$0.00
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ImmutableCreate2Factory
Compiler Version
v0.5.10+commit.5a6ea5b1
Optimization Enabled:
Yes with 200 runs
Other Settings:
petersburg EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
/**
*Submitted for verification at Etherscan.io on 2019-07-30
*/
pragma solidity 0.5.10; // 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 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 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 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) ||
(bytes20(salt) == bytes20(0)),
"Invalid salt - first 20 bytes of the salt must match calling address."
);
_;
}
}{
"evmVersion": "petersburg",
"libraries": {},
"metadata": {
"useLiteralContent": false
},
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": [
"forge-std/=lib/forge-std/src/"
]
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":true,"inputs":[{"name":"deploymentAddress","type":"address"}],"name":"hasBeenDeployed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"salt","type":"bytes32"},{"name":"initializationCode","type":"bytes"}],"name":"safeCreate2","outputs":[{"name":"deploymentAddress","type":"address"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"salt","type":"bytes32"},{"name":"initCode","type":"bytes"}],"name":"findCreate2Address","outputs":[{"name":"deploymentAddress","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"salt","type":"bytes32"},{"name":"initCodeHash","type":"bytes32"}],"name":"findCreate2AddressViaHash","outputs":[{"name":"deploymentAddress","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5061064a806100206000396000f3fe60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461008b57806385cf97ab1461011e578063a49a7c90146101a2575b600080fd5b34801561005057600080fd5b506100776004803603602081101561006757600080fd5b50356001600160a01b03166101d2565b604080519115158252519081900360200190f35b610102600480360360408110156100a157600080fd5b813591908101906040810160208201356401000000008111156100c357600080fd5b8201836020820111156100d557600080fd5b803590602001918460018302840111640100000000831117156100f757600080fd5b5090925090506101f0565b604080516001600160a01b039092168252519081900360200190f35b34801561012a57600080fd5b506101026004803603604081101561014157600080fd5b8135919081019060408101602082013564010000000081111561016357600080fd5b82018360208201111561017557600080fd5b8035906020019184600183028401116401000000008311171561019757600080fd5b509092509050610429565b3480156101ae57600080fd5b50610102600480360360408110156101c557600080fd5b50803590602001356104da565b6001600160a01b031660009081526020819052604090205460ff1690565b600083606081901c33148061020d57506001600160601b03198116155b6102485760405162461bcd60e51b815260040180806020018281038252604581526020018061058b6045913960600191505060405180910390fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051855195965090943094508b93508692506020918201918291908401908083835b602083106102be5780518252601f19909201916020918201910161029f565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183528085528251928201929092206001600160f81b03198383015260609890981b6001600160601b03191660218301526035820196909652605580820197909752825180820390970187526075018252508451948401949094206001600160a01b0381166000908152938490529390922054929350505060ff161561039d5760405162461bcd60e51b815260040180806020018281038252603f81526020018061054c603f913960400191505060405180910390fd5b81602001825188818334f595505050806001600160a01b0316846001600160a01b0316146103fc5760405162461bcd60e51b81526004018080602001828103825260468152602001806105d06046913960600191505060405180910390fd5b5050506001600160a01b0381166000908152602081905260409020805460ff191660011790559392505050565b600030848484604051602001808383808284376040805191909301818103601f1901825280845281516020928301206001600160f81b03198383015260609990991b6001600160601b031916602182015260358101979097526055808801989098528251808803909801885260759096018252508551958501959095206001600160a01b0381166000908152948590529490932054939450505060ff9091161590506104d3575060005b9392505050565b604080516001600160f81b03196020808301919091523060601b602183015260358201859052605580830185905283518084039091018152607590920183528151918101919091206001600160a01b0381166000908152918290529190205460ff1615610545575060005b9291505056fe496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c7265616479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374207573696e672070726f76696465642073616c7420616e6420696e697469616c697a6174696f6e20636f64652ea265627a7a723058200f4c29e2e81c8bc92c72eac62dbea3097ef24b8adf771a0face354840033b54964736f6c634300050a0032
Deployed Bytecode
0x60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461008b57806385cf97ab1461011e578063a49a7c90146101a2575b600080fd5b34801561005057600080fd5b506100776004803603602081101561006757600080fd5b50356001600160a01b03166101d2565b604080519115158252519081900360200190f35b610102600480360360408110156100a157600080fd5b813591908101906040810160208201356401000000008111156100c357600080fd5b8201836020820111156100d557600080fd5b803590602001918460018302840111640100000000831117156100f757600080fd5b5090925090506101f0565b604080516001600160a01b039092168252519081900360200190f35b34801561012a57600080fd5b506101026004803603604081101561014157600080fd5b8135919081019060408101602082013564010000000081111561016357600080fd5b82018360208201111561017557600080fd5b8035906020019184600183028401116401000000008311171561019757600080fd5b509092509050610429565b3480156101ae57600080fd5b50610102600480360360408110156101c557600080fd5b50803590602001356104da565b6001600160a01b031660009081526020819052604090205460ff1690565b600083606081901c33148061020d57506001600160601b03198116155b6102485760405162461bcd60e51b815260040180806020018281038252604581526020018061058b6045913960600191505060405180910390fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051855195965090943094508b93508692506020918201918291908401908083835b602083106102be5780518252601f19909201916020918201910161029f565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183528085528251928201929092206001600160f81b03198383015260609890981b6001600160601b03191660218301526035820196909652605580820197909752825180820390970187526075018252508451948401949094206001600160a01b0381166000908152938490529390922054929350505060ff161561039d5760405162461bcd60e51b815260040180806020018281038252603f81526020018061054c603f913960400191505060405180910390fd5b81602001825188818334f595505050806001600160a01b0316846001600160a01b0316146103fc5760405162461bcd60e51b81526004018080602001828103825260468152602001806105d06046913960600191505060405180910390fd5b5050506001600160a01b0381166000908152602081905260409020805460ff191660011790559392505050565b600030848484604051602001808383808284376040805191909301818103601f1901825280845281516020928301206001600160f81b03198383015260609990991b6001600160601b031916602182015260358101979097526055808801989098528251808803909801885260759096018252508551958501959095206001600160a01b0381166000908152948590529490932054939450505060ff9091161590506104d3575060005b9392505050565b604080516001600160f81b03196020808301919091523060601b602183015260358201859052605580830185905283518084039091018152607590920183528151918101919091206001600160a01b0381166000908152918290529190205460ff1615610545575060005b9291505056fe496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c7265616479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374207573696e672070726f76696465642073616c7420616e6420696e697469616c697a6174696f6e20636f64652ea265627a7a723058200f4c29e2e81c8bc92c72eac62dbea3097ef24b8adf771a0face354840033b54964736f6c634300050a0032
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MNT
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.