Contract 0x2b69d494536098700910d167902d1d397dca2b61

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x1485a90ebcf349891d0606afeeb3636ec0f22513f80087d63d32c3f9059c42790x60806040123090282022-05-17 11:31:34266 days 3 hrs ago0x8f8c780dbc3ef64e86352a1198b58f98c8fa51a6 IN  Create: UnwrapEth0 ETH0.003782549939 ETH
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x5e52fc802967b316a6d740d73b455557f80c4bf4b301f83a26d7ab9de7047f6a588196512023-02-07 14:31:183 mins ago 0x0a3600508589d4c5bb4dbc1198536b0b3983a929 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0xde2ef04d5536eb1884f12369f816ed0f6d6912bd43cd67c82da2609e566ed549588110062023-02-07 13:53:1641 mins ago 0x09fc3be18a3b347f1cbec891dfb8d9438e0b1288 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0xa124ca82c1ab4552be46e647084bc8fa79f5e4d3faa2fc3869e41c74e5a8b7b8588002702023-02-07 13:06:041 hr 29 mins ago 0xaa6e3c3fcfcc5be3a1fc32dd426ab6e0a439bdb9 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x520b5b553aadb0a52a4da421ff8a0dca716173b1edb32b4607aaacd2bc323b60587993542023-02-07 13:02:051 hr 33 mins ago 0xaa6e3c3fcfcc5be3a1fc32dd426ab6e0a439bdb9 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x71515224ac9fcaa033af5027eaedb3d8c5049c566e854561ac09e9d119b638b4587706652023-02-07 10:56:023 hrs 39 mins ago 0xe1fbc3c776cb57609bedf9ece21cfd38f658dcd3 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x79ae84644b9f34f39ca957d7f29cb37ee16d1e0aaa485ac2c7606bceaa3cd7f6587523502023-02-07 9:35:384 hrs 59 mins ago 0xcfbc4fe78c2f8d3f68cec2d26bc6bf6871035a06 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x5321c6887fb7cb26e6bf4b9a2a25d15f593ace0de547347597415de1637011c7587484562023-02-07 9:18:515 hrs 16 mins ago 0xd4b3dcf1d601469e7a2ec9b8607b60507662804d 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x289483775aa5f9efe2d91f146fe2576c8ce48c5d2b680d1ffa380b943f52a3b3587476642023-02-07 9:15:245 hrs 19 mins ago 0xd4b3dcf1d601469e7a2ec9b8607b60507662804d 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x1f6642d4a27a34c38b22d705d940bccbbc5cabafffd1fa87f4c1fb02d9393b49587276922023-02-07 7:47:536 hrs 47 mins ago 0x5cfbbe2def95befb5354f102cec2ca8389902e28 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0xf8f2ebd75a71f0dd88af32b37c6b2403d1cd0f36e33320e5f2fb7531129e8195587041592023-02-07 5:54:298 hrs 40 mins ago 0x14a165a6d9761cd623154dc27858637d47133f29 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x079b611d04567756b2d51b2d1fb582d95bc608178f700a4927b37e28c6a365af586863162023-02-07 4:16:1910 hrs 18 mins ago 0xf129c6e535952c6018617d5dd4b80609d7fc4a95 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x04f6f6135bca0f48ce0e8692bc120c940dbbc5b2dbeb2ff4bc4322025aba5666586853892023-02-07 4:11:1410 hrs 23 mins ago 0x5c2f0bed6021c767599b8a9ae0bdf4bddd2f2c83 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0xab2cbb989a52cd9d3151baaa74500e60fc6f5a63ccdbf06f7e29e3d2cb85f587586686092023-02-07 2:45:0011 hrs 50 mins ago 0x698dfea519c00f8ec5cca892cec7094340754e5e 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0xd4c08d4b49ddb12199d3c2a51ff17df0bf4cf2fed5c70625e165c74532c4f092586344402023-02-06 23:14:3115 hrs 20 mins ago 0x18d026fa54a3a33b938f3dfb160581e4e55cb654 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x14efd4e0514327c2cb0d38c5aeaab871e9a569ec773a4032f4d628db7695995f586229122023-02-06 22:05:5016 hrs 29 mins ago 0x9d35d13054071c1232e3b1665d74fb2c9dd78763 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x2443245c9910c2bbf147558e5afc4e5575d0749fab9487168a7cca7e5f65bbff586192362023-02-06 21:46:0916 hrs 49 mins ago 0x7176fa9ad00caf427fb763f42a5bf670c84318f4 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x3456bd46340846b2f0519e1f73d3dac26442ce4d69bb80732592544ea519c3aa586018752023-02-06 20:15:0418 hrs 20 mins ago 0x3316a97209356effecaaf4cada19a6c6522afe8b 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x5a75149bac70abe41a7683ffdae1f1ed7afb20a851f1566a0c2fbce76d0ad0ec585888412023-02-06 19:07:1219 hrs 27 mins ago 0x706c2932189e9dde737cf9801e42edfb2ec5de5a 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0xaff834e81d9818607e92d79bfc15ac005091c7a8c4523e0781ba7c59ec5105b9585723282023-02-06 17:43:4320 hrs 51 mins ago 0x2c8683fba2607e059d3f419644c6351973108131 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x99d4e8ddd4551fb847a57f0dc6e7a4850f2214e1b29db4438c329a51d7117ef8585635552023-02-06 17:01:5621 hrs 33 mins ago 0x7d5767ea94f8907e3480a3914d8abd21b4ca0695 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x5b965ae4a3ba93d92c588cd8250907c04e1bd697e36ec24d8e87f95e26a5f8ae585416922023-02-06 15:26:1723 hrs 8 mins ago 0x79c097d4d8f22c1d859413f0bd18b8e8916e82f4 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0xe711409f216522b88dc31cc0c19a9dfd18bbefb75f9988c7553ed737e6aeb07e585398212023-02-06 15:18:2123 hrs 16 mins ago 0x4f64bc696b84cd114329f1bb5c718762f39f8ff1 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x3fb667dc4f45788883c09af01013396d9914d071b98297a06e45147428347b96585200562023-02-06 13:50:581 day 44 mins ago 0x64f09fbca198e772de3886cf9659e0ce9427cabf 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x78d13bff95b0e42c66baa598d1ec73c5adb8cfe2660292307940a6ad9b08ca8d585198242023-02-06 13:49:541 day 45 mins ago 0x64f09fbca198e772de3886cf9659e0ce9427cabf 0x2b69d494536098700910d167902d1d397dca2b610 ETH
0x95cdf72c8dfdeeef47f7146f77b5e6d1fa1982f784f928ee2fc60fb46c7d8dab585022252023-02-06 12:29:241 day 2 hrs ago 0xbe92747a8ef488c236963c02936338d25a9095be 0x2b69d494536098700910d167902d1d397dca2b610 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
UnwrapEth

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Arbiscan on 2022-05-17
*/

// SPDX-License-Identifier: MIT

pragma solidity =0.8.10;





interface IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint256 digits);
    function totalSupply() external view returns (uint256 supply);

    function balanceOf(address _owner) external view returns (uint256 balance);

    function transfer(address _to, uint256 _value) external returns (bool success);

    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    ) external returns (bool success);

    function approve(address _spender, uint256 _value) external returns (bool success);

    function allowance(address _owner, address _spender) external view returns (uint256 remaining);

    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}





abstract contract IWETH {
    function allowance(address, address) public virtual view returns (uint256);

    function balanceOf(address) public virtual view returns (uint256);

    function approve(address, uint256) public virtual;

    function transfer(address, uint256) public virtual returns (bool);

    function transferFrom(
        address,
        address,
        uint256
    ) public virtual returns (bool);

    function deposit() public payable virtual;

    function withdraw(uint256) public virtual;
}





