Transaction Hash:
Block:
7741401 at May-11-2019 08:36:33 PM +UTC
Transaction Fee:
0.000830244 ETH
$1.65
Gas Used:
691,870 Gas / 1.2 Gwei
Emitted Events:
| 48 |
InstaRegistry.LogRecord( currentOwner=[Receiver] InstaRegistry, nextOwner=[Sender] 0xb6b788f332933d7623b816222b0cc27be181ddce, proxy=0xb4c0de3533bc0a8ec64915cf6f2850ee756bff20 )
|
| 49 |
0xb4c0de3533bc0a8ec64915cf6f2850ee756bff20.0xce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed94( 0xce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed94, 0x000000000000000000000000b6b788f332933d7623b816222b0cc27be181ddce )
|
| 50 |
InstaRegistry.Created( sender=[Sender] 0xb6b788f332933d7623b816222b0cc27be181ddce, owner=[Sender] 0xb6b788f332933d7623b816222b0cc27be181ddce, proxy=0xb4c0de3533bc0a8ec64915cf6f2850ee756bff20 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x498b3Bfa...8Cd0Fd981 | (InstaDApp: Registry) | ||||
|
0x52bc44d5...b7d7bE3b5
Miner
| (Nanopool) | 6,898.208528760789191523 Eth | 6,898.209359004789191523 Eth | 0.000830244 | |
| 0xb4C0DE35...e756Bff20 |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
| |||
| 0xb6b788f3...bE181ddCe |
2.53292806 Eth
Nonce: 0
|
2.532097816 Eth
Nonce: 1
| 0.000830244 |
Execution Trace
InstaRegistry.CALL( )
-
0xb4c0de3533bc0a8ec64915cf6f2850ee756bff20.60806040( ) 0xb4c0de3533bc0a8ec64915cf6f2850ee756bff20.13af4035( )-
InstaRegistry.record( _currentOwner=0x498b3BfaBE9F73db90D252bCD4Fa9548Cd0Fd981, _nextOwner=0xb6b788f332933D7623B816222B0cC27bE181ddCe )
-
pragma solidity ^0.5.2;
/**
* @title RegistryInterface Interface
*/
interface RegistryInterface {
function logic(address logicAddr) external view returns (bool);
function record(address currentOwner, address nextOwner) external;
}
/**
* @title Address Registry Record
*/
contract AddressRecord {
/**
* @dev address registry of system, logic and wallet addresses
*/
address public registry;
/**
* @dev Throws if the logic is not authorised
*/
modifier logicAuth(address logicAddr) {
require(logicAddr != address(0), "logic-proxy-address-required");
require(RegistryInterface(registry).logic(logicAddr), "logic-not-authorised");
_;
}
}
/**
* @title User Auth
*/
contract UserAuth is AddressRecord {
event LogSetOwner(address indexed owner);
address public owner;
/**
* @dev Throws if not called by owner or contract itself
*/
modifier auth {
require(isAuth(msg.sender), "permission-denied");
_;
}
/**
* @dev sets new owner
*/
function setOwner(address nextOwner) public auth {
RegistryInterface(registry).record(owner, nextOwner);
owner = nextOwner;
emit LogSetOwner(nextOwner);
}
/**
* @dev checks if called by owner or contract itself
* @param src is the address initiating the call
*/
function isAuth(address src) public view returns (bool) {
if (src == owner) {
return true;
} else if (src == address(this)) {
return true;
}
return false;
}
}
/**
* @dev logging the execute events
*/
contract UserNote {
event LogNote(
bytes4 indexed sig,
address indexed guy,
bytes32 indexed foo,
bytes32 bar,
uint wad,
bytes fax
);
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
);
_;
}
}
/**
* @title User Owned Contract Wallet
*/
contract UserWallet is UserAuth, UserNote {
event LogExecute(address target, uint srcNum, uint sessionNum);
/**
* @dev sets the "address registry", owner's last activity, owner's active period and initial owner
*/
constructor() public {
registry = msg.sender;
owner = msg.sender;
}
function() external payable {}
/**
* @dev Execute authorised calls via delegate call
* @param _target logic proxy address
* @param _data delegate call data
* @param _src to find the source
* @param _session to find the session
*/
function execute(
address _target,
bytes memory _data,
uint _src,
uint _session
)
public
payable
note
auth
logicAuth(_target)
returns (bytes memory response)
{
emit LogExecute(
_target,
_src,
_session
);
// 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)
}
}
}
}
/// @title AddressRegistry
/// @notice
/// @dev
contract AddressRegistry {
event LogSetAddress(string name, address addr);
/// @notice Registry of role and address
mapping(bytes32 => address) registry;
/**
* @dev Check if msg.sender is admin or owner.
*/
modifier isAdmin() {
require(
msg.sender == getAddress("admin") ||
msg.sender == getAddress("owner"),
"permission-denied"
);
_;
}
/// @dev Get the address from system registry
/// @param _name (string)
/// @return (address) Returns address based on role
function getAddress(string memory _name) public view returns(address) {
return registry[keccak256(abi.encodePacked(_name))];
}
/// @dev Set new address in system registry
/// @param _name (string) Role name
/// @param _userAddress (string) User Address
function setAddress(string memory _name, address _userAddress) public isAdmin {
registry[keccak256(abi.encodePacked(_name))] = _userAddress;
emit LogSetAddress(_name, _userAddress);
}
}
/// @title LogicRegistry
/// @notice
/// @dev LogicRegistry
contract LogicRegistry is AddressRegistry {
event LogEnableStaticLogic(address logicAddress);
event LogEnableLogic(address logicAddress);
event LogDisableLogic(address logicAddress);
/// @notice Map of static proxy state
mapping(address => bool) public logicProxiesStatic;
/// @notice Map of logic proxy state
mapping(address => bool) public logicProxies;
/// @dev
/// @param _logicAddress (address)
/// @return (bool)
function logic(address _logicAddress) public view returns (bool) {
if (logicProxiesStatic[_logicAddress] || logicProxies[_logicAddress]) {
return true;
}
return false;
}
/// @dev
/// @param _logicAddress (address)
/// @return (bool)
function logicStatic(address _logicAddress) public view returns (bool) {
if (logicProxiesStatic[_logicAddress]) {
return true;
}
return false;
}
/// @dev Sets the static logic proxy to true
/// static proxies mostly contains the logic for withdrawal of assets
/// and can never be false to freely let user withdraw their assets
/// @param _logicAddress (address)
function enableStaticLogic(address _logicAddress) public isAdmin {
logicProxiesStatic[_logicAddress] = true;
emit LogEnableStaticLogic(_logicAddress);
}
/// @dev Enable logic proxy address
/// @param _logicAddress (address)
function enableLogic(address _logicAddress) public isAdmin {
logicProxies[_logicAddress] = true;
emit LogEnableLogic(_logicAddress);
}
/// @dev Disable logic proxy address
/// @param _logicAddress (address)
function disableLogic(address _logicAddress) public isAdmin {
logicProxies[_logicAddress] = false;
emit LogDisableLogic(_logicAddress);
}
}
/**
* @dev Deploys a new proxy instance and sets msg.sender as owner of proxy
*/
contract WalletRegistry is LogicRegistry {
event Created(address indexed sender, address indexed owner, address proxy);
event LogRecord(address indexed currentOwner, address indexed nextOwner, address proxy);
/// @notice Address to UserWallet proxy map
mapping(address => UserWallet) public proxies;
/// @dev Deploys a new proxy instance and sets custom owner of proxy
/// Throws if the owner already have a UserWallet
/// @return proxy ()
function build() public returns (UserWallet proxy) {
proxy = build(msg.sender);
}
/// @dev update the proxy record whenever owner changed on any proxy
/// Throws if msg.sender is not a proxy contract created via this contract
/// @return proxy () UserWallet
function build(address _owner) public returns (UserWallet proxy) {
require(proxies[_owner] == UserWallet(0), "multiple-proxy-per-user-not-allowed");
proxy = new UserWallet();
proxies[address(this)] = proxy; // will be changed via record() in next line execution
proxy.setOwner(_owner);
emit Created(msg.sender, _owner, address(proxy));
}
/// @dev Transafers ownership
/// @param _currentOwner (address) Current Owner
/// @param _nextOwner (address) Next Owner
function record(address _currentOwner, address _nextOwner) public {
require(msg.sender == address(proxies[_currentOwner]), "invalid-proxy-or-owner");
require(proxies[_nextOwner] == UserWallet(0), "multiple-proxy-per-user-not-allowed");
proxies[_nextOwner] = proxies[_currentOwner];
proxies[_currentOwner] = UserWallet(0);
emit LogRecord(_currentOwner, _nextOwner, address(proxies[_nextOwner]));
}
}
/// @title InstaRegistry
/// @dev Initializing Registry
contract InstaRegistry is WalletRegistry {
constructor() public {
registry[keccak256(abi.encodePacked("admin"))] = msg.sender;
registry[keccak256(abi.encodePacked("owner"))] = msg.sender;
}
}