false
false
The Sokol Testnet is currently lacking validators. Please consider using Goerli or Mumbai for testing purposes.

Contract Address Details
contract

0x9E0B3DEe28d6f3dce2387a457ed5C463e1290878

Contract Name
WrappedPinakion
Creator
0xc713e1–028e32 at 0x4d7549–396301
Balance
0 SPOA
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
27736955
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
WrappedPinakion




Optimization enabled
true
Compiler version
v0.4.26+commit.4563c3fc




Optimization runs
1
EVM Version
default




Verified at
2021-05-11T14:13:39.261875Z

Contract source code

Sol2uml
new
// File: openzeppelin-eth/contracts/zos-lib/Initializable.sol

pragma solidity ^0.4.24;


/**
 * @title Initializable
 *
 * @dev Helper contract to support initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` modifier.
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an Initializable contract, as well
 * as extending an Initializable contract via inheritance.
 * WARNING: When used with inheritance, manual care must be taken to not invoke
 * a parent initializer twice, or ensure that all initializers are idempotent,
 * because this is not dealt with automatically as with constructors.
 */
contract Initializable {

  /**
   * @dev Indicates that the contract has been initialized.
   */
  bool private initialized;

  /**
   * @dev Indicates that the contract is in the process of being initialized.
   */
  bool private initializing;

  /**
   * @dev Modifier to use in the initializer function of a contract.
   */
  modifier initializer() {
    require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");

    bool wasInitializing = initializing;
    initializing = true;
    initialized = true;

    _;

    initializing = wasInitializing;
  }

  /// @dev Returns true if and only if the function is running in the constructor
  function isConstructor() private view returns (bool) {
    // extcodesize checks the size of the code stored in an address, and
    // address returns the current address. Since the code is still not
    // deployed when running a constructor, any checks on its code size will
    // yield zero, making it an effective way to detect if a contract is
    // under construction or not.
    uint256 cs;
    assembly { cs := extcodesize(address) }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[50] private ______gap;
}

// File: openzeppelin-eth/contracts/math/SafeMath.sol

pragma solidity ^0.4.24;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {

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

    uint256 c = a * b;
    require(c / a == b);

    return c;
  }

  /**
  * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b > 0); // Solidity only automatically asserts when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  /**
  * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a);
    uint256 c = a - b;

    return c;
  }

  /**
  * @dev Adds two numbers, reverts on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a);

    return c;
  }

  /**
  * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
  * reverts when dividing by zero.
  */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0);
    return a % b;
  }
}

// File: minimetoken/contracts/TokenController.sol

pragma solidity ^0.4.18;

/// @dev The token controller contract must implement these functions
contract TokenController {
    /// @notice Called when `_owner` sends ether to the MiniMe Token contract
    /// @param _owner The address that sent the ether to create tokens
    /// @return True if the ether is accepted, false if it throws
    function proxyPayment(address _owner) public payable returns(bool);

    /// @notice Notifies the controller about a token transfer allowing the
    ///  controller to react if desired
    /// @param _from The origin of the transfer
    /// @param _to The destination of the transfer
    /// @param _amount The amount of the transfer
    /// @return False if the controller does not authorize the transfer
    function onTransfer(address _from, address _to, uint _amount) public returns(bool);

    /// @notice Notifies the controller about an approval allowing the
    ///  controller to react if desired
    /// @param _owner The address that calls `approve()`
    /// @param _spender The spender in the `approve()` call
    /// @param _amount The amount in the `approve()` call
    /// @return False if the controller does not authorize the approval
    function onApprove(address _owner, address _spender, uint _amount) public
        returns(bool);
}

// File: contracts/interfaces/IERC677.sol

pragma solidity ^0.4.24;

interface IERC677 {
    function transfer(address _to, uint256 _value) external returns (bool);
    function transferFrom(address _from, address _to, uint256 _value) external returns (bool);
    function approve(address _spender, uint256 _value) external returns (bool);
    function permit(address _holder, address _spender, uint256 _nonce, uint256 _expiry, bool _allowed, uint8 _v, bytes32 _r, bytes32 _s) external;
}

// File: contracts/interfaces/ITokenBridge.sol

pragma solidity ^0.4.24;


interface ITokenBridge {
    function relayTokens(IERC677 token, address _receiver, uint256 _value) external;
}

// File: contracts/tokens/WrappedPinakion.sol

/**
 *  https://contributing.kleros.io/smart-contract-workflow
 *  @authors: [@fnanni-0]
 *  @reviewers: [@unknownunknown1, @MerlinEgalite, @hbarcelos, @shalzz]
 *  @auditors: []
 *  @bounties: []
 *  @deployments: []
 */