library Address {
    //insufficient balance
    error InsufficientBalance(uint256 available, uint256 required);
    //unable to send value, recipient may have reverted
    error SendingValueFail();
    //insufficient balance for call
    error InsufficientBalanceForCall(uint256 available, uint256 required);
    //call to non-contract
    error NonContractCall();
    
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            codehash := extcodehash(account)
        }
        return (codehash != accountHash && codehash != 0x0);
    }

    function sendValue(address payable recipient, uint256 amount) internal {
        uint256 balance = address(this).balance;
        if (balance < amount){
            revert InsufficientBalance(balance, amount);
        }

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{value: amount}("");
        if (!(success)){
            revert SendingValueFail();
        }
    }

    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, errorMessage);
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return
            functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        uint256 balance = address(this).balance;
        if (balance < value){
            revert InsufficientBalanceForCall(balance, value);
        }
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(
        address target,
        bytes memory data,
        uint256 weiValue,
        string memory errorMessage
    ) private returns (bytes memory) {
        if (!(isContract(target))){
            revert NonContractCall();
        }

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{value: weiValue}(data);
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}




library SafeMath {
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}







library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
        );
    }

    /// @dev Edited so it always first approves 0 and then the value, because of non standard tokens
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(token.approve.selector, spender, newAllowance)
        );
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(
            value,
            "SafeERC20: decreased allowance below zero"
        );
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(token.approve.selector, spender, newAllowance)
        );
    }

    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        bytes memory returndata = address(token).functionCall(
            data,
            "SafeERC20: low-level call failed"
        );
        if (returndata.length > 0) {
            // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}






library TokenUtils {
    using SafeERC20 for IERC20;

    address public constant WETH_ADDR = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1;
    address public constant ETH_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    function approveToken(
        address _tokenAddr,
        address _to,
        uint256 _amount
    ) internal {
        if (_tokenAddr == ETH_ADDR) return;

        if (IERC20(_tokenAddr).allowance(address(this), _to) < _amount) {
            IERC20(_tokenAddr).safeApprove(_to, _amount);
        }
    }

    function pullTokensIfNeeded(
        address _token,
        address _from,
        uint256 _amount
    ) internal returns (uint256) {
        // handle max uint amount
        if (_amount == type(uint256).max) {
            _amount = getBalance(_token, _from);
        }

        if (_from != address(0) && _from != address(this) && _token != ETH_ADDR && _amount != 0) {
            IERC20(_token).safeTransferFrom(_from, address(this), _amount);
        }

        return _amount;
    }

    function withdrawTokens(
        address _token,
        address _to,
        uint256 _amount
    ) internal returns (uint256) {
        if (_amount == type(uint256).max) {
            _amount = getBalance(_token, address(this));
        }

        if (_to != address(0) && _to != address(this) && _amount != 0) {
            if (_token != ETH_ADDR) {
                IERC20(_token).safeTransfer(_to, _amount);
            } else {
                (bool success, ) = _to.call{value: _amount}("");
                require(success, "Eth send fail");
            }
        }

        return _amount;
    }

    function depositWeth(uint256 _amount) internal {
        IWETH(WETH_ADDR).deposit{value: _amount}();
    }

    function withdrawWeth(uint256 _amount) internal {
        IWETH(WETH_ADDR).withdraw(_amount);
    }

    function getBalance(address _tokenAddr, address _acc) internal view returns (uint256) {
        if (_tokenAddr == ETH_ADDR) {
            return _acc.balance;
        } else {
            return IERC20(_tokenAddr).balanceOf(_acc);
        }
    }

    function getTokenDecimals(address _token) internal view returns (uint256) {
        if (_token == ETH_ADDR) return 18;

        return IERC20(_token).decimals();
    }
}





abstract contract IDFSRegistry {
 
    function getAddr(bytes4 _id) public view virtual returns (address);

    function addNewContract(
        bytes32 _id,
        address _contractAddr,
        uint256 _waitPeriod
    ) public virtual;

    function startContractChange(bytes32 _id, address _newContractAddr) public virtual;

    function approveContractChange(bytes32 _id) public virtual;

    function cancelContractChange(bytes32 _id) public virtual;

    function changeWaitPeriod(bytes32 _id, uint256 _newWaitPeriod) public virtual;
}





contract ArbitrumAuthAddresses {
    address internal constant ADMIN_VAULT_ADDR = 0xd47D8D97cAd12A866900eEc6Cde1962529F25351;
    address internal constant FACTORY_ADDRESS = 0x5261abC3a94a6475D0A1171daE94A5f84fbaEcD2;
    address internal constant ADMIN_ADDR = 0x6AFEA85cFAB61e3a55Ad2e4537252Ec05796BEfa;
}





contract AuthHelper is ArbitrumAuthAddresses {
}





contract AdminVault is AuthHelper {
    address public owner;
    address public admin;

    error SenderNotAdmin();

    constructor() {
        owner = msg.sender;
        admin = ADMIN_ADDR;
    }

    /// @notice Admin is able to change owner
    /// @param _owner Address of new owner
    function changeOwner(address _owner) public {
        if (admin != msg.sender){
            revert SenderNotAdmin();
        }
        owner = _owner;
    }

    /// @notice Admin is able to set new admin
    /// @param _admin Address of multisig that becomes new admin
    function changeAdmin(address _admin) public {
        if (admin != msg.sender){
            revert SenderNotAdmin();
        }
        admin = _admin;
    }

}








contract AdminAuth is AuthHelper {
    using SafeERC20 for IERC20;

    AdminVault public constant adminVault = AdminVault(ADMIN_VAULT_ADDR);

    error SenderNotOwner();
    error SenderNotAdmin();

    modifier onlyOwner() {
        if (adminVault.owner() != msg.sender){
            revert SenderNotOwner();
        }
        _;
    }

    modifier onlyAdmin() {
        if (adminVault.admin() != msg.sender){
            revert SenderNotAdmin();
        }
        _;
    }

    /// @notice withdraw stuck funds
    function withdrawStuckFunds(address _token, address _receiver, uint256 _amount) public onlyOwner {
        if (_token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {
            payable(_receiver).transfer(_amount);
        } else {
            IERC20(_token).safeTransfer(_receiver, _amount);
        }
    }

    /// @notice Destroy the contract
    function kill() public onlyAdmin {
        selfdestruct(payable(msg.sender));
    }
}





contract DFSRegistry is AdminAuth {
    error EntryAlreadyExistsError(bytes4);
    error EntryNonExistentError(bytes4);
    error EntryNotInChangeError(bytes4);
    error ChangeNotReadyError(uint256,uint256);
    error EmptyPrevAddrError(bytes4);
    error AlreadyInContractChangeError(bytes4);
    error AlreadyInWaitPeriodChangeError(bytes4);

    event AddNewContract(address,bytes4,address,uint256);
    event RevertToPreviousAddress(address,bytes4,address,address);
    event StartContractChange(address,bytes4,address,address);
    event ApproveContractChange(address,bytes4,address,address);
    event CancelContractChange(address,bytes4,address,address);
    event StartWaitPeriodChange(address,bytes4,uint256);
    event ApproveWaitPeriodChange(address,bytes4,uint256,uint256);
    event CancelWaitPeriodChange(address,bytes4,uint256,uint256);

    struct Entry {
        address contractAddr;
        uint256 waitPeriod;
        uint256 changeStartTime;
        bool inContractChange;
        bool inWaitPeriodChange;
        bool exists;
    }

    mapping(bytes4 => Entry) public entries;
    mapping(bytes4 => address) public previousAddresses;

    mapping(bytes4 => address) public pendingAddresses;
    mapping(bytes4 => uint256) public pendingWaitTimes;

    /// @notice Given an contract id returns the registered address
    /// @dev Id is keccak256 of the contract name
    /// @param _id Id of contract
    function getAddr(bytes4 _id) public view returns (address) {
        return entries[_id].contractAddr;
    }

    /// @notice Helper function to easily query if id is registered
    /// @param _id Id of contract
    function isRegistered(bytes4 _id) public view returns (bool) {
        return entries[_id].exists;
    }

    /////////////////////////// OWNER ONLY FUNCTIONS ///////////////////////////

    /// @notice Adds a new contract to the registry
    /// @param _id Id of contract
    /// @param _contractAddr Address of the contract
    /// @param _waitPeriod Amount of time to wait before a contract address can be changed
    function addNewContract(
        bytes4 _id,
        address _contractAddr,
        uint256 _waitPeriod
    ) public onlyOwner {
        if (entries[_id].exists){
            revert EntryAlreadyExistsError(_id);
        }

        entries[_id] = Entry({
            contractAddr: _contractAddr,
            waitPeriod: _waitPeriod,
            changeStartTime: 0,
            inContractChange: false,
            inWaitPeriodChange: false,
            exists: true
        });

        emit AddNewContract(msg.sender, _id, _contractAddr, _waitPeriod);
    }

    /// @notice Reverts to the previous address immediately
    /// @dev In case the new version has a fault, a quick way to fallback to the old contract
    /// @param _id Id of contract
    function revertToPreviousAddress(bytes4 _id) public onlyOwner {
        if (!(entries[_id].exists)){
            revert EntryNonExistentError(_id);
        }
        if (previousAddresses[_id] == address(0)){
            revert EmptyPrevAddrError(_id);
        }

        address currentAddr = entries[_id].contractAddr;
        entries[_id].contractAddr = previousAddresses[_id];

        emit RevertToPreviousAddress(msg.sender, _id, currentAddr, previousAddresses[_id]);
    }

    /// @notice Starts an address change for an existing entry
    /// @dev Can override a change that is currently in progress
    /// @param _id Id of contract
    /// @param _newContractAddr Address of the new contract
    function startContractChange(bytes4 _id, address _newContractAddr) public onlyOwner {
        if (!entries[_id].exists){
            revert EntryNonExistentError(_id);
        }
        if (entries[_id].inWaitPeriodChange){
            revert AlreadyInWaitPeriodChangeError(_id);
        }

        entries[_id].changeStartTime = block.timestamp; // solhint-disable-line
        entries[_id].inContractChange = true;

        pendingAddresses[_id] = _newContractAddr;

        emit StartContractChange(msg.sender, _id, entries[_id].contractAddr, _newContractAddr);
    }

    /// @notice Changes new contract address, correct time must have passed
    /// @param _id Id of contract
    function approveContractChange(bytes4 _id) public onlyOwner {
        if (!entries[_id].exists){
            revert EntryNonExistentError(_id);
        }
        if (!entries[_id].inContractChange){
            revert EntryNotInChangeError(_id);
        }
        if (block.timestamp < (entries[_id].changeStartTime + entries[_id].waitPeriod)){// solhint-disable-line
            revert ChangeNotReadyError(block.timestamp, (entries[_id].changeStartTime + entries[_id].waitPeriod));
        }

        address oldContractAddr = entries[_id].contractAddr;
        entries[_id].contractAddr = pendingAddresses[_id];
        entries[_id].inContractChange = false;
        entries[_id].changeStartTime = 0;

        pendingAddresses[_id] = address(0);
        previousAddresses[_id] = oldContractAddr;

        emit ApproveContractChange(msg.sender, _id, oldContractAddr, entries[_id].contractAddr);
    }

    /// @notice Cancel pending change
    /// @param _id Id of contract
    function cancelContractChange(bytes4 _id) public onlyOwner {
        if (!entries[_id].exists){
            revert EntryNonExistentError(_id);
        }
        if (!entries[_id].inContractChange){
            revert EntryNotInChangeError(_id);
        }

        address oldContractAddr = pendingAddresses[_id];

        pendingAddresses[_id] = address(0);
        entries[_id].inContractChange = false;
        entries[_id].changeStartTime = 0;

        emit CancelContractChange(msg.sender, _id, oldContractAddr, entries[_id].contractAddr);
    }

    /// @notice Starts the change for waitPeriod
    /// @param _id Id of contract
    /// @param _newWaitPeriod New wait time
    function startWaitPeriodChange(bytes4 _id, uint256 _newWaitPeriod) public onlyOwner {
        if (!entries[_id].exists){
            revert EntryNonExistentError(_id);
        }
        if (entries[_id].inContractChange){
            revert AlreadyInContractChangeError(_id);
        }

        pendingWaitTimes[_id] = _newWaitPeriod;

        entries[_id].changeStartTime = block.timestamp; // solhint-disable-line
        entries[_id].inWaitPeriodChange = true;

        emit StartWaitPeriodChange(msg.sender, _id, _newWaitPeriod);
    }

    /// @notice Changes new wait period, correct time must have passed
    /// @param _id Id of contract
    function approveWaitPeriodChange(bytes4 _id) public onlyOwner {
        if (!entries[_id].exists){
            revert EntryNonExistentError(_id);
        }
        if (!entries[_id].inWaitPeriodChange){
            revert EntryNotInChangeError(_id);
        }
        if (block.timestamp < (entries[_id].changeStartTime + entries[_id].waitPeriod)){ // solhint-disable-line
            revert ChangeNotReadyError(block.timestamp, (entries[_id].changeStartTime + entries[_id].waitPeriod));
        }

        uint256 oldWaitTime = entries[_id].waitPeriod;
        entries[_id].waitPeriod = pendingWaitTimes[_id];
        
        entries[_id].inWaitPeriodChange = false;
        entries[_id].changeStartTime = 0;

        pendingWaitTimes[_id] = 0;

        emit ApproveWaitPeriodChange(msg.sender, _id, oldWaitTime, entries[_id].waitPeriod);
    }

    /// @notice Cancel wait period change
    /// @param _id Id of contract
    function cancelWaitPeriodChange(bytes4 _id) public onlyOwner {
        if (!entries[_id].exists){
            revert EntryNonExistentError(_id);
        }
        if (!entries[_id].inWaitPeriodChange){
            revert EntryNotInChangeError(_id);
        }

        uint256 oldWaitPeriod = pendingWaitTimes[_id];

        pendingWaitTimes[_id] = 0;
        entries[_id].inWaitPeriodChange = false;
        entries[_id].changeStartTime = 0;

        emit CancelWaitPeriodChange(msg.sender, _id, oldWaitPeriod, entries[_id].waitPeriod);
    }
}





abstract contract DSAuthority {
    function canCall(
        address src,
        address dst,
        bytes4 sig
    ) public view virtual returns (bool);
}





contract DSAuthEvents {
    event LogSetAuthority(address indexed authority);
    event LogSetOwner(address indexed owner);
}

contract DSAuth is DSAuthEvents {
    DSAuthority public authority;
    address public owner;

    constructor() {
        owner = msg.sender;
        emit LogSetOwner(msg.sender);
    }

    function setOwner(address owner_) public auth {
        owner = owner_;
        emit LogSetOwner(owner);
    }

    function setAuthority(DSAuthority authority_) public auth {
        authority = authority_;
        emit LogSetAuthority(address(authority));
    }

    modifier auth {
        require(isAuthorized(msg.sender, msg.sig), "Not authorized");
        _;
    }

    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 == DSAuthority(address(0))) {
            return false;
        } else {
            return authority.canCall(src, address(this), sig);
        }
    }
}





