Address Details
contract

0xDfE36BE0eA4d7875bdd24F653149Ff3768C7DC3B

Contract Name
ImmortalTreasury
Creator
0x2e63d2–fa7043 at 0xdbf315–1f531d
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
9101821
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
ImmortalTreasury




Optimization enabled
true
Compiler version
v0.7.5+commit.eb77ed08




Optimization runs
1
EVM Version
istanbul




Verified at
2022-08-19T06:03:45.634559Z

contracts/Treasury.sol

// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.7.5;

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 add32(uint32 a, uint32 b) internal pure returns (uint32) {
        uint32 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) {
        if (a == 0) {
            return 0;
        }

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

        return c;
    }

    function mul32(uint32 a, uint32 b) internal pure returns (uint32) {
        if (a == 0) {
            return 0;
        }

        uint32 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;
        return c;
    }
}

library Address {
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    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 weiValue,
        string memory errorMessage
    ) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{value: weiValue}(
            data
        );
        if (success) {
            return returndata;
        } else {
            if (returndata.length > 0) {
                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            if (returndata.length > 0) {
                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

interface IOwnable {
    function manager() external view returns (address);

    function renounceManagement() external;

    function pushManagement(address newOwner_) external;

    function pullManagement() external;
}

contract Ownable is IOwnable {
    address internal _owner;
    address internal _newOwner;

    event OwnershipPushed(
        address indexed previousOwner,
        address indexed newOwner
    );
    event OwnershipPulled(
        address indexed previousOwner,
        address indexed newOwner
    );

    constructor() {
        _owner = msg.sender;
        emit OwnershipPushed(address(0), _owner);
    }

    function manager() public view override returns (address) {
        return _owner;
    }

    modifier onlyManager() {
        require(_owner == msg.sender, "Ownable: caller is not the owner");
        _;
    }

    function renounceManagement() public virtual override onlyManager {
        emit OwnershipPushed(_owner, address(0));
        _owner = address(0);
    }

    function pushManagement(address newOwner_)
        public
        virtual
        override
        onlyManager
    {
        require(
            newOwner_ != address(0),
            "Ownable: new owner is the zero address"
        );
        emit OwnershipPushed(_owner, newOwner_);
        _newOwner = newOwner_;
    }

    function pullManagement() public virtual override {
        require(msg.sender == _newOwner, "Ownable: must be new owner to pull");
        emit OwnershipPulled(_owner, _newOwner);
        _owner = _newOwner;
    }
}

interface IERC20 {
    function decimals() external view returns (uint8);

    function balanceOf(address account) external view returns (uint256);

    function transfer(address recipient, uint256 amount)
        external
        returns (bool);

    function approve(address spender, uint256 amount) external returns (bool);

    function totalSupply() external view returns (uint256);

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

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)
        );
    }

    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"
            );
        }
    }
}

interface IERC20Mintable {
    function mint(uint256 amount_) external;

    function mint(address account_, uint256 ammount_) external;
}

interface IIMMOERC20 {
    function burnFrom(address account_, uint256 amount_) external;
}

interface IBondCalculator {
    function valuation(address pair_, uint256 amount_)
        external
        view
        returns (uint256 _value);
}

