From 42bd6579910a20ffba9ce652101f2162c2dff9ac Mon Sep 17 00:00:00 2001 From: Sowmayjain Date: Sun, 10 Mar 2019 16:53:11 +0530 Subject: [PATCH] Added logics for guardians in user proxy. --- ProxyLogics/sendETH.sol | 13 ++++ ProxyRegistry.sol | 145 +++------------------------------------- UserProxy.sol | 78 ++++++++++----------- 3 files changed, 59 insertions(+), 177 deletions(-) create mode 100644 ProxyLogics/sendETH.sol diff --git a/ProxyLogics/sendETH.sol b/ProxyLogics/sendETH.sol new file mode 100644 index 0000000..38ea87f --- /dev/null +++ b/ProxyLogics/sendETH.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.4.23; + + +contract ProxyTest { + + event ETHSent(uint amt); + + function sendETH() public payable { + address(msg.sender).transfer(msg.value); + emit ETHSent(msg.value); + } + +} \ No newline at end of file diff --git a/ProxyRegistry.sol b/ProxyRegistry.sol index a7ff67a..cf289fc 100644 --- a/ProxyRegistry.sol +++ b/ProxyRegistry.sol @@ -1,137 +1,7 @@ pragma solidity ^0.4.23; -contract UserAuthority { - function canCall(address src, address dst, bytes4 sig) public view returns (bool); -} - -contract UserAuthEvents { - event LogSetAuthority (address indexed authority); - event LogSetOwner (address indexed owner); -} - -contract UserAuth is UserAuthEvents { - UserAuthority public authority; - address public owner; - - constructor() public { - owner = msg.sender; - emit LogSetOwner(msg.sender); - } - - function setOwner(address owner_) - public - auth - { - owner = owner_; - emit LogSetOwner(owner); - } - - function setAuthority(UserAuthority authority_) - public - auth - { - authority = authority_; - emit LogSetAuthority(authority); - } - - modifier auth { - require(isAuthorized(msg.sender, msg.sig)); - _; - } - - function isAuthorized(address src, bytes4 sig) internal view returns (bool) { - if (src == address(this)) { - return true; - } else if (src == owner) { - return true; - } else if (authority == UserAuthority(0)) { - return false; - } else { - return authority.canCall(src, this, sig); - } - } -} - -contract UserNote { - event LogNote( - bytes4 indexed sig, - address indexed guy, - bytes32 indexed foo, - bytes32 indexed bar, - uint wad, - bytes fax - ) anonymous; - - modifier note { - bytes32 foo; - bytes32 bar; - - assembly { - foo := calldataload(4) - bar := calldataload(36) - } - - emit LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); - - _; - } -} - -interface LogicRegistry { - function getLogic(address logicAddr) external view returns(bool); -} - -contract LogicProxy { - address public logicProxyAddr; - - function isLogic(address logicAddr) internal view returns(bool) { - LogicRegistry logicProxy = LogicRegistry(logicProxyAddr); - return logicProxy.getLogic(logicAddr); - } -} - -// UserProxy -// Allows code execution using a persistant identity This can be very -// useful to execute a sequence of atomic actions. Since the owner of -// the proxy can be changed, this allows for dynamic ownership models -// i.e. a multisig -contract UserProxy is UserAuth, UserNote, LogicProxy { - - constructor(address logicProxyAddr_) public { - logicProxyAddr = logicProxyAddr_; - } - - function() external payable {} - - function execute(address _target, bytes memory _data) - public - auth - note - payable - returns (bytes memory response) - { - require(_target != address(0), "user-proxy-target-address-required"); - require(isLogic(_target), "invalid-logic-proxy-address"); - - // call contract in current context - assembly { - let succeeded := delegatecall(sub(gas, 5000), _target, add(_data, 0x20), mload(_data), 0, 0) - let size := returndatasize - - response := mload(0x40) - mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - mstore(response, size) - returndatacopy(add(response, 0x20), 0, size) - - switch iszero(succeeded) - case 1 { - // throw if delegatecall failed - revert(add(response, 0x20), size) - } - } - } -} +import "./UserProxy.sol"; // ProxyRegistry contract ProxyRegistry { @@ -145,15 +15,18 @@ contract ProxyRegistry { // deploys a new proxy instance // sets owner of proxy to caller - function build() public returns (UserProxy proxy) { - proxy = build(msg.sender); + function build(uint activeDays) public returns (UserProxy proxy) { + proxy = build(msg.sender, activeDays); } // deploys a new proxy instance // sets custom owner of proxy - function build(address owner) public returns (UserProxy proxy) { - require(proxies[owner] == UserProxy(0) || proxies[owner].owner() != owner); // Not allow new proxy if the user already has one and remains being the owner - proxy = new UserProxy(logicProxyAddr); + function build(address owner, uint activeDays) public returns (UserProxy proxy) { + require( + proxies[owner] == UserProxy(0) || proxies[owner].owner() != owner, + "multiple-proxy-per-user-not-allowed" + ); // Not allow new proxy if the user already has one and remains being the owner + proxy = new UserProxy(logicProxyAddr, activeDays); emit Created(msg.sender, owner, address(proxy)); proxy.setOwner(owner); proxies[owner] = proxy; diff --git a/UserProxy.sol b/UserProxy.sol index 897c85a..456b522 100644 --- a/UserProxy.sol +++ b/UserProxy.sol @@ -1,58 +1,56 @@ pragma solidity ^0.4.23; -contract UserAuthority { - function canCall(address src, address dst, bytes4 sig) public view returns (bool); -} +contract UserAuth { + event LogSetOwner(address indexed owner, bool isGuardian); + event LogSetGuardian(address indexed guardian); -contract UserAuthEvents { - event LogSetAuthority (address indexed authority); - event LogSetOwner (address indexed owner); -} - -contract UserAuth is UserAuthEvents { - UserAuthority public authority; - address public owner; + mapping(uint => address) public guardians; + address public owner; + uint public lastActivity; // timestamp + uint public activePeriod; // timestamp // guardians can set owner after owner stay inactive for certain period constructor() public { owner = msg.sender; - emit LogSetOwner(msg.sender); - } - - function setOwner(address owner_) - public - auth - { - owner = owner_; - emit LogSetOwner(owner); - } - - function setAuthority(UserAuthority authority_) - public - auth - { - authority = authority_; - emit LogSetAuthority(authority); + emit LogSetOwner(msg.sender, false); } modifier auth { - require(isAuthorized(msg.sender, msg.sig)); + require(isAuth(msg.sender), "permission-denied"); _; } - function isAuthorized(address src, bytes4 sig) internal view returns (bool) { + function isAuth(address src) internal view returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; - } else if (authority == UserAuthority(0)) { - return false; } else { - return authority.canCall(src, this, sig); + return false; } } + + function setOwner(address owner_) public auth { + owner = owner_; + emit LogSetOwner(owner, false); + } + + function setOwnerViaGuardian(address owner_, uint num) public auth { + require(msg.sender == guardians[num], "permission-denied"); + require(block.timestamp > (lastActivity + activePeriod), "active-period-not-over"); + owner = owner_; + emit LogSetOwner(owner, true); + } + + function setGuardian(uint num, address guardian_) public auth { + require(num > 0 && num < 6, "guardians-cant-exceed-five"); + guardians[num] = guardian_; + emit LogSetGuardian(guardian_); + } + } + contract UserNote { event LogNote( bytes4 indexed sig, @@ -66,14 +64,11 @@ contract UserNote { modifier note { bytes32 foo; bytes32 bar; - assembly { foo := calldataload(4) bar := calldataload(36) } - emit LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); - _; } } @@ -82,10 +77,10 @@ interface LogicRegistry { function getLogic(address logicAddr) external view returns(bool); } +// checking if the logic proxy is authorised contract LogicProxy { address public logicProxyAddr; - - function isLogic(address logicAddr) internal view returns(bool) { + function isAuthLogic(address logicAddr) internal view returns(bool) { LogicRegistry logicProxy = LogicRegistry(logicProxyAddr); return logicProxy.getLogic(logicAddr); } @@ -98,8 +93,10 @@ contract LogicProxy { // i.e. a multisig contract UserProxy is UserAuth, UserNote, LogicProxy { - constructor(address logicProxyAddr_) public { + constructor(address logicProxyAddr_, uint activePeriod_) public { logicProxyAddr = logicProxyAddr_; + lastActivity = block.timestamp; + activePeriod = activePeriod_; } function() external payable {} @@ -112,8 +109,7 @@ contract UserProxy is UserAuth, UserNote, LogicProxy { returns (bytes memory response) { require(_target != address(0), "user-proxy-target-address-required"); - require(isLogic(_target), "invalid-logic-proxy-address"); - + require(isAuthLogic(_target), "logic-proxy-address-not-allowed"); // call contract in current context assembly { let succeeded := delegatecall(sub(gas, 5000), _target, add(_data, 0x20), mload(_data), 0, 0)