contract DSNote {
    event LogNote(
        bytes4 indexed sig,
        address indexed guy,
        bytes32 indexed foo,
        bytes32 indexed bar,
        uint256 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);

        _;
    }
}






abstract contract DSProxy is DSAuth, DSNote {
    DSProxyCache public cache; // global cache for contracts

    constructor(address _cacheAddr) {
        if (!(setCache(_cacheAddr))){
            require(isAuthorized(msg.sender, msg.sig), "Not authorized");
        }
    }

    // solhint-disable-next-line no-empty-blocks
    receive() external payable {}

    // use the proxy to execute calldata _data on contract _code
    function execute(bytes memory _code, bytes memory _data)
        public
        payable
        virtual
        returns (address target, bytes32 response);

    function execute(address _target, bytes memory _data)
        public
        payable
        virtual
        returns (bytes32 response);

    //set new cache
    function setCache(address _cacheAddr) public payable virtual returns (bool);
}

contract DSProxyCache {
    mapping(bytes32 => address) cache;

    function read(bytes memory _code) public view returns (address) {
        bytes32 hash = keccak256(_code);
        return cache[hash];
    }

    function write(bytes memory _code) public returns (address target) {
        assembly {
            target := create(0, add(_code, 0x20), mload(_code))
            switch iszero(extcodesize(target))
                case 1 {
                    // throw if contract failed to deploy
                    revert(0, 0)
                }
        }
        bytes32 hash = keccak256(_code);
        cache[hash] = target;
    }
}