pragma solidity ^0.4.24;






contract WrappedPinakion is Initializable {

    using SafeMath for uint256;

    /* Events */

    /**
    * @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).
    *
    * Note that `value` may be zero.
    */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
    * @dev Emitted when the allowance of a `spender` for an `owner` is set by
    * a call to {approve}. `value` is the new allowance.
    */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /* Storage */

    mapping (address => uint256) private balances;
    mapping (address => mapping (address => uint256)) public allowance;

    /// @dev Total supply of the token. Equals the total xPinakion deposit into the contract.
    uint256 public totalSupply;

    /// @dev Name of the token.
    string public name;

    /// @dev Symbol of the token.
    string public symbol;

    /// @dev Number of decimals of the token.
    uint8 public decimals;

    /// @dev The token's controller.
    address public controller;

    /// @dev Pinakion on xDai to be wrapped. This token is upgradeable.
    IERC677 public xPinakion;

    /// @dev xDai Token Bridge. The Token Bridge is upgradeable.
    ITokenBridge public tokenBridge;

    /* Modifiers */

    /// @dev Verifies that the sender has ability to modify controlled parameters.
    modifier onlyController() {
        require(controller == msg.sender, "The caller is not the controller.");
        _;
    }

    /* Initializer */

    /** @dev Constructor.
     *  @param _name for the wrapped Pinakion on the home chain.
     *  @param _symbol for wrapped Pinakion ticker on the home chain.
     *  @param _xPinakion the home pinakion contract which is already bridged to the foreign pinakion contract.
     *  @param _tokenBridge the TokenBridge contract.
     */
    function initialize(
        string memory _name, 
        string memory _symbol, 
        IERC677 _xPinakion, 
        ITokenBridge _tokenBridge
    ) public initializer {
        name = _name;
        symbol = _symbol;
        decimals = 18;
        xPinakion = _xPinakion;
        tokenBridge = _tokenBridge;

        controller = msg.sender;
    }

    /* External */

    /** @dev Changes `controller` to `_controller`.
     *  @param _controller The new controller of the contract
     */
    function changeController(address _controller) external onlyController {
        controller = _controller;
    }


    /** @dev Converts bridged pinakions into pinakions which can be staked in KlerosLiquid.
     *  @param _amount The amount of wrapped pinakions to mint.
     */
    function deposit(uint _amount) external {
        _mint(msg.sender, _amount);
        require(xPinakion.transferFrom(msg.sender, address(this), _amount), "Sender does not have enough approved funds.");
    }


    /** @dev IERC20 Receiver functionality. 
     *  Converts bridged PNK (xPinakion) into wrapped PNK which can be staked in KlerosLiquid.
     *  If the tokenBridge is calling this function, then this contract has already received
     *  the xPinakion tokens.
     *  @param _token The token address the _amount belongs to.
     *  @param _amount The amount of wrapped pinakions to mint.
     *  @param _data Calldata containing the address of the recipient.
     */
    function onTokenBridged(address _token, uint _amount, bytes _data) external {
        require(msg.sender == address(tokenBridge), "Sender not authorized.");
        require(_token == address(xPinakion), "Token bridged is not xPinakion.");

        address recipient;
        assembly {
            recipient := calldataload(0x84)
        }
        _mint(recipient, _amount);
    }

    /** @dev Withdraws bridged pinakions.
     *  @param _amount The amount of bridged pinakions to withdraw.
     */
    function withdraw(uint _amount) external {
        _burn(_amount);
        require(xPinakion.transfer(msg.sender, _amount), "The `transfer` function must not fail.");
    }

    /** @dev This function is not strictly needed, but it provides a good UX to users who want to get their Mainnet's PNK back. 
     *  What normally takes 3 transactions, here is done in one go. 
     *  Notice that the PNK have to be claimed on mainnet's TokenBride by the receiver.
     *  @param _amount The amount of bridged pinakions to withdraw.
     *  @param _receiver The address which will receive the PNK back in the foreign chain.
     */ 
    function withdrawAndConvertToPNK(uint _amount, address _receiver) external {
        _burn(_amount);
        // Using approve is safe here, because this contract approves the bridge to spend the tokens and triggers the relay immediately.
        xPinakion.approve(address(tokenBridge), _amount);
        tokenBridge.relayTokens(xPinakion, _receiver, _amount);
    }

    /** @dev Moves `_amount` tokens from the caller's account to `_recipient`.
     *  @param _recipient The entity receiving the funds.
     *  @param _amount The amount to tranfer in base units.
     */
    function transfer(address _recipient, uint256 _amount) public returns (bool) {
        if (isContract(controller)) {
            require(TokenController(controller).onTransfer(msg.sender, _recipient, _amount));
        }
        balances[msg.sender] = balances[msg.sender].sub(_amount); // ERC20: transfer amount exceeds balance
        balances[_recipient] = balances[_recipient].add(_amount);
        emit Transfer(msg.sender, _recipient, _amount);
        return true;
    }

    /** @dev Moves `_amount` tokens from `_sender` to `_recipient` using the
     *  allowance mechanism. `_amount` is then deducted from the caller's allowance.
     *  @param _sender The entity to take the funds from.
     *  @param _recipient The entity receiving the funds.
     *  @param _amount The amount to tranfer in base units.
     */
    function transferFrom(address _sender, address _recipient, uint256 _amount) public returns (bool) {
        if (isContract(controller)) {
            require(TokenController(controller).onTransfer(_sender, _recipient, _amount));
        }

        /** The controller of this contract can move tokens around at will,
         *  this is important to recognize! Confirm that you trust the
         *  controller of this contract, which in most situations should be
         *  another open source smart contract or 0x0.
         */
        if (msg.sender != controller) {
            allowance[_sender][msg.sender] = allowance[_sender][msg.sender].sub(_amount); // ERC20: transfer amount exceeds allowance.
        }
        
        balances[_sender] = balances[_sender].sub(_amount); // ERC20: transfer amount exceeds balance
        balances[_recipient] = balances[_recipient].add(_amount);
        emit Transfer(_sender, _recipient, _amount);
        return true;
    }

    /** @dev Approves `_spender` to spend `_amount`.
     *  @param _spender The entity allowed to spend funds.
     *  @param _amount The amount of base units the entity will be allowed to spend.
     */
    function approve(address _spender, uint256 _amount) public returns (bool) {
        // Alerts the token controller of the approve function call
        if (isContract(controller)) {
            require(TokenController(controller).onApprove(msg.sender, _spender, _amount), "Token controller does not approve.");
        }

        allowance[msg.sender][_spender] = _amount;
        emit Approval(msg.sender, _spender, _amount);
        return true;
    }

    /** @dev Increases the `_spender` allowance by `_addedValue`.
     *  @param _spender The entity allowed to spend funds.
     *  @param _addedValue The amount of extra base units the entity will be allowed to spend.
     */
    function increaseAllowance(address _spender, uint256 _addedValue) public returns (bool) {
        uint256 newAllowance = allowance[msg.sender][_spender].add(_addedValue);
        // Alerts the token controller of the approve function call
        if (isContract(controller)) {
            require(TokenController(controller).onApprove(msg.sender, _spender, newAllowance), "Token controller does not approve.");
        }

        allowance[msg.sender][_spender] = newAllowance;
        emit Approval(msg.sender, _spender, newAllowance);
        return true;
    }

    /** @dev Decreases the `_spender` allowance by `_subtractedValue`.
     *  @param _spender The entity whose spending allocation will be reduced.
     *  @param _subtractedValue The reduction of spending allocation in base units.
     */
    function decreaseAllowance(address _spender, uint256 _subtractedValue) public returns (bool) {
        uint256 newAllowance = allowance[msg.sender][_spender].sub(_subtractedValue); // ERC20: decreased allowance below zero
        // Alerts the token controller of the approve function call
        if (isContract(controller)) {
            require(TokenController(controller).onApprove(msg.sender, _spender, newAllowance), "Token controller does not approve.");
        }

        allowance[msg.sender][_spender] = newAllowance;
        emit Approval(msg.sender, _spender, newAllowance);
        return true;
    }

    /* Internal */

    /**
    * @dev Internal function that mints an amount of the token and assigns it to
    * an account. This encapsulates the modification of balances such that the
    * proper events are emitted.
    * @param _recipient The amount that will be created.
    * @param _amount The amount that will be created.
    */
    function _mint(address _recipient, uint256 _amount) internal {
        totalSupply = totalSupply.add(_amount);
        balances[_recipient] = balances[_recipient].add(_amount);
        emit Transfer(address(0x0), _recipient, _amount);
    }

    /** @dev Destroys `_amount` tokens from the caller. Cannot burn locked tokens.
     *  @param _amount The quantity of tokens to burn in base units.
     */
    function _burn(uint256 _amount) internal {
        if (isContract(controller)) {
            require(TokenController(controller).onTransfer(msg.sender, address(0x0), _amount));
        }
        balances[msg.sender] = balances[msg.sender].sub(_amount); // ERC20: burn amount exceeds balance
        totalSupply = totalSupply.sub(_amount);
        emit Transfer(msg.sender, address(0x0), _amount);
    }

    /** @dev Internal function to determine if an address is a contract.
     *  @param _addr The address being queried.
     *  @return True if `_addr` is a contract.
     */
    function isContract(address _addr) internal view returns(bool) {
        uint size;
        if (_addr == 0) return false;
        assembly {
            size := extcodesize(_addr)
        }
        return size > 0;
    }

    /* Getters */

    /**
    * @dev Gets the balance of the specified address.
    * @param _owner The address to query the balance of.
    * @return uint256 value representing the amount owned by the passed address.
    */
    function balanceOf(address _owner) public view returns (uint256) {
        return balances[_owner];
    }
}
        

