diff --git a/contracts/flusher/logic.sol b/contracts/flusher/logic.sol index e69de29..08e0698 100644 --- a/contracts/flusher/logic.sol +++ b/contracts/flusher/logic.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.8; +pragma experimental ABIEncoderV2; + +interface DeployerInterface { + function signer(address) external view returns (bool); + function master() external view returns (address); + function isConnector(address[] calldata) external view returns (bool); + function implementationLogic(address) external view returns (bool); +} + +contract Setup { + + function deployer() public pure returns (DeployerInterface) { + return DeployerInterface(address(0)); // TODO - change. + } + + string constant public name = "Flusher-v1"; + + function spell(address _target, bytes memory _data) internal { + require(_target != address(0), "target-invalid"); + assembly { + let succeeded := delegatecall(gas(), _target, add(_data, 0x20), mload(_data), 0, 0) + switch iszero(succeeded) + case 1 { + let size := returndatasize() + returndatacopy(0x00, 0x00, size) + revert(0x00, size) + } + } + } + +} + +contract UpgradeableProxy is Setup { + event Upgraded(address indexed implementation); + + /** + * @dev Storage slot with the address of the current implementation. + * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1. + */ + bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + + function changeImplementation(address newImplementation) public { + require(deployer().master() == msg.sender, "not-master"); + require(deployer().implementationLogic(newImplementation), "not-whitelisted-logic"); + // require(Address.isContract(newImplementation), "UpgradeableProxy: new implementation is not a contract"); + + bytes32 slot = _IMPLEMENTATION_SLOT; + + // solhint-disable-next-line no-inline-assembly + assembly { + sstore(slot, newImplementation) + } + emit Upgraded(newImplementation); + } +} + + +contract Flusher is UpgradeableProxy { + event LogCast(address indexed sender, uint value); + + function cast(address[] calldata _targets, bytes[] calldata _datas) external payable { + require(deployer().signer(msg.sender), "not-signer"); + require(_targets.length == _datas.length , "invalid-array-length"); + require(deployer().isConnector(_targets), "not-connector"); + for (uint i = 0; i < _targets.length; i++) { + spell(_targets[i], _datas[i]); + } + emit LogCast(msg.sender, msg.value); + } + + receive() external payable {} +} \ No newline at end of file