2020-08-25 15:49:21 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-08-24 17:30:39 +00:00
|
|
|
pragma solidity ^0.6.8;
|
|
|
|
|
|
|
|
contract Deployer {
|
|
|
|
|
2020-09-07 04:51:20 +00:00
|
|
|
mapping (address => bool) public flushers;
|
2020-09-06 21:11:23 +00:00
|
|
|
|
2020-09-07 04:51:20 +00:00
|
|
|
event LogNewFlusher(address indexed owner, address indexed flusher, address indexed logic);
|
2020-08-24 17:30:39 +00:00
|
|
|
|
2020-09-06 21:11:23 +00:00
|
|
|
// deploy create2 + minimal proxy
|
|
|
|
function deployLogic(address owner, address logic) public returns (address proxy) {
|
2020-09-07 04:51:20 +00:00
|
|
|
require(!(isFlusherDeployed(getAddress(owner, logic))), "flusher-already-deployed");
|
2020-08-24 17:30:39 +00:00
|
|
|
bytes32 salt = keccak256(abi.encodePacked(owner));
|
|
|
|
bytes20 targetBytes = bytes20(logic);
|
|
|
|
// solium-disable-next-line security/no-inline-assembly
|
|
|
|
assembly {
|
2020-09-06 21:11:23 +00:00
|
|
|
let clone := mload(0x40)
|
|
|
|
mstore(
|
|
|
|
clone,
|
|
|
|
0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
|
|
|
|
)
|
|
|
|
mstore(add(clone, 0x14), targetBytes)
|
|
|
|
mstore(
|
|
|
|
add(clone, 0x28),
|
|
|
|
0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
|
|
|
|
)
|
|
|
|
proxy := create2(0, clone, 0x37, salt)
|
2020-08-24 17:30:39 +00:00
|
|
|
}
|
2020-09-07 04:51:20 +00:00
|
|
|
flushers[proxy] = true;
|
|
|
|
emit LogNewFlusher(owner, proxy, logic);
|
2020-08-24 17:30:39 +00:00
|
|
|
}
|
|
|
|
|
2020-09-06 21:11:23 +00:00
|
|
|
function isFlusherDeployed(address _address) public view returns (bool) {
|
|
|
|
uint32 size;
|
|
|
|
assembly {
|
|
|
|
size := extcodesize(_address)
|
|
|
|
}
|
|
|
|
return (size > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// compute create2 + minimal proxy address
|
2020-08-24 17:30:39 +00:00
|
|
|
function getAddress(address owner, address logic) public view returns (address) {
|
|
|
|
bytes32 codeHash = keccak256(getCreationCode(logic));
|
|
|
|
bytes32 salt = keccak256(abi.encodePacked(owner));
|
|
|
|
bytes32 rawAddress = keccak256(
|
|
|
|
abi.encodePacked(
|
|
|
|
bytes1(0xff),
|
|
|
|
address(this),
|
|
|
|
salt,
|
|
|
|
codeHash
|
2020-09-06 21:11:23 +00:00
|
|
|
)
|
|
|
|
);
|
|
|
|
return address(bytes20(rawAddress << 96));
|
2020-08-24 17:30:39 +00:00
|
|
|
}
|
2020-09-06 21:11:23 +00:00
|
|
|
|
2020-08-24 17:30:39 +00:00
|
|
|
function getCreationCode(address logic) public pure returns (bytes memory) {
|
|
|
|
bytes20 a = bytes20(0x3D602d80600A3D3981F3363d3d373d3D3D363d73);
|
|
|
|
bytes20 b = bytes20(logic);
|
|
|
|
bytes15 c = bytes15(0x5af43d82803e903d91602b57fd5bf3);
|
|
|
|
return abi.encodePacked(a, b, c);
|
|
|
|
}
|
2020-09-06 21:11:23 +00:00
|
|
|
}
|