contract DefisaverLogger {
    event RecipeEvent(
        address indexed caller,
        string indexed logName
    );

    event ActionDirectEvent(
        address indexed caller,
        string indexed logName,
        bytes data
    );

    function logRecipeEvent(
        string memory _logName
    ) public {
        emit RecipeEvent(msg.sender, _logName);
    }

    function logActionDirectEvent(
        string memory _logName,
        bytes memory _data
    ) public {
        emit ActionDirectEvent(msg.sender, _logName, _data);
    }
}





contract ArbitrumActionsUtilAddresses {
    // TODO: set this
    address internal constant DFS_REG_CONTROLLER_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    // TODO: set this
    address internal constant SUB_STORAGE_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    address internal constant REGISTRY_ADDR = 0xBF1CaC12DB60819Bfa71A328282ecbc1D40443aA;
    address internal constant DFS_LOGGER_ADDR = 0xE6f9A5C850dbcD12bc64f40d692F537250aDEC38;
}





contract ActionsUtilHelper is ArbitrumActionsUtilAddresses {
}








abstract contract ActionBase is AdminAuth, ActionsUtilHelper {
    event ActionEvent(
        string indexed logName,
        bytes data
    );

    DFSRegistry public constant registry = DFSRegistry(REGISTRY_ADDR);

    DefisaverLogger public constant logger = DefisaverLogger(
        DFS_LOGGER_ADDR
    );

    //Wrong sub index value
    error SubIndexValueError();
    //Wrong return index value
    error ReturnIndexValueError();

    /// @dev Subscription params index range [128, 255]
    uint8 public constant SUB_MIN_INDEX_VALUE = 128;
    uint8 public constant SUB_MAX_INDEX_VALUE = 255;

    /// @dev Return params index range [1, 127]
    uint8 public constant RETURN_MIN_INDEX_VALUE = 1;
    uint8 public constant RETURN_MAX_INDEX_VALUE = 127;

    /// @dev If the input value should not be replaced
    uint8 public constant NO_PARAM_MAPPING = 0;

    /// @dev We need to parse Flash loan actions in a different way
    enum ActionType { FL_ACTION, STANDARD_ACTION, FEE_ACTION, CHECK_ACTION, CUSTOM_ACTION }

    /// @notice Parses inputs and runs the implemented action through a proxy
    /// @dev Is called by the RecipeExecutor chaining actions together
    /// @param _callData Array of input values each value encoded as bytes
    /// @param _subData Array of subscribed vales, replaces input values if specified
    /// @param _paramMapping Array that specifies how return and subscribed values are mapped in input
    /// @param _returnValues Returns values from actions before, which can be injected in inputs
    /// @return Returns a bytes32 value through DSProxy, each actions implements what that value is
    function executeAction(
        bytes memory _callData,
        bytes32[] memory _subData,
        uint8[] memory _paramMapping,
        bytes32[] memory _returnValues
    ) public payable virtual returns (bytes32);

    /// @notice Parses inputs and runs the single implemented action through a proxy
    /// @dev Used to save gas when executing a single action directly
    function executeActionDirect(bytes memory _callData) public virtual payable;

    /// @notice Returns the type of action we are implementing
    function actionType() public pure virtual returns (uint8);


    //////////////////////////// HELPER METHODS ////////////////////////////

    /// @notice Given an uint256 input, injects return/sub values if specified
    /// @param _param The original input value
    /// @param _mapType Indicated the type of the input in paramMapping
    /// @param _subData Array of subscription data we can replace the input value with
    /// @param _returnValues Array of subscription data we can replace the input value with
    function _parseParamUint(
        uint _param,
        uint8 _mapType,
        bytes32[] memory _subData,
        bytes32[] memory _returnValues
    ) internal pure returns (uint) {
        if (isReplaceable(_mapType)) {
            if (isReturnInjection(_mapType)) {
                _param = uint(_returnValues[getReturnIndex(_mapType)]);
            } else {
                _param = uint256(_subData[getSubIndex(_mapType)]);
            }
        }

        return _param;
    }


    /// @notice Given an addr input, injects return/sub values if specified
    /// @param _param The original input value
    /// @param _mapType Indicated the type of the input in paramMapping
    /// @param _subData Array of subscription data we can replace the input value with
    /// @param _returnValues Array of subscription data we can replace the input value with
    function _parseParamAddr(
        address _param,
        uint8 _mapType,
        bytes32[] memory _subData,
        bytes32[] memory _returnValues
    ) internal view returns (address) {
        if (isReplaceable(_mapType)) {
            if (isReturnInjection(_mapType)) {
                _param = address(bytes20((_returnValues[getReturnIndex(_mapType)])));
            } else {
                /// @dev The last two values are specially reserved for proxy addr and owner addr
                if (_mapType == 254) return address(this); //DSProxy address
                if (_mapType == 255) return DSProxy(payable(address(this))).owner(); // owner of DSProxy

                _param = address(uint160(uint256(_subData[getSubIndex(_mapType)])));
            }
        }

        return _param;
    }

    /// @notice Given an bytes32 input, injects return/sub values if specified
    /// @param _param The original input value
    /// @param _mapType Indicated the type of the input in paramMapping
    /// @param _subData Array of subscription data we can replace the input value with
    /// @param _returnValues Array of subscription data we can replace the input value with
    function _parseParamABytes32(
        bytes32 _param,
        uint8 _mapType,
        bytes32[] memory _subData,
        bytes32[] memory _returnValues
    ) internal pure returns (bytes32) {
        if (isReplaceable(_mapType)) {
            if (isReturnInjection(_mapType)) {
                _param = (_returnValues[getReturnIndex(_mapType)]);
            } else {
                _param = _subData[getSubIndex(_mapType)];
            }
        }

        return _param;
    }

    /// @notice Checks if the paramMapping value indicated that we need to inject values
    /// @param _type Indicated the type of the input
    function isReplaceable(uint8 _type) internal pure returns (bool) {
        return _type != NO_PARAM_MAPPING;
    }

    /// @notice Checks if the paramMapping value is in the return value range
    /// @param _type Indicated the type of the input
    function isReturnInjection(uint8 _type) internal pure returns (bool) {
        return (_type >= RETURN_MIN_INDEX_VALUE) && (_type <= RETURN_MAX_INDEX_VALUE);
    }

    /// @notice Transforms the paramMapping value to the index in return array value
    /// @param _type Indicated the type of the input
    function getReturnIndex(uint8 _type) internal pure returns (uint8) {
        if (!(isReturnInjection(_type))){
            revert SubIndexValueError();
        }

        return (_type - RETURN_MIN_INDEX_VALUE);
    }

    /// @notice Transforms the paramMapping value to the index in sub array value
    /// @param _type Indicated the type of the input
    function getSubIndex(uint8 _type) internal pure returns (uint8) {
        if (_type < SUB_MIN_INDEX_VALUE){
            revert ReturnIndexValueError();
        }
        return (_type - SUB_MIN_INDEX_VALUE);
    }
}