Contract ABI

[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":""}],"name":"name","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"approve","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"transferFrom","inputs":[{"type":"address","name":"_sender"},{"type":"address","name":"_recipient"},{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":""}],"name":"decimals","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"xPinakion","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"increaseAllowance","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_addedValue"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"changeController","inputs":[{"type":"address","name":"_controller"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdrawAndConvertToPNK","inputs":[{"type":"uint256","name":"_amount"},{"type":"address","name":"_receiver"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"string","name":"_name"},{"type":"string","name":"_symbol"},{"type":"address","name":"_xPinakion"},{"type":"address","name":"_tokenBridge"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":""}],"name":"symbol","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_subtractedValue"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"transfer","inputs":[{"type":"address","name":"_recipient"},{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"deposit","inputs":[{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"tokenBridge","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"onTokenBridged","inputs":[{"type":"address","name":"_token"},{"type":"uint256","name":"_amount"},{"type":"bytes","name":"_data"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"allowance","inputs":[{"type":"address","name":""},{"type":"address","name":""}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"controller","inputs":[],"constant":true},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","indexed":true},{"type":"address","name":"spender","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b50611574806100206000396000f3006080604052600436106100f85763ffffffff60e060020a60003504166306fdde0381146100fd578063095ea7b31461018757806318160ddd146101bf57806323b872dd146101e65780632e1a7d4d14610210578063313ce5671461022a57806333e1cbda1461025557806339509351146102865780633cebb823146102aa57806370a08231146102cb5780638108022d146102ec5780638f15b4141461031057806395d89b41146103bd578063a457c2d7146103d2578063a9059cbb146103f6578063b6b55f251461041a578063c6328a4614610432578063db7af85414610447578063dd62ed3e14610478578063f77c47911461049f575b600080fd5b34801561010957600080fd5b506101126104b4565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561014c578181015183820152602001610134565b50505050905090810190601f1680156101795780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019357600080fd5b506101ab600160a060020a0360043516602435610542565b604080519115158252519081900360200190f35b3480156101cb57600080fd5b506101d461069c565b60408051918252519081900360200190f35b3480156101f257600080fd5b506101ab600160a060020a03600435811690602435166044356106a2565b34801561021c57600080fd5b5061022860043561087f565b005b34801561023657600080fd5b5061023f610976565b6040805160ff9092168252519081900360200190f35b34801561026157600080fd5b5061026a61097f565b60408051600160a060020a039092168252519081900360200190f35b34801561029257600080fd5b506101ab600160a060020a036004351660243561098e565b3480156102b657600080fd5b50610228600160a060020a0360043516610b1f565b3480156102d757600080fd5b506101d4600160a060020a0360043516610bbb565b3480156102f857600080fd5b50610228600435600160a060020a0360243516610bd6565b34801561031c57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261022894369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975050600160a060020a038535811696506020909501359094169350610ce692505050565b3480156103c957600080fd5b50610112610e39565b3480156103de57600080fd5b506101ab600160a060020a0360043516602435610e94565b34801561040257600080fd5b506101ab600160a060020a0360043516602435610eca565b34801561042657600080fd5b50610228600435611026565b34801561043e57600080fd5b5061026a611126565b34801561045357600080fd5b5061022860048035600160a060020a0316906024803591604435918201910135611135565b34801561048457600080fd5b506101d4600160a060020a0360043581169060243516611210565b3480156104ab57600080fd5b5061026a61122d565b6036805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561053a5780601f1061050f5761010080835404028352916020019161053a565b820191906000526020600020905b81548152906001019060200180831161051d57829003601f168201915b505050505081565b60385460009061055f906101009004600160a060020a0316611241565b15610647576038546040805160e060020a63da682aeb028152336004820152600160a060020a0386811660248301526044820186905291516101009093049091169163da682aeb916064808201926020929091908290030181600087803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b505050506040513d60208110156105f357600080fd5b50511515610647576040805160e560020a62461bcd02815260206004820152602260248201526000805160206114e9833981519152604482015260f160020a61329702606482015290519081900360840190fd5b336000818152603460209081526040808320600160a060020a0388168085529083529281902086905580518681529051929392600080516020611529833981519152929181900390910190a350600192915050565b60355481565b6038546000906106bf906101009004600160a060020a0316611241565b15610762576038546040805160e060020a634a393149028152600160a060020a038781166004830152868116602483015260448201869052915161010090930490911691634a393149916064808201926020929091908290030181600087803b15801561072b57600080fd5b505af115801561073f573d6000803e3d6000fd5b505050506040513d602081101561075557600080fd5b5051151561076257600080fd5b6038546101009004600160a060020a031633146107d257600160a060020a03841660009081526034602090815260408083203384529091529020546107ad908363ffffffff61126e16565b600160a060020a03851660009081526034602090815260408083203384529091529020555b600160a060020a0384166000908152603360205260409020546107fb908363ffffffff61126e16565b600160a060020a038086166000908152603360205260408082209390935590851681522054610830908363ffffffff61128516565b600160a060020a03808516600081815260336020908152604091829020949094558051868152905191939288169260008051602061150983398151915292918290030190a35060019392505050565b6108888161129e565b6039546040805160e060020a63a9059cbb028152336004820152602481018490529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156108df57600080fd5b505af11580156108f3573d6000803e3d6000fd5b505050506040513d602081101561090957600080fd5b50511515610973576040805160e560020a62461bcd02815260206004820152602660248201527f54686520607472616e73666572602066756e6374696f6e206d757374206e6f74604482015260d160020a65103330b4b61702606482015290519081900360840190fd5b50565b60385460ff1681565b603954600160a060020a031681565b336000908152603460209081526040808320600160a060020a038616845290915281205481906109c4908463ffffffff61128516565b6038549091506109e1906101009004600160a060020a0316611241565b15610ac9576038546040805160e060020a63da682aeb028152336004820152600160a060020a0387811660248301526044820185905291516101009093049091169163da682aeb916064808201926020929091908290030181600087803b158015610a4b57600080fd5b505af1158015610a5f573d6000803e3d6000fd5b505050506040513d6020811015610a7557600080fd5b50511515610ac9576040805160e560020a62461bcd02815260206004820152602260248201526000805160206114e9833981519152604482015260f160020a61329702606482015290519081900360840190fd5b336000818152603460209081526040808320600160a060020a0389168085529083529281902085905580518581529051929392600080516020611529833981519152929181900390910190a35060019392505050565b6038546101009004600160a060020a03163314610b93576040805160e560020a62461bcd02815260206004820152602160248201527f5468652063616c6c6572206973206e6f742074686520636f6e74726f6c6c6572604482015260f960020a601702606482015290519081900360840190fd5b60388054600160a060020a039092166101000261010060a860020a0319909216919091179055565b600160a060020a031660009081526033602052604090205490565b610bdf8261129e565b603954603a546040805160e060020a63095ea7b3028152600160a060020a039283166004820152602481018690529051919092169163095ea7b39160448083019260209291908290030181600087803b158015610c3b57600080fd5b505af1158015610c4f573d6000803e3d6000fd5b505050506040513d6020811015610c6557600080fd5b5050603a546039546040805160e060020a63ad58bdd1028152600160a060020a0392831660048201528483166024820152604481018690529051919092169163ad58bdd191606480830192600092919082900301818387803b158015610cca57600080fd5b505af1158015610cde573d6000803e3d6000fd5b505050505050565b60008054610100900460ff1680610d005750610d006113c8565b80610d0e575060005460ff16155b1515610d7e576040805160e560020a62461bcd02815260206004820152602e60248201527f436f6e747261637420696e7374616e63652068617320616c72656164792062656044820152609260020a6d195b881a5b9a5d1a585b1a5e995902606482015290519081900360840190fd5b5060008054600161010061ff00198316811760ff191691909117909255855191900460ff1690610db5906036906020880190611457565b508351610dc9906037906020870190611457565b506038805460398054600160a060020a0319908116600160a060020a0397881617909155603a80549091169490951693909317909355601260ff199092169190911761010060a860020a031916610100338102919091179092556000805461ff0019169115159092021790555050565b6037805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561053a5780601f1061050f5761010080835404028352916020019161053a565b336000908152603460209081526040808320600160a060020a038616845290915281205481906109c4908463ffffffff61126e16565b603854600090610ee7906101009004600160a060020a0316611241565b15610f88576038546040805160e060020a634a393149028152336004820152600160a060020a03868116602483015260448201869052915161010090930490911691634a393149916064808201926020929091908290030181600087803b158015610f5157600080fd5b505af1158015610f65573d6000803e3d6000fd5b505050506040513d6020811015610f7b57600080fd5b50511515610f8857600080fd5b33600090815260336020526040902054610fa8908363ffffffff61126e16565b3360009081526033602052604080822092909255600160a060020a03851681522054610fda908363ffffffff61128516565b600160a060020a0384166000818152603360209081526040918290209390935580518581529051919233926000805160206115098339815191529281900390910190a350600192915050565b61103033826113d2565b6039546040805160e060020a6323b872dd028152336004820152306024820152604481018490529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561108d57600080fd5b505af11580156110a1573d6000803e3d6000fd5b505050506040513d60208110156110b757600080fd5b50511515610973576040805160e560020a62461bcd02815260206004820152602b60248201527f53656e64657220646f6573206e6f74206861766520656e6f7567682061707072604482015260a960020a6a37bb32b210333ab732399702606482015290519081900360840190fd5b603a54600160a060020a031681565b603a54600090600160a060020a03163314611196576040805160e560020a62461bcd0281526020600482015260166024820152605160020a7529b2b73232b9103737ba1030baba3437b934bd32b21702604482015290519081900360640190fd5b603954600160a060020a038681169116146111fb576040805160e560020a62461bcd02815260206004820152601f60248201527f546f6b656e2062726964676564206973206e6f74207850696e616b696f6e2e00604482015290519081900360640190fd5b5060843561120981856113d2565b5050505050565b603460209081526000928352604080842090915290825290205481565b6038546101009004600160a060020a031681565b600080600160a060020a038316151561125d5760009150611268565b823b90506000811191505b50919050565b6000808383111561127e57600080fd5b5050900390565b60008282018381101561129757600080fd5b9392505050565b6038546112b8906101009004600160a060020a0316611241565b15611359576038546040805160e060020a634a393149028152336004820152600060248201819052604482018590529151610100909304600160a060020a031692634a39314992606480840193602093929083900390910190829087803b15801561132257600080fd5b505af1158015611336573d6000803e3d6000fd5b505050506040513d602081101561134c57600080fd5b5051151561135957600080fd5b33600090815260336020526040902054611379908263ffffffff61126e16565b3360009081526033602052604090205560355461139c908263ffffffff61126e16565b60355560408051828152905160009133916000805160206115098339815191529181900360200190a350565b303b8015905b5090565b6035546113e5908263ffffffff61128516565b603555600160a060020a038216600090815260336020526040902054611411908263ffffffff61128516565b600160a060020a03831660008181526033602090815260408083209490945583518581529351929391926000805160206115098339815191529281900390910190a35050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061149857805160ff19168380011785556114c5565b828001600101855582156114c5579182015b828111156114c55782518255916020019190600101906114aa565b506113ce926114e59250905b808211156113ce57600081556001016114d1565b905600546f6b656e20636f6e74726f6c6c657220646f6573206e6f7420617070726f76ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a165627a7a723058201587f87863e1c5003d96e0c41e7261fd6959542b51393190aac915590295acb20029

Deployed ByteCode

0x6080604052600436106100f85763ffffffff60e060020a60003504166306fdde0381146100fd578063095ea7b31461018757806318160ddd146101bf57806323b872dd146101e65780632e1a7d4d14610210578063313ce5671461022a57806333e1cbda1461025557806339509351146102865780633cebb823146102aa57806370a08231146102cb5780638108022d146102ec5780638f15b4141461031057806395d89b41146103bd578063a457c2d7146103d2578063a9059cbb146103f6578063b6b55f251461041a578063c6328a4614610432578063db7af85414610447578063dd62ed3e14610478578063f77c47911461049f575b600080fd5b34801561010957600080fd5b506101126104b4565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561014c578181015183820152602001610134565b50505050905090810190601f1680156101795780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019357600080fd5b506101ab600160a060020a0360043516602435610542565b604080519115158252519081900360200190f35b3480156101cb57600080fd5b506101d461069c565b60408051918252519081900360200190f35b3480156101f257600080fd5b506101ab600160a060020a03600435811690602435166044356106a2565b34801561021c57600080fd5b5061022860043561087f565b005b34801561023657600080fd5b5061023f610976565b6040805160ff9092168252519081900360200190f35b34801561026157600080fd5b5061026a61097f565b60408051600160a060020a039092168252519081900360200190f35b34801561029257600080fd5b506101ab600160a060020a036004351660243561098e565b3480156102b657600080fd5b50610228600160a060020a0360043516610b1f565b3480156102d757600080fd5b506101d4600160a060020a0360043516610bbb565b3480156102f857600080fd5b50610228600435600160a060020a0360243516610bd6565b34801561031c57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261022894369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975050600160a060020a038535811696506020909501359094169350610ce692505050565b3480156103c957600080fd5b50610112610e39565b3480156103de57600080fd5b506101ab600160a060020a0360043516602435610e94565b34801561040257600080fd5b506101ab600160a060020a0360043516602435610eca565b34801561042657600080fd5b50610228600435611026565b34801561043e57600080fd5b5061026a611126565b34801561045357600080fd5b5061022860048035600160a060020a0316906024803591604435918201910135611135565b34801561048457600080fd5b506101d4600160a060020a0360043581169060243516611210565b3480156104ab57600080fd5b5061026a61122d565b6036805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561053a5780601f1061050f5761010080835404028352916020019161053a565b820191906000526020600020905b81548152906001019060200180831161051d57829003601f168201915b505050505081565b60385460009061055f906101009004600160a060020a0316611241565b15610647576038546040805160e060020a63da682aeb028152336004820152600160a060020a0386811660248301526044820186905291516101009093049091169163da682aeb916064808201926020929091908290030181600087803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b505050506040513d60208110156105f357600080fd5b50511515610647576040805160e560020a62461bcd02815260206004820152602260248201526000805160206114e9833981519152604482015260f160020a61329702606482015290519081900360840190fd5b336000818152603460209081526040808320600160a060020a0388168085529083529281902086905580518681529051929392600080516020611529833981519152929181900390910190a350600192915050565b60355481565b6038546000906106bf906101009004600160a060020a0316611241565b15610762576038546040805160e060020a634a393149028152600160a060020a038781166004830152868116602483015260448201869052915161010090930490911691634a393149916064808201926020929091908290030181600087803b15801561072b57600080fd5b505af115801561073f573d6000803e3d6000fd5b505050506040513d602081101561075557600080fd5b5051151561076257600080fd5b6038546101009004600160a060020a031633146107d257600160a060020a03841660009081526034602090815260408083203384529091529020546107ad908363ffffffff61126e16565b600160a060020a03851660009081526034602090815260408083203384529091529020555b600160a060020a0384166000908152603360205260409020546107fb908363ffffffff61126e16565b600160a060020a038086166000908152603360205260408082209390935590851681522054610830908363ffffffff61128516565b600160a060020a03808516600081815260336020908152604091829020949094558051868152905191939288169260008051602061150983398151915292918290030190a35060019392505050565b6108888161129e565b6039546040805160e060020a63a9059cbb028152336004820152602481018490529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156108df57600080fd5b505af11580156108f3573d6000803e3d6000fd5b505050506040513d602081101561090957600080fd5b50511515610973576040805160e560020a62461bcd02815260206004820152602660248201527f54686520607472616e73666572602066756e6374696f6e206d757374206e6f74604482015260d160020a65103330b4b61702606482015290519081900360840190fd5b50565b60385460ff1681565b603954600160a060020a031681565b336000908152603460209081526040808320600160a060020a038616845290915281205481906109c4908463ffffffff61128516565b6038549091506109e1906101009004600160a060020a0316611241565b15610ac9576038546040805160e060020a63da682aeb028152336004820152600160a060020a0387811660248301526044820185905291516101009093049091169163da682aeb916064808201926020929091908290030181600087803b158015610a4b57600080fd5b505af1158015610a5f573d6000803e3d6000fd5b505050506040513d6020811015610a7557600080fd5b50511515610ac9576040805160e560020a62461bcd02815260206004820152602260248201526000805160206114e9833981519152604482015260f160020a61329702606482015290519081900360840190fd5b336000818152603460209081526040808320600160a060020a0389168085529083529281902085905580518581529051929392600080516020611529833981519152929181900390910190a35060019392505050565b6038546101009004600160a060020a03163314610b93576040805160e560020a62461bcd02815260206004820152602160248201527f5468652063616c6c6572206973206e6f742074686520636f6e74726f6c6c6572604482015260f960020a601702606482015290519081900360840190fd5b60388054600160a060020a039092166101000261010060a860020a0319909216919091179055565b600160a060020a031660009081526033602052604090205490565b610bdf8261129e565b603954603a546040805160e060020a63095ea7b3028152600160a060020a039283166004820152602481018690529051919092169163095ea7b39160448083019260209291908290030181600087803b158015610c3b57600080fd5b505af1158015610c4f573d6000803e3d6000fd5b505050506040513d6020811015610c6557600080fd5b5050603a546039546040805160e060020a63ad58bdd1028152600160a060020a0392831660048201528483166024820152604481018690529051919092169163ad58bdd191606480830192600092919082900301818387803b158015610cca57600080fd5b505af1158015610cde573d6000803e3d6000fd5b505050505050565b60008054610100900460ff1680610d005750610d006113c8565b80610d0e575060005460ff16155b1515610d7e576040805160e560020a62461bcd02815260206004820152602e60248201527f436f6e747261637420696e7374616e63652068617320616c72656164792062656044820152609260020a6d195b881a5b9a5d1a585b1a5e995902606482015290519081900360840190fd5b5060008054600161010061ff00198316811760ff191691909117909255855191900460ff1690610db5906036906020880190611457565b508351610dc9906037906020870190611457565b506038805460398054600160a060020a0319908116600160a060020a0397881617909155603a80549091169490951693909317909355601260ff199092169190911761010060a860020a031916610100338102919091179092556000805461ff0019169115159092021790555050565b6037805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561053a5780601f1061050f5761010080835404028352916020019161053a565b336000908152603460209081526040808320600160a060020a038616845290915281205481906109c4908463ffffffff61126e16565b603854600090610ee7906101009004600160a060020a0316611241565b15610f88576038546040805160e060020a634a393149028152336004820152600160a060020a03868116602483015260448201869052915161010090930490911691634a393149916064808201926020929091908290030181600087803b158015610f5157600080fd5b505af1158015610f65573d6000803e3d6000fd5b505050506040513d6020811015610f7b57600080fd5b50511515610f8857600080fd5b33600090815260336020526040902054610fa8908363ffffffff61126e16565b3360009081526033602052604080822092909255600160a060020a03851681522054610fda908363ffffffff61128516565b600160a060020a0384166000818152603360209081526040918290209390935580518581529051919233926000805160206115098339815191529281900390910190a350600192915050565b61103033826113d2565b6039546040805160e060020a6323b872dd028152336004820152306024820152604481018490529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561108d57600080fd5b505af11580156110a1573d6000803e3d6000fd5b505050506040513d60208110156110b757600080fd5b50511515610973576040805160e560020a62461bcd02815260206004820152602b60248201527f53656e64657220646f6573206e6f74206861766520656e6f7567682061707072604482015260a960020a6a37bb32b210333ab732399702606482015290519081900360840190fd5b603a54600160a060020a031681565b603a54600090600160a060020a03163314611196576040805160e560020a62461bcd0281526020600482015260166024820152605160020a7529b2b73232b9103737ba1030baba3437b934bd32b21702604482015290519081900360640190fd5b603954600160a060020a038681169116146111fb576040805160e560020a62461bcd02815260206004820152601f60248201527f546f6b656e2062726964676564206973206e6f74207850696e616b696f6e2e00604482015290519081900360640190fd5b5060843561120981856113d2565b5050505050565b603460209081526000928352604080842090915290825290205481565b6038546101009004600160a060020a031681565b600080600160a060020a038316151561125d5760009150611268565b823b90506000811191505b50919050565b6000808383111561127e57600080fd5b5050900390565b60008282018381101561129757600080fd5b9392505050565b6038546112b8906101009004600160a060020a0316611241565b15611359576038546040805160e060020a634a393149028152336004820152600060248201819052604482018590529151610100909304600160a060020a031692634a39314992606480840193602093929083900390910190829087803b15801561132257600080fd5b505af1158015611336573d6000803e3d6000fd5b505050506040513d602081101561134c57600080fd5b5051151561135957600080fd5b33600090815260336020526040902054611379908263ffffffff61126e16565b3360009081526033602052604090205560355461139c908263ffffffff61126e16565b60355560408051828152905160009133916000805160206115098339815191529181900360200190a350565b303b8015905b5090565b6035546113e5908263ffffffff61128516565b603555600160a060020a038216600090815260336020526040902054611411908263ffffffff61128516565b600160a060020a03831660008181526033602090815260408083209490945583518581529351929391926000805160206115098339815191529281900390910190a35050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061149857805160ff19168380011785556114c5565b828001600101855582156114c5579182015b828111156114c55782518255916020019190600101906114aa565b506113ce926114e59250905b808211156113ce57600081556001016114d1565b905600546f6b656e20636f6e74726f6c6c657220646f6573206e6f7420617070726f76ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a165627a7a723058201587f87863e1c5003d96e0c41e7261fd6959542b51393190aac915590295acb20029