68 lines
2.1 KiB
Solidity
68 lines
2.1 KiB
Solidity
|
// SPDX-License-Identifier: MIT
|
||
|
pragma solidity >=0.8.17;
|
||
|
contract Create2Factory {
|
||
|
|
||
|
bytes32 savedSalt;
|
||
|
|
||
|
// Returns the address of the newly deployed contract
|
||
|
function deploy(
|
||
|
bytes32 _salt
|
||
|
) public returns (address) {
|
||
|
// This syntax is a newer way to invoke create2 without assembly, you just need to pass salt
|
||
|
// https://docs.soliditylang.org/en/latest/control-structures.html#salted-contract-creations-create2
|
||
|
savedSalt = _salt;
|
||
|
(bool success, address ret) = deployDelegateCall(_salt);
|
||
|
require(success);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
function deployDelegateCall(
|
||
|
bytes32 _salt
|
||
|
) public returns (bool, address) {
|
||
|
bytes memory data = abi.encodeWithSignature("_deploy(bytes32)", _salt);
|
||
|
(bool success, bytes memory returnedData) = address(this).delegatecall(data);
|
||
|
if(success){
|
||
|
(address ret) = abi.decode(returnedData, (address));
|
||
|
return (success, ret);
|
||
|
}else{
|
||
|
return (success, address(0));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function _deploy(bytes32 _salt) public returns (address) {
|
||
|
// https://solidity-by-example.org/app/create1/
|
||
|
// This syntax is a newer way to invoke create2 without assembly, you just need to pass salt
|
||
|
// https://docs.soliditylang.org/en/latest/control-structures.html#salted-contract-creations-create2
|
||
|
return address(new SelfDestruct{salt: _salt}(_salt));
|
||
|
}
|
||
|
|
||
|
function test(address _address) public returns (address){
|
||
|
|
||
|
// run destroy() on _address
|
||
|
SelfDestruct selfDestruct = SelfDestruct(_address);
|
||
|
selfDestruct.destroy();
|
||
|
|
||
|
//verify data can still be accessed
|
||
|
address ret = selfDestruct.sender();
|
||
|
|
||
|
// attempt and fail to deploy contract using salt
|
||
|
(bool success, ) = deployDelegateCall(selfDestruct.salt());
|
||
|
require(!success);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
contract SelfDestruct {
|
||
|
address public sender;
|
||
|
bytes32 public salt;
|
||
|
constructor(bytes32 _salt) {
|
||
|
sender = tx.origin;
|
||
|
salt=_salt;
|
||
|
}
|
||
|
function destroy() public {
|
||
|
selfdestruct(payable(msg.sender));
|
||
|
}
|
||
|
}
|
||
|
|