contract UnwrapEth is ActionBase {
    using TokenUtils for address;

    struct Params {
        uint256 amount;
        address to;
    }

    /// @inheritdoc ActionBase
    function executeAction(
        bytes memory _callData,
        bytes32[] memory _subData,
        uint8[] memory _paramMapping,
        bytes32[] memory _returnValues
    ) public payable virtual override returns (bytes32) {
        Params memory inputData = parseInputs(_callData);

        inputData.amount = _parseParamUint(inputData.amount, _paramMapping[0], _subData, _returnValues);
        inputData.to = _parseParamAddr(inputData.to, _paramMapping[1], _subData, _returnValues);

        return bytes32(_unwrapEth(inputData.amount, inputData.to));
    }

    // solhint-disable-next-line no-empty-blocks
    function executeActionDirect(bytes memory _callData) public payable override {
        Params memory inputData = parseInputs(_callData);

        _unwrapEth(inputData.amount, inputData.to);
    }

    /// @inheritdoc ActionBase
    function actionType() public pure virtual override returns (uint8) {
        return uint8(ActionType.STANDARD_ACTION);
    }

    //////////////////////////// ACTION LOGIC ////////////////////////////

    /// @notice Unwraps WETH9 -> Eth
    /// @param _amount Amount of Weth to unwrap
    /// @param _to Address where to send the unwrapped Eth
    function _unwrapEth(uint256 _amount, address _to) internal returns (uint256) {
        if (_amount == type(uint256).max) {
            _amount = TokenUtils.WETH_ADDR.getBalance(address(this));
        }

        TokenUtils.withdrawWeth(_amount);

        // if _to == proxy, it will stay on proxy
        TokenUtils.ETH_ADDR.withdrawTokens(_to, _amount);

        return _amount;
    }

    function parseInputs(bytes memory _callData) public pure returns (Params memory params) {
        params = abi.decode(_callData, (Params));
    }
}

Contract ABI

