// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; import "../access/Controlled.sol"; import "./AccountBase.sol"; /** * @title Account * * @author Stanisław Głogowski */ contract Account is Controlled, AccountBase { address public implementation; /** * @dev Public constructor * @param registry_ account registry address * @param implementation_ account implementation address */ constructor( address registry_, address implementation_ ) public Controlled() { registry = registry_; implementation = implementation_; } // external functions /** * @notice Payable receive */ receive() external payable { // } /** * @notice Fallback */ // solhint-disable-next-line payable-fallback fallback() external { if (msg.data.length != 0) { address implementation_ = implementation; // solhint-disable-next-line no-inline-assembly assembly { let calldedatasize := calldatasize() calldatacopy(0, 0, calldedatasize) let result := delegatecall(gas(), implementation_, 0, calldedatasize, 0, 0) let returneddatasize := returndatasize() returndatacopy(0, 0, returneddatasize) switch result case 0 { revert(0, returneddatasize) } default { return(0, returneddatasize) } } } } /** * @notice Sets implementation * @param implementation_ implementation address */ function setImplementation( address implementation_ ) external onlyController { implementation = implementation_; } /** * @notice Executes transaction * @param to to address * @param value value * @param data data * @return transaction result */ function executeTransaction( address to, uint256 value, bytes calldata data ) external onlyController returns (bytes memory) { bytes memory result; bool succeeded; // solhint-disable-next-line avoid-call-value, avoid-low-level-calls (succeeded, result) = payable(to).call{value: value}(data); require( succeeded, "Account: transaction reverted" ); return result; } }