ETH Price: $4,283.35 (+0.10%)

Transaction Decoder

Block:
13279399 at Sep-23-2021 02:50:39 AM +UTC
Transaction Fee:
0.002133627456608 ETH $9.14
Gas Used:
32,000 Gas / 66.675858019 Gwei

Account State Difference:

  Address   Before After State Difference Code
(Hiveon Pool)
5,333.981757165004444027 Eth5,333.981821165004444027 Eth0.000064
0x868060A4...EC49E2bDd
0.024577171767047888 Eth
Nonce: 2
0.022443544310439888 Eth
Nonce: 3
0.002133627456608

Execution Trace

ValidatorShareProxy.6ab15071( )
  • Registry.STATICCALL( )
    File 1 of 2: ValidatorShareProxy
    // File: openzeppelin-solidity/contracts/ownership/Ownable.sol
    
    pragma solidity ^0.5.2;
    
    /**
     * @title Ownable
     * @dev The Ownable contract has an owner address, and provides basic authorization control
     * functions, this simplifies the implementation of "user permissions".
     */
    contract Ownable {
        address private _owner;
    
        event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
        /**
         * @dev The Ownable constructor sets the original `owner` of the contract to the sender
         * account.
         */
        constructor () internal {
            _owner = msg.sender;
            emit OwnershipTransferred(address(0), _owner);
        }
    
        /**
         * @return the address of the owner.
         */
        function owner() public view returns (address) {
            return _owner;
        }
    
        /**
         * @dev Throws if called by any account other than the owner.
         */
        modifier onlyOwner() {
            require(isOwner());
            _;
        }
    
        /**
         * @return true if `msg.sender` is the owner of the contract.
         */
        function isOwner() public view returns (bool) {
            return msg.sender == _owner;
        }
    
        /**
         * @dev Allows the current owner to relinquish control of the contract.
         * It will not be possible to call the functions with the `onlyOwner`
         * modifier anymore.
         * @notice Renouncing ownership will leave the contract without an owner,
         * thereby removing any functionality that is only available to the owner.
         */
        function renounceOwnership() public onlyOwner {
            emit OwnershipTransferred(_owner, address(0));
            _owner = address(0);
        }
    
        /**
         * @dev Allows the current owner to transfer control of the contract to a newOwner.
         * @param newOwner The address to transfer ownership to.
         */
        function transferOwnership(address newOwner) public onlyOwner {
            _transferOwnership(newOwner);
        }
    
        /**
         * @dev Transfers control of the contract to a newOwner.
         * @param newOwner The address to transfer ownership to.
         */
        function _transferOwnership(address newOwner) internal {
            require(newOwner != address(0));
            emit OwnershipTransferred(_owner, newOwner);
            _owner = newOwner;
        }
    }
    
    // File: contracts/common/misc/ProxyStorage.sol
    
    pragma solidity ^0.5.2;
    
    
    contract ProxyStorage is Ownable {
        address internal proxyTo;
    }
    
    // File: contracts/common/misc/ERCProxy.sol
    
    /*
     * SPDX-License-Identitifer:    MIT
     */
    
    pragma solidity ^0.5.2;
    
    // See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-897.md
    
    interface ERCProxy {
        function proxyType() external pure returns (uint256 proxyTypeId);
        function implementation() external view returns (address codeAddr);
    }
    
    // File: contracts/common/misc/DelegateProxy.sol
    
    pragma solidity ^0.5.2;
    
    
    
    contract DelegateProxy is ERCProxy {
        function proxyType() external pure returns (uint256 proxyTypeId) {
            // Upgradeable proxy
            proxyTypeId = 2;
        }
    
        function implementation() external view returns (address);
    
        function delegatedFwd(address _dst, bytes memory _calldata) internal {
            // solium-disable-next-line security/no-inline-assembly
            assembly {
                let result := delegatecall(
                    sub(gas, 10000),
                    _dst,
                    add(_calldata, 0x20),
                    mload(_calldata),
                    0,
                    0
                )
                let size := returndatasize
    
                let ptr := mload(0x40)
                returndatacopy(ptr, 0, size)
    
                // revert instead of invalid() bc if the underlying call failed with invalid() it already wasted gas.
                // if the call returned error data, forward it
                switch result
                    case 0 {
                        revert(ptr, size)
                    }
                    default {
                        return(ptr, size)
                    }
            }
        }
    }
    
    // File: contracts/common/misc/UpgradableProxy.sol
    
    pragma solidity ^0.5.2;
    
    
    contract UpgradableProxy is DelegateProxy {
        event ProxyUpdated(address indexed _new, address indexed _old);
        event OwnerUpdate(address _new, address _old);
    
        bytes32 constant IMPLEMENTATION_SLOT = keccak256("matic.network.proxy.implementation");
        bytes32 constant OWNER_SLOT = keccak256("matic.network.proxy.owner");
    
        constructor(address _proxyTo) public {
            setOwner(msg.sender);
            setImplementation(_proxyTo);
        }
    
        function() external payable {
            // require(currentContract != 0, "If app code has not been set yet, do not call");
            // Todo: filter out some calls or handle in the end fallback
            delegatedFwd(loadImplementation(), msg.data);
        }
    
        modifier onlyProxyOwner() {
            require(loadOwner() == msg.sender, "NOT_OWNER");
            _;
        }
    
        function owner() external view returns(address) {
            return loadOwner();
        }
    
        function loadOwner() internal view returns(address) {
            address _owner;
            bytes32 position = OWNER_SLOT;
            assembly {
                _owner := sload(position)
            }
            return _owner;
        }
    
        function implementation() external view returns (address) {
            return loadImplementation();
        }
    
        function loadImplementation() internal view returns(address) {
            address _impl;
            bytes32 position = IMPLEMENTATION_SLOT;
            assembly {
                _impl := sload(position)
            }
            return _impl;
        }
    
        function transferOwnership(address newOwner) public onlyProxyOwner {
            require(newOwner != address(0), "ZERO_ADDRESS");
            emit OwnerUpdate(newOwner, loadOwner());
            setOwner(newOwner);
        }
    
        function setOwner(address newOwner) private {
            bytes32 position = OWNER_SLOT;
            assembly {
                sstore(position, newOwner)
            }
        }
    
        function updateImplementation(address _newProxyTo) public onlyProxyOwner {
            require(_newProxyTo != address(0x0), "INVALID_PROXY_ADDRESS");
            require(isContract(_newProxyTo), "DESTINATION_ADDRESS_IS_NOT_A_CONTRACT");
    
            emit ProxyUpdated(_newProxyTo, loadImplementation());
            
            setImplementation(_newProxyTo);
        }
    
        function updateAndCall(address _newProxyTo, bytes memory data) payable public onlyProxyOwner {
            updateImplementation(_newProxyTo);
    
            (bool success, bytes memory returnData) = address(this).call.value(msg.value)(data);
            require(success, string(returnData));
        }
    
        function setImplementation(address _newProxyTo) private {
            bytes32 position = IMPLEMENTATION_SLOT;
            assembly {
                sstore(position, _newProxyTo)
            }
        }
        
        function isContract(address _target) internal view returns (bool) {
            if (_target == address(0)) {
                return false;
            }
    
            uint256 size;
            assembly {
                size := extcodesize(_target)
            }
            return size > 0;
        }
    }
    
    // File: contracts/common/governance/IGovernance.sol
    
    pragma solidity ^0.5.2;
    
    interface IGovernance {
        function update(address target, bytes calldata data) external;
    }
    
    // File: contracts/common/governance/Governable.sol
    
    pragma solidity ^0.5.2;
    
    
    contract Governable {
        IGovernance public governance;
    
        constructor(address _governance) public {
            governance = IGovernance(_governance);
        }
    
        modifier onlyGovernance() {
            require(
                msg.sender == address(governance),
                "Only governance contract is authorized"
            );
            _;
        }
    }
    
    // File: contracts/root/withdrawManager/IWithdrawManager.sol
    
    pragma solidity ^0.5.2;
    
    contract IWithdrawManager {
        function createExitQueue(address token) external;
    
        function verifyInclusion(
            bytes calldata data,
            uint8 offset,
            bool verifyTxInclusion
        ) external view returns (uint256 age);
    
        function addExitToQueue(
            address exitor,
            address childToken,
            address rootToken,
            uint256 exitAmountOrTokenId,
            bytes32 txHash,
            bool isRegularExit,
            uint256 priority
        ) external;
    
        function addInput(
            uint256 exitId,
            uint256 age,
            address utxoOwner,
            address token
        ) external;
    
        function challengeExit(
            uint256 exitId,
            uint256 inputId,
            bytes calldata challengeData,
            address adjudicatorPredicate
        ) external;
    }
    
    // File: contracts/common/Registry.sol
    
    pragma solidity ^0.5.2;
    
    
    
    
    contract Registry is Governable {
        // @todo hardcode constants
        bytes32 private constant WETH_TOKEN = keccak256("wethToken");
        bytes32 private constant DEPOSIT_MANAGER = keccak256("depositManager");
        bytes32 private constant STAKE_MANAGER = keccak256("stakeManager");
        bytes32 private constant VALIDATOR_SHARE = keccak256("validatorShare");
        bytes32 private constant WITHDRAW_MANAGER = keccak256("withdrawManager");
        bytes32 private constant CHILD_CHAIN = keccak256("childChain");
        bytes32 private constant STATE_SENDER = keccak256("stateSender");
        bytes32 private constant SLASHING_MANAGER = keccak256("slashingManager");
    
        address public erc20Predicate;
        address public erc721Predicate;
    
        mapping(bytes32 => address) public contractMap;
        mapping(address => address) public rootToChildToken;
        mapping(address => address) public childToRootToken;
        mapping(address => bool) public proofValidatorContracts;
        mapping(address => bool) public isERC721;
    
        enum Type {Invalid, ERC20, ERC721, Custom}
        struct Predicate {
            Type _type;
        }
        mapping(address => Predicate) public predicates;
    
        event TokenMapped(address indexed rootToken, address indexed childToken);
        event ProofValidatorAdded(address indexed validator, address indexed from);
        event ProofValidatorRemoved(address indexed validator, address indexed from);
        event PredicateAdded(address indexed predicate, address indexed from);
        event PredicateRemoved(address indexed predicate, address indexed from);
        event ContractMapUpdated(bytes32 indexed key, address indexed previousContract, address indexed newContract);
    
        constructor(address _governance) public Governable(_governance) {}
    
        function updateContractMap(bytes32 _key, address _address) external onlyGovernance {
            emit ContractMapUpdated(_key, contractMap[_key], _address);
            contractMap[_key] = _address;
        }
    
        /**
         * @dev Map root token to child token
         * @param _rootToken Token address on the root chain
         * @param _childToken Token address on the child chain
         * @param _isERC721 Is the token being mapped ERC721
         */
        function mapToken(
            address _rootToken,
            address _childToken,
            bool _isERC721
        ) external onlyGovernance {
            require(_rootToken != address(0x0) && _childToken != address(0x0), "INVALID_TOKEN_ADDRESS");
            rootToChildToken[_rootToken] = _childToken;
            childToRootToken[_childToken] = _rootToken;
            isERC721[_rootToken] = _isERC721;
            IWithdrawManager(contractMap[WITHDRAW_MANAGER]).createExitQueue(_rootToken);
            emit TokenMapped(_rootToken, _childToken);
        }
    
        function addErc20Predicate(address predicate) public onlyGovernance {
            require(predicate != address(0x0), "Can not add null address as predicate");
            erc20Predicate = predicate;
            addPredicate(predicate, Type.ERC20);
        }
    
        function addErc721Predicate(address predicate) public onlyGovernance {
            erc721Predicate = predicate;
            addPredicate(predicate, Type.ERC721);
        }
    
        function addPredicate(address predicate, Type _type) public onlyGovernance {
            require(predicates[predicate]._type == Type.Invalid, "Predicate already added");
            predicates[predicate]._type = _type;
            emit PredicateAdded(predicate, msg.sender);
        }
    
        function removePredicate(address predicate) public onlyGovernance {
            require(predicates[predicate]._type != Type.Invalid, "Predicate does not exist");
            delete predicates[predicate];
            emit PredicateRemoved(predicate, msg.sender);
        }
    
        function getValidatorShareAddress() public view returns (address) {
            return contractMap[VALIDATOR_SHARE];
        }
    
        function getWethTokenAddress() public view returns (address) {
            return contractMap[WETH_TOKEN];
        }
    
        function getDepositManagerAddress() public view returns (address) {
            return contractMap[DEPOSIT_MANAGER];
        }
    
        function getStakeManagerAddress() public view returns (address) {
            return contractMap[STAKE_MANAGER];
        }
    
        function getSlashingManagerAddress() public view returns (address) {
            return contractMap[SLASHING_MANAGER];
        }
    
        function getWithdrawManagerAddress() public view returns (address) {
            return contractMap[WITHDRAW_MANAGER];
        }
    
        function getChildChainAndStateSender() public view returns (address, address) {
            return (contractMap[CHILD_CHAIN], contractMap[STATE_SENDER]);
        }
    
        function isTokenMapped(address _token) public view returns (bool) {
            return rootToChildToken[_token] != address(0x0);
        }
    
        function isTokenMappedAndIsErc721(address _token) public view returns (bool) {
            require(isTokenMapped(_token), "TOKEN_NOT_MAPPED");
            return isERC721[_token];
        }
    
        function isTokenMappedAndGetPredicate(address _token) public view returns (address) {
            if (isTokenMappedAndIsErc721(_token)) {
                return erc721Predicate;
            }
            return erc20Predicate;
        }
    
        function isChildTokenErc721(address childToken) public view returns (bool) {
            address rootToken = childToRootToken[childToken];
            require(rootToken != address(0x0), "Child token is not mapped");
            return isERC721[rootToken];
        }
    }
    
    // File: contracts/staking/validatorShare/ValidatorShareProxy.sol
    
    pragma solidity ^0.5.2;
    
    
    
    contract ValidatorShareProxy is UpgradableProxy {
        constructor(address _registry) public UpgradableProxy(_registry) {}
    
        function loadImplementation() internal view returns (address) {
            return Registry(super.loadImplementation()).getValidatorShareAddress();
        }
    }

    File 2 of 2: Registry
    /**
    Matic network contracts
    */
    
    pragma solidity ^0.5.2;
    
    
    interface IGovernance {
        function update(address target, bytes calldata data) external;
    }
    
    contract Governable {
        IGovernance public governance;
    
        constructor(address _governance) public {
            governance = IGovernance(_governance);
        }
    
        modifier onlyGovernance() {
            require(
                msg.sender == address(governance),
                "Only governance contract is authorized"
            );
            _;
        }
    }
    
    contract IWithdrawManager {
        function createExitQueue(address token) external;
    
        function verifyInclusion(
            bytes calldata data,
            uint8 offset,
            bool verifyTxInclusion
        ) external view returns (uint256 age);
    
        function addExitToQueue(
            address exitor,
            address childToken,
            address rootToken,
            uint256 exitAmountOrTokenId,
            bytes32 txHash,
            bool isRegularExit,
            uint256 priority
        ) external;
    
        function addInput(
            uint256 exitId,
            uint256 age,
            address utxoOwner,
            address token
        ) external;
    
        function challengeExit(
            uint256 exitId,
            uint256 inputId,
            bytes calldata challengeData,
            address adjudicatorPredicate
        ) external;
    }
    
    contract Registry is Governable {
        // @todo hardcode constants
        bytes32 private constant WETH_TOKEN = keccak256("wethToken");
        bytes32 private constant DEPOSIT_MANAGER = keccak256("depositManager");
        bytes32 private constant STAKE_MANAGER = keccak256("stakeManager");
        bytes32 private constant VALIDATOR_SHARE = keccak256("validatorShare");
        bytes32 private constant WITHDRAW_MANAGER = keccak256("withdrawManager");
        bytes32 private constant CHILD_CHAIN = keccak256("childChain");
        bytes32 private constant STATE_SENDER = keccak256("stateSender");
        bytes32 private constant SLASHING_MANAGER = keccak256("slashingManager");
    
        address public erc20Predicate;
        address public erc721Predicate;
    
        mapping(bytes32 => address) public contractMap;
        mapping(address => address) public rootToChildToken;
        mapping(address => address) public childToRootToken;
        mapping(address => bool) public proofValidatorContracts;
        mapping(address => bool) public isERC721;
    
        enum Type {Invalid, ERC20, ERC721, Custom}
        struct Predicate {
            Type _type;
        }
        mapping(address => Predicate) public predicates;
    
        event TokenMapped(address indexed rootToken, address indexed childToken);
        event ProofValidatorAdded(address indexed validator, address indexed from);
        event ProofValidatorRemoved(address indexed validator, address indexed from);
        event PredicateAdded(address indexed predicate, address indexed from);
        event PredicateRemoved(address indexed predicate, address indexed from);
        event ContractMapUpdated(bytes32 indexed key, address indexed previousContract, address indexed newContract);
    
        constructor(address _governance) public Governable(_governance) {}
    
        function updateContractMap(bytes32 _key, address _address) external onlyGovernance {
            emit ContractMapUpdated(_key, contractMap[_key], _address);
            contractMap[_key] = _address;
        }
    
        /**
         * @dev Map root token to child token
         * @param _rootToken Token address on the root chain
         * @param _childToken Token address on the child chain
         * @param _isERC721 Is the token being mapped ERC721
         */
        function mapToken(
            address _rootToken,
            address _childToken,
            bool _isERC721
        ) external onlyGovernance {
            require(_rootToken != address(0x0) && _childToken != address(0x0), "INVALID_TOKEN_ADDRESS");
            rootToChildToken[_rootToken] = _childToken;
            childToRootToken[_childToken] = _rootToken;
            isERC721[_rootToken] = _isERC721;
            IWithdrawManager(contractMap[WITHDRAW_MANAGER]).createExitQueue(_rootToken);
            emit TokenMapped(_rootToken, _childToken);
        }
    
        function addErc20Predicate(address predicate) public onlyGovernance {
            require(predicate != address(0x0), "Can not add null address as predicate");
            erc20Predicate = predicate;
            addPredicate(predicate, Type.ERC20);
        }
    
        function addErc721Predicate(address predicate) public onlyGovernance {
            erc721Predicate = predicate;
            addPredicate(predicate, Type.ERC721);
        }
    
        function addPredicate(address predicate, Type _type) public onlyGovernance {
            require(predicates[predicate]._type == Type.Invalid, "Predicate already added");
            predicates[predicate]._type = _type;
            emit PredicateAdded(predicate, msg.sender);
        }
    
        function removePredicate(address predicate) public onlyGovernance {
            require(predicates[predicate]._type != Type.Invalid, "Predicate does not exist");
            delete predicates[predicate];
            emit PredicateRemoved(predicate, msg.sender);
        }
    
        function getValidatorShareAddress() public view returns (address) {
            return contractMap[VALIDATOR_SHARE];
        }
    
        function getWethTokenAddress() public view returns (address) {
            return contractMap[WETH_TOKEN];
        }
    
        function getDepositManagerAddress() public view returns (address) {
            return contractMap[DEPOSIT_MANAGER];
        }
    
        function getStakeManagerAddress() public view returns (address) {
            return contractMap[STAKE_MANAGER];
        }
    
        function getSlashingManagerAddress() public view returns (address) {
            return contractMap[SLASHING_MANAGER];
        }
    
        function getWithdrawManagerAddress() public view returns (address) {
            return contractMap[WITHDRAW_MANAGER];
        }
    
        function getChildChainAndStateSender() public view returns (address, address) {
            return (contractMap[CHILD_CHAIN], contractMap[STATE_SENDER]);
        }
    
        function isTokenMapped(address _token) public view returns (bool) {
            return rootToChildToken[_token] != address(0x0);
        }
    
        function isTokenMappedAndIsErc721(address _token) public view returns (bool) {
            require(isTokenMapped(_token), "TOKEN_NOT_MAPPED");
            return isERC721[_token];
        }
    
        function isTokenMappedAndGetPredicate(address _token) public view returns (address) {
            if (isTokenMappedAndIsErc721(_token)) {
                return erc721Predicate;
            }
            return erc20Predicate;
        }
    
        function isChildTokenErc721(address childToken) public view returns (bool) {
            address rootToken = childToRootToken[childToken];
            require(rootToken != address(0x0), "Child token is not mapped");
            return isERC721[rootToken];
        }
    }