[{"inputs":[],"name":"NonContractCall","type":"error"},{"inputs":[],"name":"ReturnIndexValueError","type":"error"},{"inputs":[],"name":"SenderNotAdmin","type":"error"},{"inputs":[],"name":"SenderNotOwner","type":"error"},{"inputs":[],"name":"SubIndexValueError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"logName","type":"string"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"ActionEvent","type":"event"},{"inputs":[],"name":"NO_PARAM_MAPPING","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RETURN_MAX_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RETURN_MIN_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUB_MAX_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUB_MIN_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"actionType","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"adminVault","outputs":[{"internalType":"contract AdminVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"},{"internalType":"bytes32[]","name":"_subData","type":"bytes32[]"},{"internalType":"uint8[]","name":"_paramMapping","type":"uint8[]"},{"internalType":"bytes32[]","name":"_returnValues","type":"bytes32[]"}],"name":"executeAction","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"}],"name":"executeActionDirect","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"kill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"logger","outputs":[{"internalType":"contract DefisaverLogger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"}],"name":"parseInputs","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"internalType":"struct UnwrapEth.Params","name":"params","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract DFSRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawStuckFunds","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b5061107e806100206000396000f3fe6080604052600436106100dd5760003560e01c80638cedca711161007f5780639864dcdd116100595780639864dcdd14610243578063c579d49014610258578063d3c2e7ed14610278578063f24ccbfe1461028d57600080fd5b80638cedca71146101b65780638df50f74146101de5780639093410d146101ff57600080fd5b8063389f87ff116100bb578063389f87ff1461013757806341c0e1b51461014c5780637b103999146101615780638bcb6216146101a157600080fd5b80630f2eee42146100e2578063247492f81461010e5780632fa13cb814610122575b600080fd5b3480156100ee57600080fd5b506100f7608081565b60405160ff90911681526020015b60405180910390f35b34801561011a57600080fd5b5060016100f7565b34801561012e57600080fd5b506100f7600081565b61014a610145366004610ca4565b6102b5565b005b34801561015857600080fd5b5061014a6102d9565b34801561016d57600080fd5b5061018973bf1cac12db60819bfa71a328282ecbc1d40443aa81565b6040516001600160a01b039091168152602001610105565b3480156101ad57600080fd5b506100f7600181565b3480156101c257600080fd5b5061018973d47d8d97cad12a866900eec6cde1962529f2535181565b6101f16101ec366004610d68565b610383565b604051908152602001610105565b34801561020b57600080fd5b5061021f61021a366004610ca4565b610412565b60408051825181526020928301516001600160a01b03169281019290925201610105565b34801561024f57600080fd5b506100f7607f81565b34801561026457600080fd5b5061014a610273366004610e90565b610440565b34801561028457600080fd5b506100f760ff81565b34801561029957600080fd5b5061018973e6f9a5c850dbcd12bc64f40d692f537250adec3881565b60006102c082610412565b90506102d48160000151826020015161055c565b505050565b336001600160a01b031673d47d8d97cad12a866900eec6cde1962529f253516001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610335573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103599190610ed1565b6001600160a01b0316146103805760405163a6c827a960e01b815260040160405180910390fd5b33ff5b60008061038f86610412565b90506103bb8160000151856000815181106103ac576103ac610ef5565b602002602001015187866105b9565b8152602081015184516103eb9190869060019081106103dc576103dc610ef5565b60200260200101518786610635565b6001600160a01b03166020820181905281516104069161055c565b9150505b949350505050565b60408051808201909152600080825260208201528180602001905181019061043a9190610f0b565b92915050565b336001600160a01b031673d47d8d97cad12a866900eec6cde1962529f253516001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561049c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c09190610ed1565b6001600160a01b0316146104e757604051630ca4a64560e11b815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0384161415610548576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015610542573d6000803e3d6000fd5b50505050565b6102d46001600160a01b0384168383610705565b6000600019831415610589576105867382af49447d8a07e3bd95bd0d56f35241523fbab130610757565b92505b61059283610800565b6105b173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8385610868565b509192915050565b600060ff84161561062c576105cd84610990565b1561060157816105dc856109af565b60ff16815181106105ef576105ef610ef5565b602002602001015160001c945061062c565b8261060b856109e2565b60ff168151811061061e5761061e610ef5565b602002602001015160001c94505b50929392505050565b600060ff84161561062c5761064984610990565b1561067d5781610658856109af565b60ff168151811061066b5761066b610ef5565b602002602001015160601c945061062c565b8360ff1660fe141561069057503061040a565b8360ff1660ff141561060157306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fe9190610ed1565b905061040a565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526102d4908490610a14565b60006001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561078f57506001600160a01b0381163161043a565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa1580156107d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f99190610f61565b905061043a565b604051632e1a7d4d60e01b8152600481018290527382af49447d8a07e3bd95bd0d56f35241523fbab190632e1a7d4d90602401600060405180830381600087803b15801561084d57600080fd5b505af1158015610861573d6000803e3d6000fd5b5050505050565b60006000198214156108815761087e8430610757565b91505b6001600160a01b038316158015906108a257506001600160a01b0383163014155b80156108ad57508115155b15610989576001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146108ef576108ea6001600160a01b0385168484610705565b610989565b6000836001600160a01b03168360405160006040518083038185875af1925050503d806000811461093c576040519150601f19603f3d011682016040523d82523d6000602084013e610941565b606091505b50509050806109875760405162461bcd60e51b815260206004820152600d60248201526c115d1a081cd95b990819985a5b609a1b60448201526064015b60405180910390fd5b505b5092915050565b6000600160ff83161080159061043a5750607f60ff8316111592915050565b60006109ba82610990565b6109d75760405163dcc95a3960e01b815260040160405180910390fd5b61043a600183610f7a565b6000608060ff83161015610a095760405163866f6e8760e01b815260040160405180910390fd5b61043a608083610f7a565b6000610a69826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ae69092919063ffffffff16565b8051909150156102d45780806020019051810190610a879190610fab565b6102d45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161097e565b606061040a84846000856060610afb85610bb4565b610b185760405163304619b560e01b815260040160405180910390fd5b600080866001600160a01b03168587604051610b349190610ff9565b60006040518083038185875af1925050503d8060008114610b71576040519150601f19603f3d011682016040523d82523d6000602084013e610b76565b606091505b50915091508115610b8a57915061040a9050565b805115610b9a5780518082602001fd5b8360405162461bcd60e51b815260040161097e9190611015565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061040a575050151592915050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610c2c57610c2c610bed565b604052919050565b600082601f830112610c4557600080fd5b813567ffffffffffffffff811115610c5f57610c5f610bed565b610c72601f8201601f1916602001610c03565b818152846020838601011115610c8757600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215610cb657600080fd5b813567ffffffffffffffff811115610ccd57600080fd5b61040a84828501610c34565b600067ffffffffffffffff821115610cf357610cf3610bed565b5060051b60200190565b600082601f830112610d0e57600080fd5b81356020610d23610d1e83610cd9565b610c03565b82815260059290921b84018101918181019086841115610d4257600080fd5b8286015b84811015610d5d5780358352918301918301610d46565b509695505050505050565b60008060008060808587031215610d7e57600080fd5b843567ffffffffffffffff80821115610d9657600080fd5b610da288838901610c34565b9550602091508187013581811115610db957600080fd5b610dc589828a01610cfd565b955050604087013581811115610dda57600080fd5b8701601f81018913610deb57600080fd5b8035610df9610d1e82610cd9565b81815260059190911b8201840190848101908b831115610e1857600080fd5b928501925b82841015610e4657833560ff81168114610e375760008081fd5b82529285019290850190610e1d565b96505050506060870135915080821115610e5f57600080fd5b50610e6c87828801610cfd565b91505092959194509250565b6001600160a01b0381168114610e8d57600080fd5b50565b600080600060608486031215610ea557600080fd5b8335610eb081610e78565b92506020840135610ec081610e78565b929592945050506040919091013590565b600060208284031215610ee357600080fd5b8151610eee81610e78565b9392505050565b634e487b7160e01b600052603260045260246000fd5b600060408284031215610f1d57600080fd5b6040516040810181811067ffffffffffffffff82111715610f4057610f40610bed565b604052825181526020830151610f5581610e78565b60208201529392505050565b600060208284031215610f7357600080fd5b5051919050565b600060ff821660ff841680821015610fa257634e487b7160e01b600052601160045260246000fd5b90039392505050565b600060208284031215610fbd57600080fd5b81518015158114610eee57600080fd5b60005b83811015610fe8578181015183820152602001610fd0565b838111156105425750506000910152565b6000825161100b818460208701610fcd565b9190910192915050565b6020815260008251806020840152611034816040850160208701610fcd565b601f01601f1916919091016040019291505056fea26469706673582212202866479a4b526d07ba9f17a9780f707f581975c5e54a42707c967125473ad0e764736f6c634300080a0033

Deployed ByteCode Sourcemap

33838:1968:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27702:47;;;;;;;;;;;;27746:3;27702:47;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;27702:47:0;;;;;;;;34893:126;;;;;;;;;;-1:-1:-1;34984:26:0;34893:126;;28031:42;;;;;;;;;;;;28072:1;28031:42;;34654:199;;;;;;:::i;:::-;;:::i;:::-;;14386:85;;;;;;;;;;;;;:::i;27341:65::-;;;;;;;;;;;;26954:42;27341:65;;;;;-1:-1:-1;;;;;1659:32:1;;;1641:51;;1629:2;1614:18;27341:65:0;1475:223:1;27861:48:0;;;;;;;;;;;;27908:1;27861:48;;13557:68;;;;;;;;;;;;12408:42;13557:68;;34023:573;;;;;;:::i;:::-;;:::i;:::-;;;4666:25:1;;;4654:2;4639:18;34023:573:0;4520:177:1;35656:147:0;;;;;;;;;;-1:-1:-1;35656:147:0;;;;;:::i;:::-;;:::i;:::-;;;;4914:13:1;;4896:32;;4988:4;4976:17;;;4970:24;-1:-1:-1;;;;;4966:50:1;4944:20;;;4937:80;;;;4869:18;35656:147:0;4702:321:1;27916:50:0;;;;;;;;;;;;27963:3;27916:50;;14024:316;;;;;;;;;;-1:-1:-1;14024:316:0;;;;;:::i;:::-;;:::i;27756:47::-;;;;;;;;;;;;27800:3;27756:47;;27415:89;;;;;;;;;;;;27047:42;27415:89;;34654:199;34742:23;34768:22;34780:9;34768:11;:22::i;:::-;34742:48;;34803:42;34814:9;:16;;;34832:9;:12;;;34803:10;:42::i;:::-;;34731:122;34654:199;:::o;14386:85::-;13898:10;-1:-1:-1;;;;;13876:32:0;12408:42;-1:-1:-1;;;;;13876:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;13876:32:0;;13872:87;;13931:16;;-1:-1:-1;;;13931:16:0;;;;;;;;;;;13872:87;14451:10:::1;14430:33;34023:573:::0;34243:7;34263:23;34289:22;34301:9;34289:11;:22::i;:::-;34263:48;;34343:76;34359:9;:16;;;34377:13;34391:1;34377:16;;;;;;;;:::i;:::-;;;;;;;34395:8;34405:13;34343:15;:76::i;:::-;34324:95;;34461:12;;;;34475:16;;34445:72;;34461:12;34475:13;;34489:1;;34475:16;;;;;;:::i;:::-;;;;;;;34493:8;34503:13;34445:15;:72::i;:::-;-1:-1:-1;;;;;34430:87:0;:12;;;:87;;;34556:16;;34545:42;;:10;:42::i;:::-;34537:51;-1:-1:-1;;34023:573:0;;;;;;;:::o;35656:147::-;-1:-1:-1;;;;;;;;;;;;;;;;;35775:9:0;35764:31;;;;;;;;;;;;:::i;:::-;35755:40;35656:147;-1:-1:-1;;35656:147:0:o;14024:316::-;13752:10;-1:-1:-1;;;;;13730:32:0;12408:42;-1:-1:-1;;;;;13730:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;13730:32:0;;13726:87;;13785:16;;-1:-1:-1;;;13785:16:0;;;;;;;;;;;13726:87;14146:42:::1;-1:-1:-1::0;;;;;14136:52:0;::::1;;14132:201;;;14205:36;::::0;-1:-1:-1;;;;;14205:27:0;::::1;::::0;:36;::::1;;;::::0;14233:7;;14205:36:::1;::::0;;;14233:7;14205:27;:36;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;34803:42:::0;34731:122;34654:199;:::o;14132:201::-:1;14274:47;-1:-1:-1::0;;;;;14274:27:0;::::1;14302:9:::0;14313:7;14274:27:::1;:47::i;35252:396::-:0;35320:7;-1:-1:-1;;35344:7:0;:28;35340:117;;;35399:46;9485:42;35439:4;35399:31;:46::i;:::-;35389:56;;35340:117;35469:32;35493:7;35469:23;:32::i;:::-;35565:48;9569:42;35600:3;35605:7;35565:34;:48::i;:::-;-1:-1:-1;35633:7:0;;35252:396;-1:-1:-1;;35252:396:0:o;29926:496::-;30105:4;32748:25;;;;30122:267;;30170:27;30188:8;30170:17;:27::i;:::-;30166:212;;;30232:13;30246:24;30261:8;30246:14;:24::i;:::-;30232:39;;;;;;;;;;:::i;:::-;;;;;;;30227:45;;30218:54;;30166:212;;;30330:8;30339:21;30351:8;30339:11;:21::i;:::-;30330:31;;;;;;;;;;:::i;:::-;;;;;;;30322:40;;30313:49;;30166:212;-1:-1:-1;30408:6:0;;29926:496;-1:-1:-1;;;29926:496:0:o;30811:819::-;30993:7;32748:25;;;;31013:584;;31061:27;31079:8;31061:17;:27::i;:::-;31057:529;;;31135:13;31149:24;31164:8;31149:14;:24::i;:::-;31135:39;;;;;;;;;;:::i;:::-;;;;;;;31118:59;;31109:68;;31057:529;;;31321:8;:15;;31333:3;31321:15;31317:41;;;-1:-1:-1;31353:4:0;31338:20;;31317:41;31399:8;:15;;31411:3;31399:15;31395:67;;;31447:4;-1:-1:-1;;;;;31423:37:0;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31416:46;;;;7153:211;7297:58;;;-1:-1:-1;;;;;7141:32:1;;7297:58:0;;;7123:51:1;7190:18;;;;7183:34;;;7297:58:0;;;;;;;;;;7096:18:1;;;;7297:58:0;;;;;;;;-1:-1:-1;;;;;7297:58:0;-1:-1:-1;;;7297:58:0;;;7270:86;;7290:5;;7270:19;:86::i;11308:252::-;11385:7;-1:-1:-1;;;;;11409:22:0;;9569:42;11409:22;11405:148;;;-1:-1:-1;;;;;;11455:12:0;;;11448:19;;11405:148;11507:34;;-1:-1:-1;;;11507:34:0;;-1:-1:-1;;;;;1659:32:1;;;11507:34:0;;;1641:51:1;11507:28:0;;;;;1614:18:1;;11507:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11500:41;;;;11199:101;11258:34;;-1:-1:-1;;;11258:34:0;;;;;4666:25:1;;;9485:42:0;;11258:25;;4639:18:1;;11258:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11199:101;:::o;10454:621::-;10576:7;-1:-1:-1;;10600:7:0;:28;10596:104;;;10655:33;10666:6;10682:4;10655:10;:33::i;:::-;10645:43;;10596:104;-1:-1:-1;;;;;10716:17:0;;;;;;:41;;-1:-1:-1;;;;;;10737:20:0;;10752:4;10737:20;;10716:41;:57;;;;-1:-1:-1;10761:12:0;;;10716:57;10712:329;;;-1:-1:-1;;;;;10794:18:0;;9569:42;10794:18;10790:240;;10833:41;-1:-1:-1;;;;;10833:27:0;;10861:3;10866:7;10833:27;:41::i;:::-;10790:240;;;10916:12;10934:3;-1:-1:-1;;;;;10934:8:0;10950:7;10934:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10915:47;;;10989:7;10981:33;;;;-1:-1:-1;;;10981:33:0;;8219:2:1;10981:33:0;;;8201:21:1;8258:2;8238:18;;;8231:30;-1:-1:-1;;;8277:18:1;;;8270:43;8330:18;;10981:33:0;;;;;;;;;10896:134;10790:240;-1:-1:-1;11060:7:0;10454:621;-1:-1:-1;;10454:621:0:o;32922:165::-;32985:4;27908:1;33010:31;;;;;;;33009:70;;-1:-1:-1;27963:3:0;33047:31;;;;;33002:77;32922:165;-1:-1:-1;;32922:165:0:o;33235:223::-;33295:5;33319:24;33337:5;33319:17;:24::i;:::-;33313:86;;33367:20;;-1:-1:-1;;;33367:20:0;;;;;;;;;;;33313:86;33419:30;27908:1;33419:5;:30;:::i;33603:218::-;33660:5;27746:3;33682:27;;;;33678:89;;;33732:23;;-1:-1:-1;;;33732:23:0;;;;;;;;;;;33678:89;33785:27;27746:3;33785:5;:27;:::i;8903:468::-;8984:23;9010:106;9052:4;9010:106;;;;;;;;;;;;;;;;;9018:5;-1:-1:-1;;;;;9010:27:0;;;:106;;;;;:::i;:::-;9131:17;;8984:132;;-1:-1:-1;9131:21:0;9127:237;;9286:10;9275:30;;;;;;;;;;;;:::i;:::-;9267:85;;;;-1:-1:-1;;;9267:85:0;;9140:2:1;9267:85:0;;;9122:21:1;9179:2;9159:18;;;9152:30;9218:34;9198:18;;;9191:62;-1:-1:-1;;;9269:18:1;;;9262:40;9319:19;;9267:85:0;8938:406:1;3175:230:0;3312:12;3344:53;3367:6;3375:4;3381:1;3384:12;4298;4329:18;4340:6;4329:10;:18::i;:::-;4323:77;;4371:17;;-1:-1:-1;;;4371:17:0;;;;;;;;;;;4323:77;4473:12;4487:23;4514:6;-1:-1:-1;;;;;4514:11:0;4533:8;4543:4;4514:34;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4472:76;;;;4563:7;4559:595;;;4594:10;-1:-1:-1;4587:17:0;;-1:-1:-1;4587:17:0;4559:595;4708:17;;:21;4704:439;;4971:10;4965:17;5032:15;5019:10;5015:2;5011:19;5004:44;4704:439;5114:12;5107:20;;-1:-1:-1;;;5107:20:0;;;;;;;;:::i;1885:641::-;1945:4;2426:20;;2256:66;2475:23;;;;;;:42;;-1:-1:-1;;2502:15:0;;;2467:51;-1:-1:-1;;1885:641:0:o;203:127:1:-;264:10;259:3;255:20;252:1;245:31;295:4;292:1;285:15;319:4;316:1;309:15;335:275;406:2;400:9;471:2;452:13;;-1:-1:-1;;448:27:1;436:40;;506:18;491:34;;527:22;;;488:62;485:88;;;553:18;;:::i;:::-;589:2;582:22;335:275;;-1:-1:-1;335:275:1:o;615:530::-;657:5;710:3;703:4;695:6;691:17;687:27;677:55;;728:1;725;718:12;677:55;764:6;751:20;790:18;786:2;783:26;780:52;;;812:18;;:::i;:::-;856:55;899:2;880:13;;-1:-1:-1;;876:27:1;905:4;872:38;856:55;:::i;:::-;936:2;927:7;920:19;982:3;975:4;970:2;962:6;958:15;954:26;951:35;948:55;;;999:1;996;989:12;948:55;1064:2;1057:4;1049:6;1045:17;1038:4;1029:7;1025:18;1012:55;1112:1;1087:16;;;1105:4;1083:27;1076:38;;;;1091:7;615:530;-1:-1:-1;;;615:530:1:o;1150:320::-;1218:6;1271:2;1259:9;1250:7;1246:23;1242:32;1239:52;;;1287:1;1284;1277:12;1239:52;1327:9;1314:23;1360:18;1352:6;1349:30;1346:50;;;1392:1;1389;1382:12;1346:50;1415:49;1456:7;1447:6;1436:9;1432:22;1415:49;:::i;1930:183::-;1990:4;2023:18;2015:6;2012:30;2009:56;;;2045:18;;:::i;:::-;-1:-1:-1;2090:1:1;2086:14;2102:4;2082:25;;1930:183::o;2118:662::-;2172:5;2225:3;2218:4;2210:6;2206:17;2202:27;2192:55;;2243:1;2240;2233:12;2192:55;2279:6;2266:20;2305:4;2329:60;2345:43;2385:2;2345:43;:::i;:::-;2329:60;:::i;:::-;2423:15;;;2509:1;2505:10;;;;2493:23;;2489:32;;;2454:12;;;;2533:15;;;2530:35;;;2561:1;2558;2551:12;2530:35;2597:2;2589:6;2585:15;2609:142;2625:6;2620:3;2617:15;2609:142;;;2691:17;;2679:30;;2729:12;;;;2642;;2609:142;;;-1:-1:-1;2769:5:1;2118:662;-1:-1:-1;;;;;;2118:662:1:o;2785:1730::-;2953:6;2961;2969;2977;3030:3;3018:9;3009:7;3005:23;3001:33;2998:53;;;3047:1;3044;3037:12;2998:53;3087:9;3074:23;3116:18;3157:2;3149:6;3146:14;3143:34;;;3173:1;3170;3163:12;3143:34;3196:49;3237:7;3228:6;3217:9;3213:22;3196:49;:::i;:::-;3186:59;;3264:2;3254:12;;3319:2;3308:9;3304:18;3291:32;3348:2;3338:8;3335:16;3332:36;;;3364:1;3361;3354:12;3332:36;3387:63;3442:7;3431:8;3420:9;3416:24;3387:63;:::i;:::-;3377:73;;;3503:2;3492:9;3488:18;3475:32;3532:2;3522:8;3519:16;3516:36;;;3548:1;3545;3538:12;3516:36;3571:24;;3626:4;3618:13;;3614:27;-1:-1:-1;3604:55:1;;3655:1;3652;3645:12;3604:55;3691:2;3678:16;3714:60;3730:43;3770:2;3730:43;:::i;3714:60::-;3808:15;;;3890:1;3886:10;;;;3878:19;;3874:28;;;3839:12;;;;3914:19;;;3911:39;;;3946:1;3943;3936:12;3911:39;3970:11;;;;3990:311;4006:6;4001:3;3998:15;3990:311;;;4086:3;4073:17;4134:4;4127:5;4123:16;4116:5;4113:27;4103:125;;4182:1;4211:2;4207;4200:14;4103:125;4241:18;;4023:12;;;;4279;;;;3990:311;;;4320:5;-1:-1:-1;;;;4378:2:1;4363:18;;4350:32;;-1:-1:-1;4394:16:1;;;4391:36;;;4423:1;4420;4413:12;4391:36;;4446:63;4501:7;4490:8;4479:9;4475:24;4446:63;:::i;:::-;4436:73;;;2785:1730;;;;;;;:::o;5028:131::-;-1:-1:-1;;;;;5103:31:1;;5093:42;;5083:70;;5149:1;5146;5139:12;5083:70;5028:131;:::o;5164:456::-;5241:6;5249;5257;5310:2;5298:9;5289:7;5285:23;5281:32;5278:52;;;5326:1;5323;5316:12;5278:52;5365:9;5352:23;5384:31;5409:5;5384:31;:::i;:::-;5434:5;-1:-1:-1;5491:2:1;5476:18;;5463:32;5504:33;5463:32;5504:33;:::i;:::-;5164:456;;5556:7;;-1:-1:-1;;;5610:2:1;5595:18;;;;5582:32;;5164:456::o;5989:251::-;6059:6;6112:2;6100:9;6091:7;6087:23;6083:32;6080:52;;;6128:1;6125;6118:12;6080:52;6160:9;6154:16;6179:31;6204:5;6179:31;:::i;:::-;6229:5;5989:251;-1:-1:-1;;;5989:251:1:o;6245:127::-;6306:10;6301:3;6297:20;6294:1;6287:31;6337:4;6334:1;6327:15;6361:4;6358:1;6351:15;6377:567;6471:6;6524:2;6512:9;6503:7;6499:23;6495:32;6492:52;;;6540:1;6537;6530:12;6492:52;6573:2;6567:9;6615:2;6607:6;6603:15;6684:6;6672:10;6669:22;6648:18;6636:10;6633:34;6630:62;6627:88;;;6695:18;;:::i;:::-;6731:2;6724:22;6770:16;;6755:32;;6830:2;6815:18;;6809:25;6843:31;6809:25;6843:31;:::i;:::-;6902:2;6890:15;;6883:30;6894:6;6377:567;-1:-1:-1;;;6377:567:1:o;7436:184::-;7506:6;7559:2;7547:9;7538:7;7534:23;7530:32;7527:52;;;7575:1;7572;7565:12;7527:52;-1:-1:-1;7598:16:1;;7436:184;-1:-1:-1;7436:184:1:o;8359:292::-;8397:4;8434;8431:1;8427:12;8466:4;8463:1;8459:12;8491:3;8486;8483:12;8480:135;;;8537:10;8532:3;8528:20;8525:1;8518:31;8572:4;8569:1;8562:15;8600:4;8597:1;8590:15;8480:135;8632:13;;;8359:292;-1:-1:-1;;;8359:292:1:o;8656:277::-;8723:6;8776:2;8764:9;8755:7;8751:23;8747:32;8744:52;;;8792:1;8789;8782:12;8744:52;8824:9;8818:16;8877:5;8870:13;8863:21;8856:5;8853:32;8843:60;;8899:1;8896;8889:12;9349:258;9421:1;9431:113;9445:6;9442:1;9439:13;9431:113;;;9521:11;;;9515:18;9502:11;;;9495:39;9467:2;9460:10;9431:113;;;9562:6;9559:1;9556:13;9553:48;;;-1:-1:-1;;9597:1:1;9579:16;;9572:27;9349:258::o;9612:274::-;9741:3;9779:6;9773:13;9795:53;9841:6;9836:3;9829:4;9821:6;9817:17;9795:53;:::i;:::-;9864:16;;;;;9612:274;-1:-1:-1;;9612:274:1:o;9891:383::-;10040:2;10029:9;10022:21;10003:4;10072:6;10066:13;10115:6;10110:2;10099:9;10095:18;10088:34;10131:66;10190:6;10185:2;10174:9;10170:18;10165:2;10157:6;10153:15;10131:66;:::i;:::-;10258:2;10237:15;-1:-1:-1;;10233:29:1;10218:45;;;;10265:2;10214:54;;9891:383;-1:-1:-1;;9891:383:1:o

Metadata Hash

2866479a4b526d07ba9f17a9780f707f581975c5e54a42707c967125473ad0e7
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.