yield-contract/contracts/deployer.sol

152 lines
4.6 KiB
Solidity
Raw Normal View History

// SPDX-License-Identifier: MIT
2020-09-12 09:33:57 +00:00
pragma solidity ^0.6.8;
2020-09-12 10:05:49 +00:00
contract Controller {
2020-09-12 10:05:49 +00:00
event LogNewMaster(address indexed master);
event LogUpdateMaster(address indexed master);
event LogEnableConnector(address indexed connector);
event LogDisableConnector(address indexed connector);
2020-09-12 10:12:37 +00:00
event LogAddSigner(address indexed signer);
event LogRemoveSigner(address indexed signer);
2020-09-12 10:05:49 +00:00
address private newMaster;
address public master;
mapping (address => bool) public connectors;
2020-09-12 10:12:37 +00:00
mapping (address => bool) public signer;
2020-09-12 10:05:49 +00:00
modifier isMaster() {
require(msg.sender == master, "not-master");
_;
}
// change the master address
function changeMaster(address _newMaster) external isMaster {
require(_newMaster != master, "already-a-master");
require(_newMaster != address(0), "not-valid-address");
require(newMaster != _newMaster, "already-a-new-master");
newMaster = _newMaster;
emit LogNewMaster(_newMaster);
}
// new master claiming master position
function claimMaster() external {
require(newMaster != address(0), "not-valid-address");
require(msg.sender == newMaster, "not-new-master");
master = newMaster;
newMaster = address(0);
emit LogUpdateMaster(master);
}
2020-09-12 10:12:37 +00:00
// enable connector
function enableConnector(address _connector) external isMaster {
require(!connectors[_connector], "already-enabled");
require(_connector != address(0), "invalid-connector");
connectors[_connector] = true;
emit LogEnableConnector(_connector);
}
2020-09-12 10:12:37 +00:00
// disable connector
function disableConnector(address _connector) external isMaster {
require(connectors[_connector], "already-disabled");
delete connectors[_connector];
emit LogDisableConnector(_connector);
}
2020-09-12 10:12:37 +00:00
// enable signer
function enableSigner(address _signer) external isMaster {
require(_signer != address(0), "invalid-address");
require(!signer[_signer], "signer-already-enabled");
signer[_signer] = true;
emit LogAddSigner(_signer);
}
// disable signer
function disableSigner(address _signer) external isMaster {
require(_signer != address(0), "invalid-address");
require(signer[_signer], "signer-already-disabled");
delete signer[_signer];
emit LogRemoveSigner(_signer);
}
// check if connectors[] are enabled
function isConnector(address[] calldata _connectors) external view returns (bool isOk) {
isOk = true;
for (uint i = 0; i < _connectors.length; i++) {
if (!connectors[_connectors[i]]) {
isOk = false;
break;
}
}
}
2020-09-12 10:05:49 +00:00
}
contract InstaDeployer is Controller {
2020-09-12 10:05:49 +00:00
event LogNewFlusher(address indexed owner, address indexed flusher, address indexed logic);
mapping (address => address) public flushers;
// deploy create2 + minimal proxy
2020-09-13 17:08:14 +00:00
function deployFlusher(address owner, address logic) public returns (address proxy) {
2020-09-12 10:05:49 +00:00
require(!(isFlusherDeployed(getAddress(owner, logic))), "flusher-already-deployed");
2020-09-12 20:48:06 +00:00
bytes32 salt = keccak256(abi.encodePacked(owner, logic));
2020-09-12 10:05:49 +00:00
bytes20 targetBytes = bytes20(logic);
// solium-disable-next-line security/no-inline-assembly
assembly {
let clone := mload(0x40)
mstore(
clone,
0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
)
mstore(add(clone, 0x14), targetBytes)
mstore(
add(clone, 0x28),
0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
)
proxy := create2(0, clone, 0x37, salt)
}
flushers[proxy] = owner;
emit LogNewFlusher(owner, proxy, logic);
}
// is flusher deployed?
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
function getAddress(address owner, address logic) public view returns (address) {
bytes32 codeHash = keccak256(getCreationCode(logic));
2020-09-11 20:16:55 +00:00
bytes32 salt = keccak256(abi.encodePacked(owner, logic));
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-09-06 21:11:23 +00:00
// get logic contract creation code
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-12 10:05:49 +00:00
constructor(address _master) public {
master = _master;
emit LogUpdateMaster(master);
}
2020-09-06 21:11:23 +00:00
}