contract ImmortalTreasury is Ownable {
    using SafeMath for uint256;
    using SafeMath for uint32;
    using SafeERC20 for IERC20;

    event Deposit(address indexed token, uint256 amount, uint256 value);
    event Withdrawal(address indexed token, uint256 amount, uint256 value);
    event CreateDebt(
        address indexed debtor,
        address indexed token,
        uint256 amount,
        uint256 value
    );
    event RepayDebt(
        address indexed debtor,
        address indexed token,
        uint256 amount,
        uint256 value
    );
    event ReservesManaged(address indexed token, uint256 amount);
    event ReservesUpdated(uint256 indexed totalReserves);
    event ReservesAudited(uint256 indexed totalReserves);
    event RewardsMinted(
        address indexed caller,
        address indexed recipient,
        uint256 amount
    );
    event ChangeQueued(MANAGING indexed managing, address queued);
    event ChangeActivated(
        MANAGING indexed managing,
        address activated,
        bool result
    );

    enum MANAGING {
        RESERVEDEPOSITOR,
        RESERVESPENDER,
        RESERVETOKEN,
        RESERVEMANAGER,
        LIQUIDITYDEPOSITOR,
        LIQUIDITYTOKEN,
        LIQUIDITYMANAGER,
        DEBTOR,
        REWARDMANAGER,
        SIMMO
    }

    address public immutable IMMO;
    uint32 public immutable secondsNeededForQueue;

    address[] public reserveTokens; // Push only, beware false-positives.
    mapping(address => bool) public isReserveToken;
    mapping(address => uint32) public reserveTokenQueue; // Delays changes to mapping.

    address[] public reserveDepositors; // Push only, beware false-positives. Only for viewing.
    mapping(address => bool) public isReserveDepositor;
    mapping(address => uint32) public reserveDepositorQueue; // Delays changes to mapping.

    address[] public reserveSpenders; // Push only, beware false-positives. Only for viewing.
    mapping(address => bool) public isReserveSpender;
    mapping(address => uint32) public reserveSpenderQueue; // Delays changes to mapping.

    address[] public liquidityTokens; // Push only, beware false-positives.
    mapping(address => bool) public isLiquidityToken;
    mapping(address => uint32) public LiquidityTokenQueue; // Delays changes to mapping.

    address[] public liquidityDepositors; // Push only, beware false-positives. Only for viewing.
    mapping(address => bool) public isLiquidityDepositor;
    mapping(address => uint32) public LiquidityDepositorQueue; // Delays changes to mapping.

    mapping(address => address) public bondCalculator; // bond calculator for liquidity token

    address[] public reserveManagers; // Push only, beware false-positives. Only for viewing.
    mapping(address => bool) public isReserveManager;
    mapping(address => uint32) public ReserveManagerQueue; // Delays changes to mapping.

    address[] public liquidityManagers; // Push only, beware false-positives. Only for viewing.
    mapping(address => bool) public isLiquidityManager;
    mapping(address => uint32) public LiquidityManagerQueue; // Delays changes to mapping.

    address[] public debtors; // Push only, beware false-positives. Only for viewing.
    mapping(address => bool) public isDebtor;
    mapping(address => uint32) public debtorQueue; // Delays changes to mapping.
    mapping(address => uint256) public debtorBalance;

    address[] public rewardManagers; // Push only, beware false-positives. Only for viewing.
    mapping(address => bool) public isRewardManager;
    mapping(address => uint32) public rewardManagerQueue; // Delays changes to mapping.

    address public sIMMO;
    uint256 public sIMMOQueue; // Delays change to sOHM address

    uint256 public totalReserves; // Risk-free value of all assets
    uint256 public totalDebt;

    constructor(
        address _IMMO,
        address _mcUSD,
        uint32 _secondsNeededForQueue
    ) {
        require(_IMMO != address(0));
        IMMO = _IMMO;

        isReserveToken[_mcUSD] = true;
        reserveTokens.push(_mcUSD);

        secondsNeededForQueue = _secondsNeededForQueue;
    }

    /**
        @notice allow approved address to deposit an asset for OHM
        @param _amount uint
        @param _token address
        @param _profit uint
        @return send_ uint
     */
    function deposit(
        uint256 _amount,
        address _token,
        uint256 _profit
    ) external returns (uint256 send_) {
        require(
            isReserveToken[_token] || isLiquidityToken[_token],
            "Not accepted"
        );
        IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);

        if (isReserveToken[_token]) {
            require(isReserveDepositor[msg.sender], "Not approved");
        } else {
            require(isLiquidityDepositor[msg.sender], "Not approved");
        }

        uint256 value = valueOfToken(_token, _amount);
        // mint OHM needed and store amount of rewards for distribution
        send_ = value.sub(_profit);
        IERC20Mintable(IMMO).mint(msg.sender, send_);

        totalReserves = totalReserves.add(value);
        emit ReservesUpdated(totalReserves);

        emit Deposit(_token, _amount, value);
    }

    /**
        @notice allow approved address to burn OHM for reserves
        @param _amount uint
        @param _token address
     */
    function withdraw(uint256 _amount, address _token) external {
        require(isReserveToken[_token], "Not accepted"); // Only reserves can be used for redemptions
        require(isReserveSpender[msg.sender] == true, "Not approved");

        uint256 value = valueOfToken(_token, _amount);
        IIMMOERC20(IMMO).burnFrom(msg.sender, value);

        totalReserves = totalReserves.sub(value);
        emit ReservesUpdated(totalReserves);

        IERC20(_token).safeTransfer(msg.sender, _amount);

        emit Withdrawal(_token, _amount, value);
    }

    /**
        @notice allow approved address to borrow reserves
        @param _amount uint
        @param _token address
     */
    function incurDebt(uint256 _amount, address _token) external {
        require(isDebtor[msg.sender], "Not approved");
        require(isReserveToken[_token], "Not accepted");

        uint256 value = valueOfToken(_token, _amount);

        uint256 maximumDebt = IERC20(sIMMO).balanceOf(msg.sender); // Can only borrow against sOHM held
        uint256 availableDebt = maximumDebt.sub(debtorBalance[msg.sender]);
        require(value <= availableDebt, "Exceeds debt limit");

        debtorBalance[msg.sender] = debtorBalance[msg.sender].add(value);
        totalDebt = totalDebt.add(value);

        totalReserves = totalReserves.sub(value);
        emit ReservesUpdated(totalReserves);

        IERC20(_token).transfer(msg.sender, _amount);

        emit CreateDebt(msg.sender, _token, _amount, value);
    }

    /**
        @notice allow approved address to repay borrowed reserves with reserves
        @param _amount uint
        @param _token address
     */
    function repayDebtWithReserve(uint256 _amount, address _token) external {
        require(isDebtor[msg.sender], "Not approved");
        require(isReserveToken[_token], "Not accepted");

        IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);

        uint256 value = valueOfToken(_token, _amount);
        debtorBalance[msg.sender] = debtorBalance[msg.sender].sub(value);
        totalDebt = totalDebt.sub(value);

        totalReserves = totalReserves.add(value);
        emit ReservesUpdated(totalReserves);

        emit RepayDebt(msg.sender, _token, _amount, value);
    }

    /**
        @notice allow approved address to repay borrowed reserves with OHM
        @param _amount uint
     */
    function repayDebtWithIMMO(uint256 _amount) external {
        require(isDebtor[msg.sender], "Not approved");

        IIMMOERC20(IMMO).burnFrom(msg.sender, _amount);

        debtorBalance[msg.sender] = debtorBalance[msg.sender].sub(_amount);
        totalDebt = totalDebt.sub(_amount);

        emit RepayDebt(msg.sender, IMMO, _amount, _amount);
    }

    /**
        @notice allow approved address to withdraw assets
        @param _token address
        @param _amount uint
     */
    function manage(address _token, uint256 _amount) external {
        if (isLiquidityToken[_token]) {
            require(isLiquidityManager[msg.sender], "Not approved");
        } else {
            require(isReserveManager[msg.sender], "Not approved");
        }

        uint256 value = valueOfToken(_token, _amount);
        require(value <= excessReserves(), "Insufficient reserves");

        totalReserves = totalReserves.sub(value);
        emit ReservesUpdated(totalReserves);

        IERC20(_token).safeTransfer(msg.sender, _amount);

        emit ReservesManaged(_token, _amount);
    }

    /**
        @notice send epoch reward to staking contract
     */
    function mintRewards(address _recipient, uint256 _amount) external {
        require(isRewardManager[msg.sender], "Not approved");
        require(_amount <= excessReserves(), "Insufficient reserves");

        IERC20Mintable(IMMO).mint(_recipient, _amount);

        emit RewardsMinted(msg.sender, _recipient, _amount);
    }

    /**
        @notice returns excess reserves not backing tokens
        @return uint
     */
    function excessReserves() public view returns (uint256) {
        return totalReserves.sub(IERC20(IMMO).totalSupply().sub(totalDebt));
    }

    /**
        @notice takes inventory of all tracked assets
        @notice always consolidate to recognized reserves before audit
     */
    function auditReserves() external onlyManager {
        uint256 reserves;
        for (uint256 i = 0; i < reserveTokens.length; i++) {
            reserves = reserves.add(
                valueOfToken(
                    reserveTokens[i],
                    IERC20(reserveTokens[i]).balanceOf(address(this))
                )
            );
        }
        for (uint256 i = 0; i < liquidityTokens.length; i++) {
            reserves = reserves.add(
                valueOfToken(
                    liquidityTokens[i],
                    IERC20(liquidityTokens[i]).balanceOf(address(this))
                )
            );
        }
        totalReserves = reserves;
        emit ReservesUpdated(reserves);
        emit ReservesAudited(reserves);
    }

    /**
        @notice returns OHM valuation of asset
        @param _token address
        @param _amount uint
        @return value_ uint
     */
    function valueOfToken(address _token, uint256 _amount)
        public
        view
        returns (uint256 value_)
    {
        if (isReserveToken[_token]) {
            // convert amount to match OHM decimals
            value_ = _amount.mul(10**IERC20(IMMO).decimals()).div(
                10**IERC20(_token).decimals()
            );
        } else if (isLiquidityToken[_token]) {
            value_ = IBondCalculator(bondCalculator[_token]).valuation(
                _token,
                _amount
            );
        }
    }

    /**
        @notice queue address to change boolean in mapping
        @param _managing MANAGING
        @param _address address
        @return bool
     */
    function queue(MANAGING _managing, address _address)
        external
        onlyManager
        returns (bool)
    {
        require(_address != address(0));
        if (_managing == MANAGING.RESERVEDEPOSITOR) {
            // 0
            reserveDepositorQueue[_address] = uint32(block.timestamp).add32(
                secondsNeededForQueue
            );
        } else if (_managing == MANAGING.RESERVESPENDER) {
            // 1
            reserveSpenderQueue[_address] = uint32(block.timestamp).add32(
                secondsNeededForQueue
            );
        } else if (_managing == MANAGING.RESERVETOKEN) {
            // 2
            reserveTokenQueue[_address] = uint32(block.timestamp).add32(
                secondsNeededForQueue
            );
        } else if (_managing == MANAGING.RESERVEMANAGER) {
            // 3
            ReserveManagerQueue[_address] = uint32(block.timestamp).add32(
                secondsNeededForQueue.mul32(2)
            );
        } else if (_managing == MANAGING.LIQUIDITYDEPOSITOR) {
            // 4
            LiquidityDepositorQueue[_address] = uint32(block.timestamp).add32(
                secondsNeededForQueue
            );
        } else if (_managing == MANAGING.LIQUIDITYTOKEN) {
            // 5
            LiquidityTokenQueue[_address] = uint32(block.timestamp).add32(
                secondsNeededForQueue
            );
        } else if (_managing == MANAGING.LIQUIDITYMANAGER) {
            // 6
            LiquidityManagerQueue[_address] = uint32(block.timestamp).add32(
                secondsNeededForQueue.mul32(2)
            );
        } else if (_managing == MANAGING.DEBTOR) {
            // 7
            debtorQueue[_address] = uint32(block.timestamp).add32(
                secondsNeededForQueue
            );
        } else if (_managing == MANAGING.REWARDMANAGER) {
            // 8
            rewardManagerQueue[_address] = uint32(block.timestamp).add32(
                secondsNeededForQueue
            );
        } else if (_managing == MANAGING.SIMMO) {
            // 9
            sIMMOQueue = uint32(block.timestamp).add32(secondsNeededForQueue);
        } else return false;

        emit ChangeQueued(_managing, _address);
        return true;
    }

    /**
        @notice verify queue then set boolean in mapping
        @param _managing MANAGING
        @param _address address
        @param _calculator address
        @return bool
     */
    function toggle(
        MANAGING _managing,
        address _address,
        address _calculator
    ) external onlyManager returns (bool) {
        require(_address != address(0));
        bool result;
        if (_managing == MANAGING.RESERVEDEPOSITOR) {
            // 0
            if (
                requirements(
                    reserveDepositorQueue,
                    isReserveDepositor,
                    _address
                )
            ) {
                reserveDepositorQueue[_address] = 0;
                if (!listContains(reserveDepositors, _address)) {
                    reserveDepositors.push(_address);
                }
            }
            result = !isReserveDepositor[_address];
            isReserveDepositor[_address] = result;
        } else if (_managing == MANAGING.RESERVESPENDER) {
            // 1
            if (requirements(reserveSpenderQueue, isReserveSpender, _address)) {
                reserveSpenderQueue[_address] = 0;
                if (!listContains(reserveSpenders, _address)) {
                    reserveSpenders.push(_address);
                }
            }
            result = !isReserveSpender[_address];
            isReserveSpender[_address] = result;
        } else if (_managing == MANAGING.RESERVETOKEN) {
            // 2
            if (requirements(reserveTokenQueue, isReserveToken, _address)) {
                reserveTokenQueue[_address] = 0;
                if (!listContains(reserveTokens, _address)) {
                    reserveTokens.push(_address);
                }
            }
            result = !isReserveToken[_address];
            isReserveToken[_address] = result;
        } else if (_managing == MANAGING.RESERVEMANAGER) {
            // 3
            if (requirements(ReserveManagerQueue, isReserveManager, _address)) {
                reserveManagers.push(_address);
                ReserveManagerQueue[_address] = 0;
                if (!listContains(reserveManagers, _address)) {
                    reserveManagers.push(_address);
                }
            }
            result = !isReserveManager[_address];
            isReserveManager[_address] = result;
        } else if (_managing == MANAGING.LIQUIDITYDEPOSITOR) {
            // 4
            if (
                requirements(
                    LiquidityDepositorQueue,
                    isLiquidityDepositor,
                    _address
                )
            ) {
                liquidityDepositors.push(_address);
                LiquidityDepositorQueue[_address] = 0;
                if (!listContains(liquidityDepositors, _address)) {
                    liquidityDepositors.push(_address);
                }
            }
            result = !isLiquidityDepositor[_address];
            isLiquidityDepositor[_address] = result;
        } else if (_managing == MANAGING.LIQUIDITYTOKEN) {
            // 5
            if (requirements(LiquidityTokenQueue, isLiquidityToken, _address)) {
                LiquidityTokenQueue[_address] = 0;
                if (!listContains(liquidityTokens, _address)) {
                    liquidityTokens.push(_address);
                }
            }
            result = !isLiquidityToken[_address];
            isLiquidityToken[_address] = result;
            bondCalculator[_address] = _calculator;
        } else if (_managing == MANAGING.LIQUIDITYMANAGER) {
            // 6
            if (
                requirements(
                    LiquidityManagerQueue,
                    isLiquidityManager,
                    _address
                )
            ) {
                LiquidityManagerQueue[_address] = 0;
                if (!listContains(liquidityManagers, _address)) {
                    liquidityManagers.push(_address);
                }
            }
            result = !isLiquidityManager[_address];
            isLiquidityManager[_address] = result;
        } else if (_managing == MANAGING.DEBTOR) {
            // 7
            if (requirements(debtorQueue, isDebtor, _address)) {
                debtorQueue[_address] = 0;
                if (!listContains(debtors, _address)) {
                    debtors.push(_address);
                }
            }
            result = !isDebtor[_address];
            isDebtor[_address] = result;
        } else if (_managing == MANAGING.REWARDMANAGER) {
            // 8
            if (requirements(rewardManagerQueue, isRewardManager, _address)) {
                rewardManagerQueue[_address] = 0;
                if (!listContains(rewardManagers, _address)) {
                    rewardManagers.push(_address);
                }
            }
            result = !isRewardManager[_address];
            isRewardManager[_address] = result;
        } else if (_managing == MANAGING.SIMMO) {
            // 9
            sIMMOQueue = 0;
            sIMMO = _address;
            result = true;
        } else return false;

        emit ChangeActivated(_managing, _address, result);
        return true;
    }

    /**
        @notice checks requirements and returns altered structs
        @param queue_ mapping( address => uint )
        @param status_ mapping( address => bool )
        @param _address address
        @return bool 
     */
    function requirements(
        mapping(address => uint32) storage queue_,
        mapping(address => bool) storage status_,
        address _address
    ) internal view returns (bool) {
        if (!status_[_address]) {
            require(queue_[_address] != 0, "Must queue");
            require(
                queue_[_address] <= uint32(block.timestamp),
                "Queue not expired"
            );
            return true;
        }
        return false;
    }

    /**
        @notice checks array to ensure against duplicate
        @param _list address[]
        @param _token address
        @return bool
     */
    function listContains(address[] storage _list, address _token)
        internal
        view
        returns (bool)
    {
        for (uint256 i = 0; i < _list.length; i++) {
            if (_list[i] == _token) {
                return true;
            }
        }
        return false;
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_IMMO","internalType":"address"},{"type":"address","name":"_mcUSD","internalType":"address"},{"type":"uint32","name":"_secondsNeededForQueue","internalType":"uint32"}]},{"type":"event","name":"ChangeActivated","inputs":[{"type":"uint8","name":"managing","internalType":"enum ImmortalTreasury.MANAGING","indexed":true},{"type":"address","name":"activated","internalType":"address","indexed":false},{"type":"bool","name":"result","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"ChangeQueued","inputs":[{"type":"uint8","name":"managing","internalType":"enum ImmortalTreasury.MANAGING","indexed":true},{"type":"address","name":"queued","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"CreateDebt","inputs":[{"type":"address","name":"debtor","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Deposit","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipPulled","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipPushed","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RepayDebt","inputs":[{"type":"address","name":"debtor","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ReservesAudited","inputs":[{"type":"uint256","name":"totalReserves","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"ReservesManaged","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ReservesUpdated","inputs":[{"type":"uint256","name":"totalReserves","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"RewardsMinted","inputs":[{"type":"address","name":"caller","internalType":"address","indexed":true},{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdrawal","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"IMMO","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"LiquidityDepositorQueue","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"LiquidityManagerQueue","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"LiquidityTokenQueue","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"ReserveManagerQueue","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"auditReserves","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"bondCalculator","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"debtorBalance","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"debtorQueue","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"debtors","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"send_","internalType":"uint256"}],"name":"deposit","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_profit","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"excessReserves","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"incurDebt","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isDebtor","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isLiquidityDepositor","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isLiquidityManager","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isLiquidityToken","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isReserveDepositor","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isReserveManager","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isReserveSpender","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isReserveToken","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isRewardManager","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"liquidityDepositors","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"liquidityManagers","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"liquidityTokens","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"manage","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"manager","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintRewards","inputs":[{"type":"address","name":"_recipient","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pullManagement","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pushManagement","inputs":[{"type":"address","name":"newOwner_","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"queue","inputs":[{"type":"uint8","name":"_managing","internalType":"enum ImmortalTreasury.MANAGING"},{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceManagement","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"repayDebtWithIMMO","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"repayDebtWithReserve","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"reserveDepositorQueue","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"reserveDepositors","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"reserveManagers","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"reserveSpenderQueue","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"reserveSpenders","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"reserveTokenQueue","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"reserveTokens","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"rewardManagerQueue","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rewardManagers","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"sIMMO","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"sIMMOQueue","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"secondsNeededForQueue","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"toggle","inputs":[{"type":"uint8","name":"_managing","internalType":"enum ImmortalTreasury.MANAGING"},{"type":"address","name":"_address","internalType":"address"},{"type":"address","name":"_calculator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalDebt","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalReserves","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"value_","internalType":"uint256"}],"name":"valueOfToken","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_token","internalType":"address"}]}]
              

Contract Creation Code

0x60c060405234801561001057600080fd5b5060405162003827380380620038278339818101604052606081101561003557600080fd5b5080516020820151604092830151600080546001600160a01b031916331780825594519394929391926001600160a01b0316917fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba908290a36001600160a01b0383166100a057600080fd5b6001600160601b0319606084901b166080526001600160a01b039182166000818152600360205260408120805460ff1916600190811790915560028054918201815582527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319169092179091556001600160e01b031960e083901b1660a052919092169163ffffffff169061367e90620001a990398061164d5280611f725280611fef528061206c52806120e8528061217a52806121f7528061227352806122f5528061237252806123ef5250806109ae5280610ac35280610d625280611542528061175452806118085280611a2d5280611c1f525061367e6000f3fe608060405234801561001057600080fd5b50600436106102505760003560e01c8062f714ce14610255578063025de6cd146102835780630619aff1146102a7578063089208d8146102c4578063094a8651146102cc5780630b0eee30146103045780630c3513a814610330578063124154ca1461033857806312422d23146103725780631af4da701461039e5780631fa2eb32146103c45780632b7ce500146103cc578063437f7912146103d457806346f68ee9146103f1578063481c6a75146104175780634e83423c1461041f5780635a96ac0a1461044557806368c31dd51461044d5780636a20de92146104735780636b5e40a71461049f57806370a0502a146104bc578063788c6c01146104d95780637a8960d814610518578063869871bf1461052057806387d67dff1461053d5780638f59c727146105635780638f6a7b57146105895780638f840ddd146105a6578063932cc8c3146105ae5780639f924d6d146105d4578063a1210a2d146105f1578063a569e57114610617578063ab319c9a1461063d578063b1bd38b014610663578063b5b1d56014610689578063bc157ac1146106a6578063c24ad43e146106d8578063cd85641a146106fe578063d031370b14610724578063d1b317e514610741578063d796ffb81461076d578063da8de1b814610799578063df89b344146107a1578063e83afee3146107c7578063ebd83cd8146107f6578063ee4e19a11461081c578063fb93958814610842578063fbfd393b14610868578063fc7b9c181461089f578063fd1ec010146108a7578063fff9ee87146108c4575b600080fd5b6102816004803603604081101561026b57600080fd5b50803590602001356001600160a01b03166108ea565b005b61028b610ac1565b604080516001600160a01b039092168252519081900360200190f35b61028b600480360360208110156102bd57600080fd5b5035610ae5565b610281610b0f565b6102f2600480360360208110156102e257600080fd5b50356001600160a01b0316610b94565b60408051918252519081900360200190f35b6102816004803603604081101561031a57600080fd5b506001600160a01b038135169060200135610ba6565b6102f2610d55565b61035e6004803603602081101561034e57600080fd5b50356001600160a01b0316610df9565b604080519115158252519081900360200190f35b6102816004803603604081101561038857600080fd5b50803590602001356001600160a01b0316610e0e565b61028b600480360360208110156103b457600080fd5b50356001600160a01b03166110de565b61028b6110f9565b610281611108565b61028b600480360360208110156103ea57600080fd5b50356112cb565b6102816004803603602081101561040757600080fd5b50356001600160a01b03166112db565b61028b6113b6565b61035e6004803603602081101561043557600080fd5b50356001600160a01b03166113c5565b6102816113da565b61035e6004803603602081101561046357600080fd5b50356001600160a01b0316611484565b6102816004803603604081101561048957600080fd5b506001600160a01b038135169060200135611499565b61028b600480360360208110156104b557600080fd5b5035611613565b61028b600480360360208110156104d257600080fd5b5035611623565b6104ff600480360360208110156104ef57600080fd5b50356001600160a01b0316611633565b6040805163ffffffff9092168252519081900360200190f35b6104ff61164b565b61028b6004803603602081101561053657600080fd5b503561166f565b61035e6004803603602081101561055357600080fd5b50356001600160a01b031661167f565b6104ff6004803603602081101561057957600080fd5b50356001600160a01b0316611694565b61028b6004803603602081101561059f57600080fd5b50356116ac565b6102f26116bc565b6104ff600480360360208110156105c457600080fd5b50356001600160a01b03166116c2565b610281600480360360208110156105ea57600080fd5b50356116da565b61035e6004803603602081101561060757600080fd5b50356001600160a01b0316611847565b61035e6004803603602081101561062d57600080fd5b50356001600160a01b031661185c565b6104ff6004803603602081101561065357600080fd5b50356001600160a01b0316611871565b6104ff6004803603602081101561067957600080fd5b50356001600160a01b0316611889565b61028b6004803603602081101561069f57600080fd5b50356118a1565b6102f2600480360360608110156106bc57600080fd5b508035906001600160a01b0360208201351690604001356118b1565b6104ff600480360360208110156106ee57600080fd5b50356001600160a01b0316611b2f565b6104ff6004803603602081101561071457600080fd5b50356001600160a01b0316611b47565b61028b6004803603602081101561073a57600080fd5b5035611b5f565b6102f26004803603604081101561075757600080fd5b506001600160a01b038135169060200135611b6f565b6102816004803603604081101561078357600080fd5b50803590602001356001600160a01b0316611d63565b6102f2611ed4565b61035e600480360360208110156107b757600080fd5b50356001600160a01b0316611eda565b61035e600480360360408110156107dd57600080fd5b50803560ff1690602001356001600160a01b0316611eef565b61035e6004803603602081101561080c57600080fd5b50356001600160a01b031661247c565b61035e6004803603602081101561083257600080fd5b50356001600160a01b0316612491565b6104ff6004803603602081101561085857600080fd5b50356001600160a01b03166124a6565b61035e6004803603606081101561087e57600080fd5b5060ff813516906001600160a01b03602082013581169160400135166124be565b6102f2612d8c565b61028b600480360360208110156108bd57600080fd5b5035612d92565b6104ff600480360360208110156108da57600080fd5b50356001600160a01b0316612da2565b6001600160a01b03811660009081526003602052604090205460ff16610946576040805162461bcd60e51b815260206004820152600c60248201526b139bdd081858d8d95c1d195960a21b604482015290519081900360640190fd5b3360009081526009602052604090205460ff16151560011461099e576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b60006109aa8284611b6f565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166379cc679033836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610a2357600080fd5b505af1158015610a37573d6000803e3d6000fd5b5050602154610a499250905082612dba565b60218190556040516000805160206135df83398151915290600090a2610a796001600160a01b0383163385612dfc565b604080518481526020810183905281516001600160a01b038516927fdf273cb619d95419a9cd0ec88123a0538c85064229baa6363788f743fff90deb928290030190a2505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60128181548110610af557600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b03163314610b5c576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116906000805160206134f6833981519152908390a3600080546001600160a01b0319169055565b601b6020526000908152604090205481565b6001600160a01b0382166000908152600c602052604090205460ff1615610c1f573360009081526016602052604090205460ff16610c1a576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b610c72565b3360009081526013602052604090205460ff16610c72576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6000610c7e8383611b6f565b9050610c88610d55565b811115610cd4576040805162461bcd60e51b8152602060048201526015602482015274496e73756666696369656e7420726573657276657360581b604482015290519081900360640190fd5b602154610ce19082612dba565b60218190556040516000805160206135df83398151915290600090a2610d116001600160a01b0384163384612dfc565b6040805183815290516001600160a01b038516917f2bb2640731848fe9820ba48dbc978c1fc9bbd5f11b948bfab05b7dee3378fd80919081900360200190a2505050565b6000610df4610deb6022547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610db957600080fd5b505afa158015610dcd573d6000803e3d6000fd5b505050506040513d6020811015610de357600080fd5b505190612dba565b60215490612dba565b905090565b60066020526000908152604090205460ff1681565b3360009081526019602052604090205460ff16610e61576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6001600160a01b03811660009081526003602052604090205460ff16610ebd576040805162461bcd60e51b815260206004820152600c60248201526b139bdd081858d8d95c1d195960a21b604482015290519081900360640190fd5b6000610ec98284611b6f565b601f54604080516370a0823160e01b815233600482015290519293506000926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610f1a57600080fd5b505afa158015610f2e573d6000803e3d6000fd5b505050506040513d6020811015610f4457600080fd5b5051336000908152601b602052604081205491925090610f65908390612dba565b905080831115610fb1576040805162461bcd60e51b8152602060048201526012602482015271115e18d959591cc81919589d081b1a5b5a5d60721b604482015290519081900360640190fd5b336000908152601b6020526040902054610fcb9084612e53565b336000908152601b6020526040902055602254610fe89084612e53565b602255602154610ff89084612dba565b60218190556040516000805160206135df83398151915290600090a26040805163a9059cbb60e01b81523360048201526024810187905290516001600160a01b0386169163a9059cbb9160448083019260209291908290030181600087803b15801561106357600080fd5b505af1158015611077573d6000803e3d6000fd5b505050506040513d602081101561108d57600080fd5b5050604080518681526020810185905281516001600160a01b0387169233927f7e1a939bed137a819b5d2979822c67f877689f7a863d5e4cb57cdca97b2977d6929081900390910190a35050505050565b6011602052600090815260409020546001600160a01b031681565b601f546001600160a01b031681565b6000546001600160a01b03163314611155576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b6000805b60025481101561122d5761122361121c6002838154811061117657fe5b600091825260209091200154600280546001600160a01b03909216918590811061119c57fe5b60009182526020918290200154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b1580156111eb57600080fd5b505afa1580156111ff573d6000803e3d6000fd5b505050506040513d602081101561121557600080fd5b5051611b6f565b8390612e53565b9150600101611159565b5060005b600b5481101561127e5761127461121c600b838154811061124e57fe5b600091825260209091200154600b80546001600160a01b03909216918590811061119c57fe5b9150600101611231565b50602181905560405181906000805160206135df83398151915290600090a260405181907fec691f09f6924b27932253f85caf99bacc30360cc0e50a1cc4d2acc24601446690600090a250565b60088181548110610af557600080fd5b6000546001600160a01b03163314611328576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b6001600160a01b03811661136d5760405162461bcd60e51b81526004018080602001828103825260268152602001806135166026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216916000805160206134f683398151915291a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031690565b601d6020526000908152604090205460ff1681565b6001546001600160a01b031633146114235760405162461bcd60e51b815260040180806020018281038252602281526020018061357c6022913960400191505060405180910390fd5b600154600080546040516001600160a01b0393841693909116917faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d91a3600154600080546001600160a01b0319166001600160a01b03909216919091179055565b60036020526000908152604090205460ff1681565b336000908152601d602052604090205460ff166114ec576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6114f4610d55565b811115611540576040805162461bcd60e51b8152602060048201526015602482015274496e73756666696369656e7420726573657276657360581b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340c10f1983836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156115b757600080fd5b505af11580156115cb573d6000803e3d6000fd5b50506040805184815290516001600160a01b03861693503392507ffa8ccab40e7da8146c2304cd0950334fd30a6ba093abe86261aa13911fed849c9181900360200190a35050565b60058181548110610af557600080fd5b60158181548110610af557600080fd5b60046020526000908152604090205463ffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60188181548110610af557600080fd5b60096020526000908152604090205460ff1681565b600d6020526000908152604090205463ffffffff1681565b600e8181548110610af557600080fd5b60215481565b60076020526000908152604090205463ffffffff1681565b3360009081526019602052604090205460ff1661172d576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6040805163079cc67960e41b81523360048201526024810183905290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916379cc679091604480830192600092919082900301818387803b15801561179b57600080fd5b505af11580156117af573d6000803e3d6000fd5b5050336000908152601b60205260409020546117ce9250905082612dba565b336000908152601b60205260409020556022546117eb9082612dba565b602255604080518281526020810183905281516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169233926000805160206135ff833981519152929081900390910190a350565b600f6020526000908152604090205460ff1681565b600c6020526000908152604090205460ff1681565b60176020526000908152604090205463ffffffff1681565b60146020526000908152604090205463ffffffff1681565b601c8181548110610af557600080fd5b6001600160a01b03821660009081526003602052604081205460ff16806118f057506001600160a01b0383166000908152600c602052604090205460ff165b611930576040805162461bcd60e51b815260206004820152600c60248201526b139bdd081858d8d95c1d195960a21b604482015290519081900360640190fd5b6119456001600160a01b038416333087612eab565b6001600160a01b03831660009081526003602052604090205460ff16156119be573360009081526006602052604090205460ff166119b9576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b611a11565b336000908152600f602052604090205460ff16611a11576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6000611a1d8486611b6f565b9050611a298184612dba565b91507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340c10f1933846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611aa257600080fd5b505af1158015611ab6573d6000803e3d6000fd5b5050602154611ac89250905082612e53565b60218190556040516000805160206135df83398151915290600090a2604080518681526020810183905281516001600160a01b038716927f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15928290030190a2509392505050565b600a6020526000908152604090205463ffffffff1681565b601a6020526000908152604090205463ffffffff1681565b60028181548110610af557600080fd5b6001600160a01b03821660009081526003602052604081205460ff1615611cac57611ca5836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611bcc57600080fd5b505afa158015611be0573d6000803e3d6000fd5b505050506040513d6020811015611bf657600080fd5b50516040805163313ce56760e01b8152905160ff909216600a0a91611c9f916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163313ce56791600480820192602092909190829003018186803b158015611c6657600080fd5b505afa158015611c7a573d6000803e3d6000fd5b505050506040513d6020811015611c9057600080fd5b5051859060ff16600a0a612f0b565b90612f64565b9050611d5d565b6001600160a01b0383166000908152600c602052604090205460ff1615611d5d576001600160a01b03808416600081815260116020908152604091829020548251634249719f60e01b815260048101949094526024840187905291519190931692634249719f9260448082019391829003018186803b158015611d2e57600080fd5b505afa158015611d42573d6000803e3d6000fd5b505050506040513d6020811015611d5857600080fd5b505190505b92915050565b3360009081526019602052604090205460ff16611db6576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6001600160a01b03811660009081526003602052604090205460ff16611e12576040805162461bcd60e51b815260206004820152600c60248201526b139bdd081858d8d95c1d195960a21b604482015290519081900360640190fd5b611e276001600160a01b038216333085612eab565b6000611e338284611b6f565b336000908152601b6020526040902054909150611e509082612dba565b336000908152601b6020526040902055602254611e6d9082612dba565b602255602154611e7d9082612e53565b60218190556040516000805160206135df83398151915290600090a2604080518481526020810183905281516001600160a01b0385169233926000805160206135ff833981519152929081900390910190a3505050565b60205481565b60166020526000908152604090205460ff1681565b600080546001600160a01b03163314611f3d576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b6001600160a01b038216611f5057600080fd5b6000836009811115611f5e57fe5b1415611fcd57611f9863ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152600760205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b6001836009811115611fdb57fe5b141561204a5761201563ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152600a60205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b600283600981111561205857fe5b14156120c75761209263ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152600460205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b60038360098111156120d557fe5b14156121585761212361211363ffffffff7f000000000000000000000000000000000000000000000000000000000000000081169060029061300416565b63ffffffff4281169190612fa316565b6001600160a01b0383166000908152601460205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b600483600981111561216657fe5b14156121d5576121a063ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152601060205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b60058360098111156121e357fe5b14156122525761221d63ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152600d60205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b600683600981111561226057fe5b14156122d35761229e61211363ffffffff7f000000000000000000000000000000000000000000000000000000000000000081169060029061300416565b6001600160a01b0383166000908152601760205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b60078360098111156122e157fe5b14156123505761231b63ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152601a60205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b600883600981111561235e57fe5b14156123cd5761239863ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152601e60205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b60098360098111156123db57fe5b14156124235761241563ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b63ffffffff1660205561242b565b506000611d5d565b82600981111561243757fe5b604080516001600160a01b038516815290517f0e4f2c4b5bc209d509bc3d49348c787fefadc66a79351b470599ac0f5be52eaf9181900360200190a250600192915050565b60136020526000908152604090205460ff1681565b60196020526000908152604090205460ff1681565b601e6020526000908152604090205463ffffffff1681565b600080546001600160a01b0316331461250c576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b6001600160a01b03831661251f57600080fd5b60008085600981111561252e57fe5b14156125f4576125416007600686613075565b156125c4576001600160a01b0384166000908152600760205260409020805463ffffffff1916905561257460058561316e565b6125c457600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152600660205260409020805460ff81161560ff199091168117909155612d2e565b600185600981111561260257fe5b14156126c857612615600a600986613075565b15612698576001600160a01b0384166000908152600a60205260409020805463ffffffff1916905561264860088561316e565b61269857600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152600960205260409020805460ff81161560ff199091168117909155612d2e565b60028560098111156126d657fe5b141561279c576126e96004600386613075565b1561276c576001600160a01b0384166000908152600460205260409020805463ffffffff1916905561271c60028561316e565b61276c57600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152600360205260409020805460ff81161560ff199091168117909155612d2e565b60038560098111156127aa57fe5b1415612889576127bd6014601386613075565b15612859576012805460018101825560008051602061355c8339815191520180546001600160a01b0319166001600160a01b0387169081179091556000908152601460205260409020805463ffffffff1916905561281b908561316e565b612859576012805460018101825560009190915260008051602061355c8339815191520180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152601360205260409020805460ff81161560ff199091168117909155612d2e565b600485600981111561289757fe5b1415612976576128aa6010600f86613075565b1561294657600e805460018101825560008051602061353c8339815191520180546001600160a01b0319166001600160a01b0387169081179091556000908152601060205260409020805463ffffffff19169055612908908561316e565b61294657600e805460018101825560009190915260008051602061353c8339815191520180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152600f60205260409020805460ff81161560ff199091168117909155612d2e565b600585600981111561298457fe5b1415612a6c57612997600d600c86613075565b15612a1a576001600160a01b0384166000908152600d60205260409020805463ffffffff191690556129ca600b8561316e565b612a1a57600b80546001810182556000919091527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b038381166000908152600c60209081526040808320805460ff81161560ff199091168117909155601190925290912080546001600160a01b03191692851692909217909155612d2e565b6006856009811115612a7a57fe5b1415612b4057612a8d6017601686613075565b15612b10576001600160a01b0384166000908152601760205260409020805463ffffffff19169055612ac060158561316e565b612b1057601580546001810182556000919091527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec4750180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152601660205260409020805460ff81161560ff199091168117909155612d2e565b6007856009811115612b4e57fe5b1415612c1457612b61601a601986613075565b15612be4576001600160a01b0384166000908152601a60205260409020805463ffffffff19169055612b9460188561316e565b612be457601880546001810182556000919091527fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e0180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152601960205260409020805460ff81161560ff199091168117909155612d2e565b6008856009811115612c2257fe5b1415612ce857612c35601e601d86613075565b15612cb8576001600160a01b0384166000908152601e60205260409020805463ffffffff19169055612c68601c8561316e565b612cb857601c80546001810182556000919091527f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a2110180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152601d60205260409020805460ff81161560ff199091168117909155612d2e565b6009856009811115612cf657fe5b1415612d2457506000602055601f80546001600160a01b0319166001600160a01b0385161790556001612d2e565b6000915050612d85565b846009811115612d3a57fe5b604080516001600160a01b0387168152831515602082015281517f0dcacb7e392f3d6a216ed2660e3dcfd40b7793d33591db2ba185a6b8e44fc477929181900390910190a260019150505b9392505050565b60225481565b600b8181548110610af557600080fd5b60106020526000908152604090205463ffffffff1681565b6000612d8583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506131be565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612e4e908490613255565b505050565b600082820183811015612d85576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612f05908590613255565b50505050565b600082612f1a57506000611d5d565b82820282848281612f2757fe5b0414612d855760405162461bcd60e51b815260040180806020018281038252602181526020018061359e6021913960400191505060405180910390fd5b6000612d8583836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b815250613306565b600082820163ffffffff8085169082161015612d85576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b600063ffffffff831661301957506000611d5d565b82820263ffffffff808416908086169083168161303257fe5b0463ffffffff1614612d855760405162461bcd60e51b815260040180806020018281038252602181526020018061359e6021913960400191505060405180910390fd5b6001600160a01b03811660009081526020839052604081205460ff16613164576001600160a01b03821660009081526020859052604090205463ffffffff166130f2576040805162461bcd60e51b815260206004820152600a6024820152694d75737420717565756560b01b604482015290519081900360640190fd5b6001600160a01b03821660009081526020859052604090205463ffffffff4281169116111561315c576040805162461bcd60e51b8152602060048201526011602482015270145d595d59481b9bdd08195e1c1a5c9959607a1b604482015290519081900360640190fd5b506001612d85565b5060009392505050565b6000805b835481101561316457826001600160a01b031684828154811061319157fe5b6000918252602090912001546001600160a01b031614156131b6576001915050611d5d565b600101613172565b6000818484111561324d5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156132125781810151838201526020016131fa565b50505050905090810190601f16801561323f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60606132aa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661336b9092919063ffffffff16565b805190915015612e4e578080602001905160208110156132c957600080fd5b5051612e4e5760405162461bcd60e51b815260040180806020018281038252602a81526020018061361f602a913960400191505060405180910390fd5b600081836133555760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156132125781810151838201526020016131fa565b50600083858161336157fe5b0495945050505050565b606061337a8484600085613382565b949350505050565b606061338d856134ef565b6133de576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061341d5780518252601f1990920191602091820191016133fe565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461347f576040519150601f19603f3d011682016040523d82523d6000602084013e613484565b606091505b5091509150811561349857915061337a9050565b8051156134a85780518082602001fd5b60405162461bcd60e51b81526020600482018181528651602484015286518793919283926044019190850190808383600083156132125781810151838201526020016131fa565b3b15159056feea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373bb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fdbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34444f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657293bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d66c6d98eecfc9c78ab62c89a82950079b54874749f1f6f24090f7acc758bc2f3095361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212207028148bd42ecbfabbbfe0e1896bdafe81c568d413bbe98b40fa0a545e24f2e564736f6c6343000705003300000000000000000000000088424b77de0cccf4fee697585a4a7366fc8608370000000000000000000000007d43a503e5c3343c16101b887a15d2f835a8f6930000000000000000000000000000000000000000000000000000000000000000

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106102505760003560e01c8062f714ce14610255578063025de6cd146102835780630619aff1146102a7578063089208d8146102c4578063094a8651146102cc5780630b0eee30146103045780630c3513a814610330578063124154ca1461033857806312422d23146103725780631af4da701461039e5780631fa2eb32146103c45780632b7ce500146103cc578063437f7912146103d457806346f68ee9146103f1578063481c6a75146104175780634e83423c1461041f5780635a96ac0a1461044557806368c31dd51461044d5780636a20de92146104735780636b5e40a71461049f57806370a0502a146104bc578063788c6c01146104d95780637a8960d814610518578063869871bf1461052057806387d67dff1461053d5780638f59c727146105635780638f6a7b57146105895780638f840ddd146105a6578063932cc8c3146105ae5780639f924d6d146105d4578063a1210a2d146105f1578063a569e57114610617578063ab319c9a1461063d578063b1bd38b014610663578063b5b1d56014610689578063bc157ac1146106a6578063c24ad43e146106d8578063cd85641a146106fe578063d031370b14610724578063d1b317e514610741578063d796ffb81461076d578063da8de1b814610799578063df89b344146107a1578063e83afee3146107c7578063ebd83cd8146107f6578063ee4e19a11461081c578063fb93958814610842578063fbfd393b14610868578063fc7b9c181461089f578063fd1ec010146108a7578063fff9ee87146108c4575b600080fd5b6102816004803603604081101561026b57600080fd5b50803590602001356001600160a01b03166108ea565b005b61028b610ac1565b604080516001600160a01b039092168252519081900360200190f35b61028b600480360360208110156102bd57600080fd5b5035610ae5565b610281610b0f565b6102f2600480360360208110156102e257600080fd5b50356001600160a01b0316610b94565b60408051918252519081900360200190f35b6102816004803603604081101561031a57600080fd5b506001600160a01b038135169060200135610ba6565b6102f2610d55565b61035e6004803603602081101561034e57600080fd5b50356001600160a01b0316610df9565b604080519115158252519081900360200190f35b6102816004803603604081101561038857600080fd5b50803590602001356001600160a01b0316610e0e565b61028b600480360360208110156103b457600080fd5b50356001600160a01b03166110de565b61028b6110f9565b610281611108565b61028b600480360360208110156103ea57600080fd5b50356112cb565b6102816004803603602081101561040757600080fd5b50356001600160a01b03166112db565b61028b6113b6565b61035e6004803603602081101561043557600080fd5b50356001600160a01b03166113c5565b6102816113da565b61035e6004803603602081101561046357600080fd5b50356001600160a01b0316611484565b6102816004803603604081101561048957600080fd5b506001600160a01b038135169060200135611499565b61028b600480360360208110156104b557600080fd5b5035611613565b61028b600480360360208110156104d257600080fd5b5035611623565b6104ff600480360360208110156104ef57600080fd5b50356001600160a01b0316611633565b6040805163ffffffff9092168252519081900360200190f35b6104ff61164b565b61028b6004803603602081101561053657600080fd5b503561166f565b61035e6004803603602081101561055357600080fd5b50356001600160a01b031661167f565b6104ff6004803603602081101561057957600080fd5b50356001600160a01b0316611694565b61028b6004803603602081101561059f57600080fd5b50356116ac565b6102f26116bc565b6104ff600480360360208110156105c457600080fd5b50356001600160a01b03166116c2565b610281600480360360208110156105ea57600080fd5b50356116da565b61035e6004803603602081101561060757600080fd5b50356001600160a01b0316611847565b61035e6004803603602081101561062d57600080fd5b50356001600160a01b031661185c565b6104ff6004803603602081101561065357600080fd5b50356001600160a01b0316611871565b6104ff6004803603602081101561067957600080fd5b50356001600160a01b0316611889565b61028b6004803603602081101561069f57600080fd5b50356118a1565b6102f2600480360360608110156106bc57600080fd5b508035906001600160a01b0360208201351690604001356118b1565b6104ff600480360360208110156106ee57600080fd5b50356001600160a01b0316611b2f565b6104ff6004803603602081101561071457600080fd5b50356001600160a01b0316611b47565b61028b6004803603602081101561073a57600080fd5b5035611b5f565b6102f26004803603604081101561075757600080fd5b506001600160a01b038135169060200135611b6f565b6102816004803603604081101561078357600080fd5b50803590602001356001600160a01b0316611d63565b6102f2611ed4565b61035e600480360360208110156107b757600080fd5b50356001600160a01b0316611eda565b61035e600480360360408110156107dd57600080fd5b50803560ff1690602001356001600160a01b0316611eef565b61035e6004803603602081101561080c57600080fd5b50356001600160a01b031661247c565b61035e6004803603602081101561083257600080fd5b50356001600160a01b0316612491565b6104ff6004803603602081101561085857600080fd5b50356001600160a01b03166124a6565b61035e6004803603606081101561087e57600080fd5b5060ff813516906001600160a01b03602082013581169160400135166124be565b6102f2612d8c565b61028b600480360360208110156108bd57600080fd5b5035612d92565b6104ff600480360360208110156108da57600080fd5b50356001600160a01b0316612da2565b6001600160a01b03811660009081526003602052604090205460ff16610946576040805162461bcd60e51b815260206004820152600c60248201526b139bdd081858d8d95c1d195960a21b604482015290519081900360640190fd5b3360009081526009602052604090205460ff16151560011461099e576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b60006109aa8284611b6f565b90507f00000000000000000000000088424b77de0cccf4fee697585a4a7366fc8608376001600160a01b03166379cc679033836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610a2357600080fd5b505af1158015610a37573d6000803e3d6000fd5b5050602154610a499250905082612dba565b60218190556040516000805160206135df83398151915290600090a2610a796001600160a01b0383163385612dfc565b604080518481526020810183905281516001600160a01b038516927fdf273cb619d95419a9cd0ec88123a0538c85064229baa6363788f743fff90deb928290030190a2505050565b7f00000000000000000000000088424b77de0cccf4fee697585a4a7366fc86083781565b60128181548110610af557600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b03163314610b5c576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116906000805160206134f6833981519152908390a3600080546001600160a01b0319169055565b601b6020526000908152604090205481565b6001600160a01b0382166000908152600c602052604090205460ff1615610c1f573360009081526016602052604090205460ff16610c1a576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b610c72565b3360009081526013602052604090205460ff16610c72576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6000610c7e8383611b6f565b9050610c88610d55565b811115610cd4576040805162461bcd60e51b8152602060048201526015602482015274496e73756666696369656e7420726573657276657360581b604482015290519081900360640190fd5b602154610ce19082612dba565b60218190556040516000805160206135df83398151915290600090a2610d116001600160a01b0384163384612dfc565b6040805183815290516001600160a01b038516917f2bb2640731848fe9820ba48dbc978c1fc9bbd5f11b948bfab05b7dee3378fd80919081900360200190a2505050565b6000610df4610deb6022547f00000000000000000000000088424b77de0cccf4fee697585a4a7366fc8608376001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610db957600080fd5b505afa158015610dcd573d6000803e3d6000fd5b505050506040513d6020811015610de357600080fd5b505190612dba565b60215490612dba565b905090565b60066020526000908152604090205460ff1681565b3360009081526019602052604090205460ff16610e61576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6001600160a01b03811660009081526003602052604090205460ff16610ebd576040805162461bcd60e51b815260206004820152600c60248201526b139bdd081858d8d95c1d195960a21b604482015290519081900360640190fd5b6000610ec98284611b6f565b601f54604080516370a0823160e01b815233600482015290519293506000926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610f1a57600080fd5b505afa158015610f2e573d6000803e3d6000fd5b505050506040513d6020811015610f4457600080fd5b5051336000908152601b602052604081205491925090610f65908390612dba565b905080831115610fb1576040805162461bcd60e51b8152602060048201526012602482015271115e18d959591cc81919589d081b1a5b5a5d60721b604482015290519081900360640190fd5b336000908152601b6020526040902054610fcb9084612e53565b336000908152601b6020526040902055602254610fe89084612e53565b602255602154610ff89084612dba565b60218190556040516000805160206135df83398151915290600090a26040805163a9059cbb60e01b81523360048201526024810187905290516001600160a01b0386169163a9059cbb9160448083019260209291908290030181600087803b15801561106357600080fd5b505af1158015611077573d6000803e3d6000fd5b505050506040513d602081101561108d57600080fd5b5050604080518681526020810185905281516001600160a01b0387169233927f7e1a939bed137a819b5d2979822c67f877689f7a863d5e4cb57cdca97b2977d6929081900390910190a35050505050565b6011602052600090815260409020546001600160a01b031681565b601f546001600160a01b031681565b6000546001600160a01b03163314611155576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b6000805b60025481101561122d5761122361121c6002838154811061117657fe5b600091825260209091200154600280546001600160a01b03909216918590811061119c57fe5b60009182526020918290200154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b1580156111eb57600080fd5b505afa1580156111ff573d6000803e3d6000fd5b505050506040513d602081101561121557600080fd5b5051611b6f565b8390612e53565b9150600101611159565b5060005b600b5481101561127e5761127461121c600b838154811061124e57fe5b600091825260209091200154600b80546001600160a01b03909216918590811061119c57fe5b9150600101611231565b50602181905560405181906000805160206135df83398151915290600090a260405181907fec691f09f6924b27932253f85caf99bacc30360cc0e50a1cc4d2acc24601446690600090a250565b60088181548110610af557600080fd5b6000546001600160a01b03163314611328576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b6001600160a01b03811661136d5760405162461bcd60e51b81526004018080602001828103825260268152602001806135166026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216916000805160206134f683398151915291a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031690565b601d6020526000908152604090205460ff1681565b6001546001600160a01b031633146114235760405162461bcd60e51b815260040180806020018281038252602281526020018061357c6022913960400191505060405180910390fd5b600154600080546040516001600160a01b0393841693909116917faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d91a3600154600080546001600160a01b0319166001600160a01b03909216919091179055565b60036020526000908152604090205460ff1681565b336000908152601d602052604090205460ff166114ec576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6114f4610d55565b811115611540576040805162461bcd60e51b8152602060048201526015602482015274496e73756666696369656e7420726573657276657360581b604482015290519081900360640190fd5b7f00000000000000000000000088424b77de0cccf4fee697585a4a7366fc8608376001600160a01b03166340c10f1983836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156115b757600080fd5b505af11580156115cb573d6000803e3d6000fd5b50506040805184815290516001600160a01b03861693503392507ffa8ccab40e7da8146c2304cd0950334fd30a6ba093abe86261aa13911fed849c9181900360200190a35050565b60058181548110610af557600080fd5b60158181548110610af557600080fd5b60046020526000908152604090205463ffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60188181548110610af557600080fd5b60096020526000908152604090205460ff1681565b600d6020526000908152604090205463ffffffff1681565b600e8181548110610af557600080fd5b60215481565b60076020526000908152604090205463ffffffff1681565b3360009081526019602052604090205460ff1661172d576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6040805163079cc67960e41b81523360048201526024810183905290516001600160a01b037f00000000000000000000000088424b77de0cccf4fee697585a4a7366fc86083716916379cc679091604480830192600092919082900301818387803b15801561179b57600080fd5b505af11580156117af573d6000803e3d6000fd5b5050336000908152601b60205260409020546117ce9250905082612dba565b336000908152601b60205260409020556022546117eb9082612dba565b602255604080518281526020810183905281516001600160a01b037f00000000000000000000000088424b77de0cccf4fee697585a4a7366fc860837169233926000805160206135ff833981519152929081900390910190a350565b600f6020526000908152604090205460ff1681565b600c6020526000908152604090205460ff1681565b60176020526000908152604090205463ffffffff1681565b60146020526000908152604090205463ffffffff1681565b601c8181548110610af557600080fd5b6001600160a01b03821660009081526003602052604081205460ff16806118f057506001600160a01b0383166000908152600c602052604090205460ff165b611930576040805162461bcd60e51b815260206004820152600c60248201526b139bdd081858d8d95c1d195960a21b604482015290519081900360640190fd5b6119456001600160a01b038416333087612eab565b6001600160a01b03831660009081526003602052604090205460ff16156119be573360009081526006602052604090205460ff166119b9576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b611a11565b336000908152600f602052604090205460ff16611a11576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6000611a1d8486611b6f565b9050611a298184612dba565b91507f00000000000000000000000088424b77de0cccf4fee697585a4a7366fc8608376001600160a01b03166340c10f1933846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611aa257600080fd5b505af1158015611ab6573d6000803e3d6000fd5b5050602154611ac89250905082612e53565b60218190556040516000805160206135df83398151915290600090a2604080518681526020810183905281516001600160a01b038716927f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15928290030190a2509392505050565b600a6020526000908152604090205463ffffffff1681565b601a6020526000908152604090205463ffffffff1681565b60028181548110610af557600080fd5b6001600160a01b03821660009081526003602052604081205460ff1615611cac57611ca5836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611bcc57600080fd5b505afa158015611be0573d6000803e3d6000fd5b505050506040513d6020811015611bf657600080fd5b50516040805163313ce56760e01b8152905160ff909216600a0a91611c9f916001600160a01b037f00000000000000000000000088424b77de0cccf4fee697585a4a7366fc860837169163313ce56791600480820192602092909190829003018186803b158015611c6657600080fd5b505afa158015611c7a573d6000803e3d6000fd5b505050506040513d6020811015611c9057600080fd5b5051859060ff16600a0a612f0b565b90612f64565b9050611d5d565b6001600160a01b0383166000908152600c602052604090205460ff1615611d5d576001600160a01b03808416600081815260116020908152604091829020548251634249719f60e01b815260048101949094526024840187905291519190931692634249719f9260448082019391829003018186803b158015611d2e57600080fd5b505afa158015611d42573d6000803e3d6000fd5b505050506040513d6020811015611d5857600080fd5b505190505b92915050565b3360009081526019602052604090205460ff16611db6576040805162461bcd60e51b815260206004820152600c60248201526b139bdd08185c1c1c9bdd995960a21b604482015290519081900360640190fd5b6001600160a01b03811660009081526003602052604090205460ff16611e12576040805162461bcd60e51b815260206004820152600c60248201526b139bdd081858d8d95c1d195960a21b604482015290519081900360640190fd5b611e276001600160a01b038216333085612eab565b6000611e338284611b6f565b336000908152601b6020526040902054909150611e509082612dba565b336000908152601b6020526040902055602254611e6d9082612dba565b602255602154611e7d9082612e53565b60218190556040516000805160206135df83398151915290600090a2604080518481526020810183905281516001600160a01b0385169233926000805160206135ff833981519152929081900390910190a3505050565b60205481565b60166020526000908152604090205460ff1681565b600080546001600160a01b03163314611f3d576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b6001600160a01b038216611f5057600080fd5b6000836009811115611f5e57fe5b1415611fcd57611f9863ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152600760205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b6001836009811115611fdb57fe5b141561204a5761201563ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152600a60205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b600283600981111561205857fe5b14156120c75761209263ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152600460205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b60038360098111156120d557fe5b14156121585761212361211363ffffffff7f000000000000000000000000000000000000000000000000000000000000000081169060029061300416565b63ffffffff4281169190612fa316565b6001600160a01b0383166000908152601460205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b600483600981111561216657fe5b14156121d5576121a063ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152601060205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b60058360098111156121e357fe5b14156122525761221d63ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152600d60205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b600683600981111561226057fe5b14156122d35761229e61211363ffffffff7f000000000000000000000000000000000000000000000000000000000000000081169060029061300416565b6001600160a01b0383166000908152601760205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b60078360098111156122e157fe5b14156123505761231b63ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152601a60205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b600883600981111561235e57fe5b14156123cd5761239863ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b6001600160a01b0383166000908152601e60205260409020805463ffffffff191663ffffffff9290921691909117905561242b565b60098360098111156123db57fe5b14156124235761241563ffffffff428116907f000000000000000000000000000000000000000000000000000000000000000090612fa316565b63ffffffff1660205561242b565b506000611d5d565b82600981111561243757fe5b604080516001600160a01b038516815290517f0e4f2c4b5bc209d509bc3d49348c787fefadc66a79351b470599ac0f5be52eaf9181900360200190a250600192915050565b60136020526000908152604090205460ff1681565b60196020526000908152604090205460ff1681565b601e6020526000908152604090205463ffffffff1681565b600080546001600160a01b0316331461250c576040805162461bcd60e51b815260206004820181905260248201526000805160206135bf833981519152604482015290519081900360640190fd5b6001600160a01b03831661251f57600080fd5b60008085600981111561252e57fe5b14156125f4576125416007600686613075565b156125c4576001600160a01b0384166000908152600760205260409020805463ffffffff1916905561257460058561316e565b6125c457600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152600660205260409020805460ff81161560ff199091168117909155612d2e565b600185600981111561260257fe5b14156126c857612615600a600986613075565b15612698576001600160a01b0384166000908152600a60205260409020805463ffffffff1916905561264860088561316e565b61269857600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152600960205260409020805460ff81161560ff199091168117909155612d2e565b60028560098111156126d657fe5b141561279c576126e96004600386613075565b1561276c576001600160a01b0384166000908152600460205260409020805463ffffffff1916905561271c60028561316e565b61276c57600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152600360205260409020805460ff81161560ff199091168117909155612d2e565b60038560098111156127aa57fe5b1415612889576127bd6014601386613075565b15612859576012805460018101825560008051602061355c8339815191520180546001600160a01b0319166001600160a01b0387169081179091556000908152601460205260409020805463ffffffff1916905561281b908561316e565b612859576012805460018101825560009190915260008051602061355c8339815191520180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152601360205260409020805460ff81161560ff199091168117909155612d2e565b600485600981111561289757fe5b1415612976576128aa6010600f86613075565b1561294657600e805460018101825560008051602061353c8339815191520180546001600160a01b0319166001600160a01b0387169081179091556000908152601060205260409020805463ffffffff19169055612908908561316e565b61294657600e805460018101825560009190915260008051602061353c8339815191520180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152600f60205260409020805460ff81161560ff199091168117909155612d2e565b600585600981111561298457fe5b1415612a6c57612997600d600c86613075565b15612a1a576001600160a01b0384166000908152600d60205260409020805463ffffffff191690556129ca600b8561316e565b612a1a57600b80546001810182556000919091527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b038381166000908152600c60209081526040808320805460ff81161560ff199091168117909155601190925290912080546001600160a01b03191692851692909217909155612d2e565b6006856009811115612a7a57fe5b1415612b4057612a8d6017601686613075565b15612b10576001600160a01b0384166000908152601760205260409020805463ffffffff19169055612ac060158561316e565b612b1057601580546001810182556000919091527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec4750180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152601660205260409020805460ff81161560ff199091168117909155612d2e565b6007856009811115612b4e57fe5b1415612c1457612b61601a601986613075565b15612be4576001600160a01b0384166000908152601a60205260409020805463ffffffff19169055612b9460188561316e565b612be457601880546001810182556000919091527fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e0180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152601960205260409020805460ff81161560ff199091168117909155612d2e565b6008856009811115612c2257fe5b1415612ce857612c35601e601d86613075565b15612cb8576001600160a01b0384166000908152601e60205260409020805463ffffffff19169055612c68601c8561316e565b612cb857601c80546001810182556000919091527f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a2110180546001600160a01b0319166001600160a01b0386161790555b506001600160a01b0383166000908152601d60205260409020805460ff81161560ff199091168117909155612d2e565b6009856009811115612cf657fe5b1415612d2457506000602055601f80546001600160a01b0319166001600160a01b0385161790556001612d2e565b6000915050612d85565b846009811115612d3a57fe5b604080516001600160a01b0387168152831515602082015281517f0dcacb7e392f3d6a216ed2660e3dcfd40b7793d33591db2ba185a6b8e44fc477929181900390910190a260019150505b9392505050565b60225481565b600b8181548110610af557600080fd5b60106020526000908152604090205463ffffffff1681565b6000612d8583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506131be565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612e4e908490613255565b505050565b600082820183811015612d85576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612f05908590613255565b50505050565b600082612f1a57506000611d5d565b82820282848281612f2757fe5b0414612d855760405162461bcd60e51b815260040180806020018281038252602181526020018061359e6021913960400191505060405180910390fd5b6000612d8583836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b815250613306565b600082820163ffffffff8085169082161015612d85576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b600063ffffffff831661301957506000611d5d565b82820263ffffffff808416908086169083168161303257fe5b0463ffffffff1614612d855760405162461bcd60e51b815260040180806020018281038252602181526020018061359e6021913960400191505060405180910390fd5b6001600160a01b03811660009081526020839052604081205460ff16613164576001600160a01b03821660009081526020859052604090205463ffffffff166130f2576040805162461bcd60e51b815260206004820152600a6024820152694d75737420717565756560b01b604482015290519081900360640190fd5b6001600160a01b03821660009081526020859052604090205463ffffffff4281169116111561315c576040805162461bcd60e51b8152602060048201526011602482015270145d595d59481b9bdd08195e1c1a5c9959607a1b604482015290519081900360640190fd5b506001612d85565b5060009392505050565b6000805b835481101561316457826001600160a01b031684828154811061319157fe5b6000918252602090912001546001600160a01b031614156131b6576001915050611d5d565b600101613172565b6000818484111561324d5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156132125781810151838201526020016131fa565b50505050905090810190601f16801561323f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60606132aa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661336b9092919063ffffffff16565b805190915015612e4e578080602001905160208110156132c957600080fd5b5051612e4e5760405162461bcd60e51b815260040180806020018281038252602a81526020018061361f602a913960400191505060405180910390fd5b600081836133555760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156132125781810151838201526020016131fa565b50600083858161336157fe5b0495945050505050565b606061337a8484600085613382565b949350505050565b606061338d856134ef565b6133de576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061341d5780518252601f1990920191602091820191016133fe565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461347f576040519150601f19603f3d011682016040523d82523d6000602084013e613484565b606091505b5091509150811561349857915061337a9050565b8051156134a85780518082602001fd5b60405162461bcd60e51b81526020600482018181528651602484015286518793919283926044019190850190808383600083156132125781810151838201526020016131fa565b3b15159056feea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373bb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fdbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34444f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657293bb8edd35984706eee1b92541281f7f62d33c01c5b2ec0929a113603bd21d66c6d98eecfc9c78ab62c89a82950079b54874749f1f6f24090f7acc758bc2f3095361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212207028148bd42ecbfabbbfe0e1896bdafe81c568d413bbe98b40fa0a545e24f2e564736f6c63430007050033