ETH Price: $3,387.62 (-1.45%)
Gas: 2 Gwei

Contract

0x8407dc57739bCDA7aA53Ca6F12F82F9d51c2F21E
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Deposit Eth For138104802021-12-15 15:12:21926 days ago1639581141IN
0x8407dc57...d51c2F21E
0.00114009 ETH0.002306180.35204504
0x60806040117246262021-01-25 11:42:341250 days ago1611574954IN
 Create: MainchainGatewayManager
0 ETH0.1864551374

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MainchainGatewayManager

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-04-28
*/

// File: @axie/contract-library/contracts/cryptography/ECVerify.sol

pragma solidity ^0.5.2;


library ECVerify {

  enum SignatureMode {
    EIP712,
    GETH,
    TREZOR
  }

  function recover(bytes32 _hash, bytes memory _signature) internal pure returns (address _signer) {
    return recover(_hash, _signature, 0);
  }

  // solium-disable-next-line security/no-assign-params
  function recover(bytes32 _hash, bytes memory _signature, uint256 _index) internal pure returns (address _signer) {
    require(_signature.length >= _index + 66);

    SignatureMode _mode = SignatureMode(uint8(_signature[_index]));
    bytes32 _r;
    bytes32 _s;
    uint8 _v;

    // solium-disable-next-line security/no-inline-assembly
    assembly {
      _r := mload(add(_signature, add(_index, 33)))
      _s := mload(add(_signature, add(_index, 65)))
      _v := and(255, mload(add(_signature, add(_index, 66))))
    }

    if (_v < 27) {
      _v += 27;
    }

    require(_v == 27 || _v == 28);

    if (_mode == SignatureMode.GETH) {
      _hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash));
    } else if (_mode == SignatureMode.TREZOR) {
      _hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n\x20", _hash));
    }

    return ecrecover(_hash, _v, _r, _s);
  }

  function ecverify(bytes32 _hash, bytes memory _signature, address _signer) internal pure returns (bool _valid) {
    return _signer == recover(_hash, _signature);
  }
}

// File: @axie/contract-library/contracts/math/SafeMath.sol

pragma solidity ^0.5.2;


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

  function sub(uint256 a, uint256 b) internal pure returns (uint256 c) {
    require(b <= a);
    return a - b;
  }

  function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
    if (a == 0) {
      return 0;
    }

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

  function div(uint256 a, uint256 b) internal pure returns (uint256 c) {
    // Since Solidity automatically asserts when dividing by 0,
    // but we only need it to revert.
    require(b > 0);
    return a / b;
  }

  function mod(uint256 a, uint256 b) internal pure returns (uint256 c) {
    // Same reason as `div`.
    require(b > 0);
    return a % b;
  }

  function ceilingDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
    return add(div(a, b), mod(a, b) > 0 ? 1 : 0);
  }

  function subU64(uint64 a, uint64 b) internal pure returns (uint64 c) {
    require(b <= a);
    return a - b;
  }

  function addU8(uint8 a, uint8 b) internal pure returns (uint8 c) {
    c = a + b;
    require(c >= a);
  }
}

// File: @axie/contract-library/contracts/token/erc20/IERC20.sol

pragma solidity ^0.5.2;


interface IERC20 {
  event Transfer(address indexed _from, address indexed _to, uint256 _value);
  event Approval(address indexed _owner, address indexed _spender, uint256 _value);

  function totalSupply() external view returns (uint256 _supply);
  function balanceOf(address _owner) external view returns (uint256 _balance);

  function approve(address _spender, uint256 _value) external returns (bool _success);
  function allowance(address _owner, address _spender) external view returns (uint256 _value);

  function transfer(address _to, uint256 _value) external returns (bool _success);
  function transferFrom(address _from, address _to, uint256 _value) external returns (bool _success);
}

// File: @axie/contract-library/contracts/token/erc20/IERC20Mintable.sol

pragma solidity ^0.5.2;

interface IERC20Mintable {
  function mint(address _to, uint256 _value) external returns (bool _success);
}

// File: @axie/contract-library/contracts/token/erc721/IERC721.sol

pragma solidity ^0.5.2;


interface IERC721 {
  event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
  event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
  event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

  function balanceOf(address _owner) external view returns (uint256 _balance);
  function ownerOf(uint256 _tokenId) external view returns (address _owner);

  function approve(address _to, uint256 _tokenId) external;
  function getApproved(uint256 _tokenId) external view returns (address _operator);

  function setApprovalForAll(address _operator, bool _approved) external;
  function isApprovedForAll(address _owner, address _operator) external view returns (bool _approved);

  function transferFrom(address _from, address _to, uint256 _tokenId) external;
  function safeTransferFrom(address _from, address _to, uint256 _tokenId) external;
  function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata _data) external;
}

// File: @axie/contract-library/contracts/token/erc721/IERC721Mintable.sol

pragma solidity ^0.5.2;


interface IERC721Mintable {
  function mint(address _to, uint256 _tokenId) external returns (bool);
  function mintNew(address _to) external returns (uint256 _tokenId);
}

// File: @axie/contract-library/contracts/util/AddressUtils.sol

pragma solidity ^0.5.2;


library AddressUtils {
  function toPayable(address _address) internal pure returns (address payable _payable) {
    return address(uint160(_address));
  }

  function isContract(address _address) internal view returns (bool _correct) {
    uint256 _size;
    // solium-disable-next-line security/no-inline-assembly
    assembly { _size := extcodesize(_address) }
    return _size > 0;
  }
}

// File: @axie/contract-library/contracts/token/erc20/ERC20.sol

pragma solidity ^0.5.2;




contract ERC20 is IERC20 {
  using SafeMath for uint256;

  uint256 public totalSupply;
  mapping (address => uint256) public balanceOf;
  mapping (address => mapping (address => uint256)) public allowance;

  function approve(address _spender, uint256 _value) public returns (bool _success) {
    allowance[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  function transfer(address _to, uint256 _value) public returns (bool _success) {
    require(_to != address(0));
    balanceOf[msg.sender] = balanceOf[msg.sender].sub(_value);
    balanceOf[_to] = balanceOf[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

  function transferFrom(address _from, address _to, uint256 _value) public returns (bool _success) {
    require(_to != address(0));
    balanceOf[_from] = balanceOf[_from].sub(_value);
    balanceOf[_to] = balanceOf[_to].add(_value);
    allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value);
    emit Transfer(_from, _to, _value);
    return true;
  }
}

// File: @axie/contract-library/contracts/token/erc20/IERC20Detailed.sol

pragma solidity ^0.5.2;


interface IERC20Detailed {
  function name() external view returns (string memory _name);
  function symbol() external view returns (string memory _symbol);
  function decimals() external view returns (uint8 _decimals);
}

// File: @axie/contract-library/contracts/token/erc20/ERC20Detailed.sol

pragma solidity ^0.5.2;




contract ERC20Detailed is ERC20, IERC20Detailed {
  string public name;
  string public symbol;
  uint8 public decimals;

  constructor(string memory _name, string memory _symbol, uint8 _decimals) public {
    name = _name;
    symbol = _symbol;
    decimals = _decimals;
  }
}

// File: @axie/contract-library/contracts/access/HasAdmin.sol

pragma solidity ^0.5.2;


contract HasAdmin {
  event AdminChanged(address indexed _oldAdmin, address indexed _newAdmin);
  event AdminRemoved(address indexed _oldAdmin);

  address public admin;

  modifier onlyAdmin {
    require(msg.sender == admin);
    _;
  }

  constructor() internal {
    admin = msg.sender;
    emit AdminChanged(address(0), admin);
  }

  function changeAdmin(address _newAdmin) external onlyAdmin {
    require(_newAdmin != address(0));
    emit AdminChanged(admin, _newAdmin);
    admin = _newAdmin;
  }

  function removeAdmin() external onlyAdmin {
    emit AdminRemoved(admin);
    admin = address(0);
  }
}

// File: @axie/contract-library/contracts/access/HasMinters.sol

pragma solidity ^0.5.2;



contract HasMinters is HasAdmin {
  event MinterAdded(address indexed _minter);
  event MinterRemoved(address indexed _minter);

  address[] public minters;
  mapping (address => bool) public minter;

  modifier onlyMinter {
    require(minter[msg.sender]);
    _;
  }

  function addMinters(address[] memory _addedMinters) public onlyAdmin {
    address _minter;

    for (uint256 i = 0; i < _addedMinters.length; i++) {
      _minter = _addedMinters[i];

      if (!minter[_minter]) {
        minters.push(_minter);
        minter[_minter] = true;
        emit MinterAdded(_minter);
      }
    }
  }

  function removeMinters(address[] memory _removedMinters) public onlyAdmin {
    address _minter;

    for (uint256 i = 0; i < _removedMinters.length; i++) {
      _minter = _removedMinters[i];

      if (minter[_minter]) {
        minter[_minter] = false;
        emit MinterRemoved(_minter);
      }
    }

    uint256 i = 0;

    while (i < minters.length) {
      _minter = minters[i];

      if (!minter[_minter]) {
        minters[i] = minters[minters.length - 1];
        delete minters[minters.length - 1];
        minters.length--;
      } else {
        i++;
      }
    }
  }

  function isMinter(address _addr) public view returns (bool) {
    return minter[_addr];
  }
}

// File: @axie/contract-library/contracts/token/erc20/ERC20Mintable.sol

pragma solidity ^0.5.2;




contract ERC20Mintable is HasMinters, ERC20 {
  function mint(address _to, uint256 _value) public onlyMinter returns (bool _success) {
    return _mint(_to, _value);
  }

  function _mint(address _to, uint256 _value) internal returns (bool success) {
    totalSupply = totalSupply.add(_value);
    balanceOf[_to] = balanceOf[_to].add(_value);
    emit Transfer(address(0), _to, _value);
    return true;
  }
}

// File: contracts/chain/mainchain/WETH.sol

pragma solidity ^0.5.17;




contract WETH is ERC20Detailed {

  event Deposit(
    address _sender,
    uint256 _value
  );

  event Withdrawal(
    address _sender,
    uint256 _value
  );

  constructor () ERC20Detailed("Wrapped Ether", "WETH", 18)
    public
  {}

  function deposit()
    external
    payable
  {
    balanceOf[msg.sender] += msg.value;

    emit Deposit(msg.sender, msg.value);
  }

  function withdraw(uint256 _wad)
    external
  {
    require(balanceOf[msg.sender] >= _wad);
    balanceOf[msg.sender] -= _wad;
    msg.sender.transfer(_wad);

    emit Withdrawal(msg.sender, _wad);
  }
}

// File: @axie/contract-library/contracts/proxy/ProxyStorage.sol

pragma solidity ^0.5.2;

/**
 * @title ProxyStorage
 * @dev Store the address of logic contact that the proxy should forward to.
 */
contract ProxyStorage is HasAdmin {
  address internal _proxyTo;
}

// File: @axie/contract-library/contracts/lifecycle/Pausable.sol

pragma solidity ^0.5.2;



contract Pausable is HasAdmin {
  event Paused();
  event Unpaused();

  bool public paused;

  modifier whenNotPaused() {
    require(!paused);
    _;
  }

  modifier whenPaused() {
    require(paused);
    _;
  }

  function pause() public onlyAdmin whenNotPaused {
    paused = true;
    emit Paused();
  }

  function unpause() public onlyAdmin whenPaused {
    paused = false;
    emit Unpaused();
  }
}

// File: contracts/chain/common/IValidator.sol

pragma solidity ^0.5.17;


contract IValidator {
  event ValidatorAdded(uint256 indexed _id, address indexed _validator);
  event ValidatorRemoved(uint256 indexed _id, address indexed _validator);
  event ThresholdUpdated(
    uint256 indexed _id,
    uint256 indexed _numerator,
    uint256 indexed _denominator,
    uint256 _previousNumerator,
    uint256 _previousDenominator
  );

  function isValidator(address _addr) public view returns (bool);
  function getValidators() public view returns (address[] memory _validators);

  function checkThreshold(uint256 _voteCount) public view returns (bool);
}

// File: contracts/chain/common/Validator.sol

pragma solidity ^0.5.17;




contract Validator is IValidator {
  using SafeMath for uint256;

  mapping(address => bool) validatorMap;
  address[] public validators;
  uint256 public validatorCount;

  uint256 public num;
  uint256 public denom;

  constructor(address[] memory _validators, uint256 _num, uint256 _denom)
    public
  {
    validators = _validators;
    validatorCount = _validators.length;

    for (uint256 _i = 0; _i < validatorCount; _i++) {
      address _validator = _validators[_i];
      validatorMap[_validator] = true;
    }

    num = _num;
    denom = _denom;
  }

  function isValidator(address _addr)
    public
    view
    returns (bool)
  {
    return validatorMap[_addr];
  }

  function getValidators()
    public
    view
    returns (address[] memory _validators)
  {
    _validators = validators;
  }

  function checkThreshold(uint256 _voteCount)
    public
    view
    returns (bool)
  {
    return _voteCount.mul(denom) >= num.mul(validatorCount);
  }

  function _addValidator(uint256 _id, address _validator)
    internal
  {
    require(!validatorMap[_validator]);

    validators.push(_validator);
    validatorMap[_validator] = true;
    validatorCount++;

    emit ValidatorAdded(_id, _validator);
  }

  function _removeValidator(uint256 _id, address _validator)
    internal
  {
    require(isValidator(_validator));

    uint256 _index;
    for (uint256 _i = 0; _i < validatorCount; _i++) {
      if (validators[_i] == _validator) {
        _index = _i;
        break;
      }
    }

    validatorMap[_validator] = false;
    validators[_index] = validators[validatorCount - 1];
    validators.pop();

    validatorCount--;

    emit ValidatorRemoved(_id, _validator);
  }

  function _updateQuorum(uint256 _id, uint256 _numerator, uint256 _denominator)
    internal
  {
    require(_numerator <= _denominator);
    uint256 _previousNumerator = num;
    uint256 _previousDenominator = denom;

    num = _numerator;
    denom = _denominator;

    emit ThresholdUpdated(
      _id,
      _numerator,
      _denominator,
      _previousNumerator,
      _previousDenominator
    );
  }
}

// File: contracts/chain/mainchain/MainchainValidator.sol

pragma solidity ^0.5.17;




/**
 * @title Validator
 * @dev Simple validator contract
 */
contract MainchainValidator is Validator, HasAdmin {
  uint256 nonce;

  constructor(
    address[] memory _validators,
    uint256 _num,
    uint256 _denom
  ) Validator(_validators, _num, _denom) public {
  }

  function addValidators(address[] calldata _validators) external onlyAdmin {
    for (uint256 _i; _i < _validators.length; ++_i) {
      _addValidator(nonce++, _validators[_i]);
    }
  }

  function removeValidator(address _validator) external onlyAdmin {
    _removeValidator(nonce++, _validator);
  }

  function updateQuorum(uint256 _numerator, uint256 _denominator) external onlyAdmin {
    _updateQuorum(nonce++, _numerator, _denominator);
  }
}

// File: contracts/chain/common/Registry.sol

pragma solidity ^0.5.17;



contract Registry is HasAdmin {

  event ContractAddressUpdated(
    string indexed _name,
    bytes32 indexed _code,
    address indexed _newAddress
  );

  event TokenMapped(
    address indexed _mainchainToken,
    address indexed _sidechainToken,
    uint32 _standard
  );

  string public constant GATEWAY = "GATEWAY";
  string public constant WETH_TOKEN = "WETH_TOKEN";
  string public constant VALIDATOR = "VALIDATOR";
  string public constant ACKNOWLEDGEMENT = "ACKNOWLEDGEMENT";

  struct TokenMapping {
    address mainchainToken;
    address sidechainToken;
    uint32 standard; // 20, 721 or any other standards
  }

  mapping(bytes32 => address) public contractAddresses;
  mapping(address => TokenMapping) public mainchainMap;
  mapping(address => TokenMapping) public sidechainMap;

  function getContract(string calldata _name)
    external
    view
    returns (address _address)
  {
    bytes32 _code = getCode(_name);
    _address = contractAddresses[_code];
    require(_address != address(0));
  }

  function isTokenMapped(address _token, uint32 _standard, bool _isMainchain)
    external
    view
    returns (bool)
  {
    TokenMapping memory _mapping = _getTokenMapping(_token, _isMainchain);

    return _mapping.mainchainToken != address(0) &&
      _mapping.sidechainToken != address(0) &&
      _mapping.standard == _standard;
  }

  function updateContract(string calldata _name, address _newAddress)
    external
    onlyAdmin
  {
    bytes32 _code = getCode(_name);
    contractAddresses[_code] = _newAddress;

    emit ContractAddressUpdated(_name, _code, _newAddress);
  }

  function mapToken(address _mainchainToken, address _sidechainToken, uint32 _standard)
    external
    onlyAdmin
  {
    TokenMapping memory _map = TokenMapping(
      _mainchainToken,
      _sidechainToken,
      _standard
    );

    mainchainMap[_mainchainToken] = _map;
    sidechainMap[_sidechainToken] = _map;

    emit TokenMapped(
      _mainchainToken,
      _sidechainToken,
      _standard
    );
  }

  function clearMapToken(address _mainchainToken, address _sidechainToken)
    external
    onlyAdmin
  {
    TokenMapping storage _mainchainMap = mainchainMap[_mainchainToken];
    _clearMapEntry(_mainchainMap);

    TokenMapping storage _sidechainMap = sidechainMap[_sidechainToken];
    _clearMapEntry(_sidechainMap);
  }

  function getMappedToken(
    address _token,
    bool _isMainchain
  )
    external
    view
  returns (
    address _mainchainToken,
    address _sidechainToken,
    uint32 _standard
  )
  {
    TokenMapping memory _mapping = _getTokenMapping(_token, _isMainchain);
    _mainchainToken = _mapping.mainchainToken;
    _sidechainToken = _mapping.sidechainToken;
    _standard = _mapping.standard;
  }

  function getCode(string memory _name)
    public
    pure
    returns (bytes32)
  {
    return keccak256(abi.encodePacked(_name));
  }

  function _getTokenMapping(
    address _token,
    bool isMainchain
  )
    internal
    view
    returns (TokenMapping memory _mapping)
  {
    if (isMainchain) {
      _mapping = mainchainMap[_token];
    } else {
      _mapping = sidechainMap[_token];
    }
  }

  function _clearMapEntry(TokenMapping storage _entry)
    internal
  {
    _entry.mainchainToken = address(0);
    _entry.sidechainToken = address(0);
    _entry.standard = 0;
  }
}

// File: contracts/chain/mainchain/MainchainGatewayStorage.sol

pragma solidity ^0.5.17;







/**
 * @title GatewayStorage
 * @dev Storage of deposit and withdraw information.
 */
contract MainchainGatewayStorage is ProxyStorage, Pausable {

  event TokenDeposited(
    uint256 indexed _depositId,
    address indexed _owner,
    address indexed _tokenAddress,
    address _sidechainAddress,
    uint32  _standard,
    uint256 _tokenNumber // ERC-20 amount or ERC721 tokenId
  );

  event TokenWithdrew(
    uint256 indexed _withdrawId,
    address indexed _owner,
    address indexed _tokenAddress,
    uint256 _tokenNumber
  );

  struct DepositEntry {
    address owner;
    address tokenAddress;
    address sidechainAddress;
    uint32  standard;
    uint256 tokenNumber;
  }

  struct WithdrawalEntry {
    address owner;
    address tokenAddress;
    uint256 tokenNumber;
  }

  Registry public registry;

  uint256 public depositCount;
  DepositEntry[] public deposits;
  mapping(uint256 => WithdrawalEntry) public withdrawals;

  function updateRegistry(address _registry) external onlyAdmin {
    registry = Registry(_registry);
  }
}

// File: contracts/chain/mainchain/MainchainGatewayManager.sol

pragma solidity ^0.5.17;











/**
 * @title MainchainGatewayManager
 * @dev Logic to handle deposits and withdrawl on Mainchain.
 */
contract MainchainGatewayManager is MainchainGatewayStorage {
  using AddressUtils for address;
  using SafeMath for uint256;
  using ECVerify for bytes32;

  modifier onlyMappedToken(address _token, uint32 _standard) {
    require(
      registry.isTokenMapped(_token, _standard, true),
      "MainchainGatewayManager: Token is not mapped"
    );
    _;
  }

  modifier onlyNewWithdrawal(uint256 _withdrawalId) {
    WithdrawalEntry storage _entry = withdrawals[_withdrawalId];
    require(_entry.owner == address(0) && _entry.tokenAddress == address(0));
    _;
  }

  // Should be able to withdraw from WETH
  function()
    external
    payable
  {}

  function depositEth()
    external
    whenNotPaused
    payable
    returns (uint256)
  {
    return depositEthFor(msg.sender);
  }

  function depositERC20(address _token, uint256 _amount)
    external
    whenNotPaused
    returns (uint256)
  {
    return depositERC20For(msg.sender, _token, _amount);
  }

  function depositERC721(address _token, uint256 _tokenId)
    external
    whenNotPaused
    returns (uint256)
  {
    return depositERC721For(msg.sender, _token, _tokenId);
  }

  function depositEthFor(address _owner)
    public
    whenNotPaused
    payable
    returns (uint256)
  {
    address _weth = registry.getContract(registry.WETH_TOKEN());
    WETH(_weth).deposit.value(msg.value)();
    return _createDepositEntry(_owner, _weth, 20, msg.value);
  }

  function depositERC20For(address _user, address _token, uint256 _amount)
    public
    whenNotPaused
    returns (uint256)
  {
    require(
      IERC20(_token).transferFrom(msg.sender, address(this), _amount),
      "MainchainGatewayManager: ERC-20 token transfer failed"
    );
    return _createDepositEntry(_user, _token, 20, _amount);
  }

  function depositERC721For(address _user, address _token, uint256 _tokenId)
    public
    whenNotPaused
    returns (uint256)
  {
    IERC721(_token).transferFrom(msg.sender, address(this), _tokenId);
    return _createDepositEntry(_user, _token, 721, _tokenId);
  }

  function depositBulkFor(
    address _user,
    address[] memory _tokens,
    uint256[] memory _tokenNumbers
  )
    public
    whenNotPaused
  {
    require(_tokens.length == _tokenNumbers.length);

    for (uint256 _i = 0; _i < _tokens.length; _i++) {
      address _token = _tokens[_i];
      uint256 _tokenNumber = _tokenNumbers[_i];
      (,, uint32 _standard) = registry.getMappedToken(_token, true);

      if (_standard == 20) {
        depositERC20For(_user, _token, _tokenNumber);
      } else if (_standard == 721) {
        depositERC721For(_user, _token, _tokenNumber);
      } else {
        revert("Token is not mapped or token type not supported");
      }
    }
  }

  function withdrawToken(
    uint256 _withdrawalId,
    address _token,
    uint256 _amount,
    bytes memory _signatures
  )
    public
    whenNotPaused
  {
    withdrawTokenFor(
      _withdrawalId,
      msg.sender,
      _token,
      _amount,
      _signatures
    );
  }

  function withdrawTokenFor(
    uint256 _withdrawalId,
    address _user,
    address _token,
    uint256 _amount,
    bytes memory _signatures
  )
    public
    whenNotPaused
  {
    (,, uint32 _tokenType) = registry.getMappedToken(_token, true);

    if (_tokenType == 20) {
      withdrawERC20For(
        _withdrawalId,
        _user,
        _token,
        _amount,
        _signatures
      );
    } else if (_tokenType == 721) {
      withdrawERC721For(
        _withdrawalId,
        _user,
        _token,
        _amount,
        _signatures
      );
    }
  }

  function withdrawERC20(
    uint256 _withdrawalId,
    address _token,
    uint256 _amount,
    bytes memory _signatures
  )
    public
    whenNotPaused
  {
    withdrawERC20For(
      _withdrawalId,
      msg.sender,
      _token,
      _amount,
      _signatures
    );
  }

  function withdrawERC20For(
    uint256 _withdrawalId,
    address _user,
    address _token,
    uint256 _amount,
    bytes memory _signatures
  )
    public
    whenNotPaused
    onlyMappedToken(_token, 20)
  {
    bytes32 _hash = keccak256(
      abi.encodePacked(
        "withdrawERC20",
        _withdrawalId,
        _user,
        _token,
        _amount
      )
    );

    require(verifySignatures(_hash, _signatures));

    if (_token == registry.getContract(registry.WETH_TOKEN())) {
      _withdrawETHFor(_user, _amount);
    } else {
      uint256 _gatewayBalance = IERC20(_token).balanceOf(address(this));

      if (_gatewayBalance < _amount) {
        require(
          IERC20Mintable(_token).mint(address(this), _amount.sub(_gatewayBalance)),
          "MainchainGatewayManager: Minting ERC20 token to gateway failed"
        );
      }

      require(IERC20(_token).transfer(_user, _amount), "Transfer failed");
    }

    _insertWithdrawalEntry(
      _withdrawalId,
      _user,
      _token,
      _amount
    );
  }

  function withdrawERC721(
    uint256 _withdrawalId,
    address _token,
    uint256 _tokenId,
    bytes memory _signatures
  )
    public
    whenNotPaused
  {
    withdrawERC721For(
      _withdrawalId,
      msg.sender,
      _token,
      _tokenId,
      _signatures
    );
  }

  function withdrawERC721For(
    uint256 _withdrawalId,
    address _user,
    address _token,
    uint256 _tokenId,
    bytes memory _signatures
  )
    public
    whenNotPaused
    onlyMappedToken(_token, 721)
  {
    bytes32 _hash = keccak256(
      abi.encodePacked(
        "withdrawERC721",
        _withdrawalId,
        _user,
        _token,
        _tokenId
      )
    );

    require(verifySignatures(_hash, _signatures));

    if (!_tryERC721TransferFrom(_token, address(this), _user, _tokenId)) {
      require(
        IERC721Mintable(_token).mint(_user, _tokenId),
        "MainchainGatewayManager: Minting ERC721 token to gateway failed"
      );
    }

    _insertWithdrawalEntry(_withdrawalId, _user, _token, _tokenId);
  }

  /**
   * @dev returns true if there is enough signatures from validators.
   */
  function verifySignatures(
    bytes32 _hash,
    bytes memory _signatures
  )
    public
    view
    returns (bool)
  {
    uint256 _signatureCount = _signatures.length.div(66);

    Validator _validator = Validator(registry.getContract(registry.VALIDATOR()));
    uint256 _validatorCount = 0;
    address _lastSigner = address(0);

    for (uint256 i = 0; i < _signatureCount; i++) {
      address _signer = _hash.recover(_signatures, i.mul(66));
      if (_validator.isValidator(_signer)) {
        _validatorCount++;
      }
      // Prevent duplication of signatures
      require(_signer > _lastSigner);
      _lastSigner = _signer;
    }

    return _validator.checkThreshold(_validatorCount);
  }

  function _createDepositEntry(
    address _owner,
    address _token,
    uint32 _standard,
    uint256 _number
  )
    internal
    onlyMappedToken(_token, _standard)
    returns (uint256 _depositId)
  {
    (,address _sidechainToken, uint32 _tokenStandard) = registry.getMappedToken(_token, true);
    require(_standard == _tokenStandard);

    DepositEntry memory _entry = DepositEntry(
      _owner,
      _token,
      _sidechainToken,
      _standard,
      _number
    );

    deposits.push(_entry);
    _depositId = depositCount++;

    emit TokenDeposited(
      _depositId,
      _owner,
      _token,
      _sidechainToken,
      _standard,
      _number
    );
  }

  function _insertWithdrawalEntry(
    uint256 _withdrawalId,
    address _owner,
    address _token,
    uint256 _number
  )
    internal
    onlyNewWithdrawal(_withdrawalId)
  {
    WithdrawalEntry memory _entry = WithdrawalEntry(
      _owner,
      _token,
      _number
    );

    withdrawals[_withdrawalId] = _entry;

    emit TokenWithdrew(_withdrawalId, _owner, _token, _number);
  }

  function _withdrawETHFor(
    address _user,
    uint256 _amount
  )
    internal
  {
    address _weth = registry.getContract(registry.WETH_TOKEN());
    WETH(_weth).withdraw(_amount);
    _user.toPayable().transfer(_amount);
  }

  // See more here https://blog.polymath.network/try-catch-in-solidity-handling-the-revert-exception-f53718f76047
  function _tryERC721TransferFrom(
    address _token,
    address _from,
    address _to,
    uint256 _tokenId
  )
    internal
    returns (bool)
  {
    (bool success,) = _token.call(
      abi.encodeWithSelector(
        IERC721(_token).transferFrom.selector, _from, _to, _tokenId
      )
    );
    return success;
  }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oldAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"_newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oldAdmin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_depositId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_tokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"_sidechainAddress","type":"address"},{"indexed":false,"internalType":"uint32","name":"_standard","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"_tokenNumber","type":"uint256"}],"name":"TokenDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_withdrawId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenNumber","type":"uint256"}],"name":"TokenWithdrew","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpaused","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_tokenNumbers","type":"uint256[]"}],"name":"depositBulkFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"depositCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositERC20","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositERC20For","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"depositERC721","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"depositERC721For","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"depositEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"depositEthFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deposits","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"sidechainAddress","type":"address"},{"internalType":"uint32","name":"standard","type":"uint32"},{"internalType":"uint256","name":"tokenNumber","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"registry","outputs":[{"internalType":"contract Registry","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"removeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_registry","type":"address"}],"name":"updateRegistry","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"verifySignatures","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_withdrawalId","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"withdrawERC20","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_withdrawalId","type":"uint256"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"withdrawERC20For","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_withdrawalId","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"withdrawERC721","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_withdrawalId","type":"uint256"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"withdrawERC721For","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_withdrawalId","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"withdrawToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_withdrawalId","type":"uint256"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"withdrawTokenFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawals","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenNumber","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

60806040819052600080546001600160a01b03191633178082556001600160a01b0316917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f908290a3612c35806100576000396000f3fe6080604052600436106101665760003560e01c80638456cb59116100d1578063a7616c3b1161008a578063c7a823e011610064578063c7a823e014610a3c578063d29a4bf614610af4578063eee3f07a14610b2d578063f851a44014610b5357610166565b8063a7616c3b146108c2578063ace77c1914610905578063b02c43d0146109d257610166565b80638456cb591461071357806385eb3a35146107285780638f2839701461076b57806397feb9261461079e578063993e1c42146107d75780639a202d47146108ad57610166565b80635a8143de116101235780635a8143de146103ec5780635c975abb146104c25780635cc07076146104eb57806367a1569b1461053f57806375af64561461060c5780637b103999146106e257610166565b80631a5da6c8146101685780632dfdf0b51461019b5780633afecb8a146101c25780633f4ba83a14610302578063439370b1146103175780634789dcb91461031f575b005b34801561017457600080fd5b506101666004803603602081101561018b57600080fd5b50356001600160a01b0316610b68565b3480156101a757600080fd5b506101b0610ba1565b60408051918252519081900360200190f35b3480156101ce57600080fd5b50610166600480360360608110156101e557600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561020f57600080fd5b82018360208201111561022157600080fd5b803590602001918460208302840111600160201b8311171561024257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561029157600080fd5b8201836020820111156102a357600080fd5b803590602001918460208302840111600160201b831117156102c457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610ba7945050505050565b34801561030e57600080fd5b50610166610d17565b6101b0610d7c565b34801561032b57600080fd5b506101666004803603608081101561034257600080fd5b8135916001600160a01b036020820135169160408201359190810190608081016060820135600160201b81111561037857600080fd5b82018360208201111561038a57600080fd5b803590602001918460018302840111600160201b831117156103ab57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610da4945050505050565b3480156103f857600080fd5b50610166600480360360a081101561040f57600080fd5b8135916001600160a01b03602082013581169260408301359091169160608101359181019060a081016080820135600160201b81111561044e57600080fd5b82018360208201111561046057600080fd5b803590602001918460018302840111600160201b8311171561048157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610dc8945050505050565b3480156104ce57600080fd5b506104d7610eae565b604080519115158252519081900360200190f35b3480156104f757600080fd5b506105156004803603602081101561050e57600080fd5b5035610ebe565b604080516001600160a01b0394851681529290931660208301528183015290519081900360600190f35b34801561054b57600080fd5b506101666004803603608081101561056257600080fd5b8135916001600160a01b036020820135169160408201359190810190608081016060820135600160201b81111561059857600080fd5b8201836020820111156105aa57600080fd5b803590602001918460018302840111600160201b831117156105cb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610eec945050505050565b34801561061857600080fd5b50610166600480360360a081101561062f57600080fd5b8135916001600160a01b03602082013581169260408301359091169160608101359181019060a081016080820135600160201b81111561066e57600080fd5b82018360208201111561068057600080fd5b803590602001918460018302840111600160201b831117156106a157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610f0c945050505050565b3480156106ee57600080fd5b506106f7611152565b604080516001600160a01b039092168252519081900360200190f35b34801561071f57600080fd5b50610166611161565b34801561073457600080fd5b506101b06004803603606081101561074b57600080fd5b506001600160a01b038135811691602081013590911690604001356111cd565b34801561077757600080fd5b506101666004803603602081101561078e57600080fd5b50356001600160a01b03166112b8565b3480156107aa57600080fd5b506101b0600480360360408110156107c157600080fd5b506001600160a01b03813516906020013561133d565b3480156107e357600080fd5b50610166600480360360a08110156107fa57600080fd5b8135916001600160a01b03602082013581169260408301359091169160608101359181019060a081016080820135600160201b81111561083957600080fd5b82018360208201111561084b57600080fd5b803590602001918460018302840111600160201b8311171561086c57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061136b945050505050565b3480156108b957600080fd5b50610166611910565b3480156108ce57600080fd5b506101b0600480360360608110156108e557600080fd5b506001600160a01b0381358116916020810135909116906040013561196f565b34801561091157600080fd5b506101666004803603608081101561092857600080fd5b8135916001600160a01b036020820135169160408201359190810190608081016060820135600160201b81111561095e57600080fd5b82018360208201111561097057600080fd5b803590602001918460018302840111600160201b8311171561099157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611a03945050505050565b3480156109de57600080fd5b506109fc600480360360208110156109f557600080fd5b5035611a27565b604080516001600160a01b0396871681529486166020860152929094168383015263ffffffff166060830152608082019290925290519081900360a00190f35b348015610a4857600080fd5b506104d760048036036040811015610a5f57600080fd5b81359190810190604081016020820135600160201b811115610a8057600080fd5b820183602082011115610a9257600080fd5b803590602001918460018302840111600160201b83111715610ab357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611a7c945050505050565b348015610b0057600080fd5b506101b060048036036040811015610b1757600080fd5b506001600160a01b038135169060200135611dfb565b6101b060048036036020811015610b4357600080fd5b50356001600160a01b0316611e20565b348015610b5f57600080fd5b506106f76120a6565b6000546001600160a01b03163314610b7f57600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60035481565b600154600160a01b900460ff1615610bbe57600080fd5b8051825114610bcc57600080fd5b60005b8251811015610d11576000838281518110610be657fe5b602002602001015190506000838381518110610bfe57fe5b60209081029190910101516002546040805163eb96fbcd60e01b81526001600160a01b038681166004830152600160248301529151939450600093919092169163eb96fbcd916044808301926060929190829003018186803b158015610c6357600080fd5b505afa158015610c77573d6000803e3d6000fd5b505050506040513d6060811015610c8d57600080fd5b50604001519050601463ffffffff82161415610cb457610cae8784846111cd565b50610d06565b8063ffffffff166102d11415610ccf57610cae87848461196f565b60405162461bcd60e51b815260040180806020018281038252602f815260200180612b93602f913960400191505060405180910390fd5b505050600101610bcf565b50505050565b6000546001600160a01b03163314610d2e57600080fd5b600154600160a01b900460ff16610d4457600080fd5b6001805460ff60a01b191690556040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600154600090600160a01b900460ff1615610d9657600080fd5b610d9f33611e20565b905090565b600154600160a01b900460ff1615610dbb57600080fd5b610d11843385858561136b565b600154600160a01b900460ff1615610ddf57600080fd5b6002546040805163eb96fbcd60e01b81526001600160a01b038681166004830152600160248301529151600093929092169163eb96fbcd91604480820192606092909190829003018186803b158015610e3757600080fd5b505afa158015610e4b573d6000803e3d6000fd5b505050506040513d6060811015610e6157600080fd5b50604001519050601463ffffffff82161415610e8957610e84868686868661136b565b610ea6565b8063ffffffff166102d11415610ea657610ea68686868686610f0c565b505050505050565b600154600160a01b900460ff1681565b6005602052600090815260409020805460018201546002909201546001600160a01b03918216929091169083565b600154600160a01b900460ff1615610f0357600080fd5b610d1184338585855b600154600160a01b900460ff1615610f2357600080fd5b60025460408051631abcf33d60e11b81526001600160a01b0380871660048301526102d16024830181905260016044840152925187949190911691633579e67a916064808301926020929190829003018186803b158015610f8357600080fd5b505afa158015610f97573d6000803e3d6000fd5b505050506040513d6020811015610fad57600080fd5b5051610fea5760405162461bcd60e51b815260040180806020018281038252602c815260200180612af4602c913960400191505060405180910390fd5b604080516d776974686472617745524337323160901b602080830191909152602e82018a90526bffffffffffffffffffffffff1960608a811b8216604e85015289901b1660628301526076808301889052835180840390910181526096909201909252805191012061105c8185611a7c565b61106557600080fd5b611071863089886120b5565b61113c57856001600160a01b03166340c10f1988876040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156110d557600080fd5b505af11580156110e9573d6000803e3d6000fd5b505050506040513d60208110156110ff57600080fd5b505161113c5760405162461bcd60e51b815260040180806020018281038252603f815260200180612bc2603f913960400191505060405180910390fd5b611148888888886121ad565b5050505050505050565b6002546001600160a01b031681565b6000546001600160a01b0316331461117857600080fd5b600154600160a01b900460ff161561118f57600080fd5b6001805460ff60a01b1916600160a01b1790556040517f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e75290600090a1565b600154600090600160a01b900460ff16156111e757600080fd5b604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b038516916323b872dd9160648083019260209291908290030181600087803b15801561123c57600080fd5b505af1158015611250573d6000803e3d6000fd5b505050506040513d602081101561126657600080fd5b50516112a35760405162461bcd60e51b8152600401808060200182810382526035815260200180612b5e6035913960400191505060405180910390fd5b6112b084846014856122a0565b949350505050565b6000546001600160a01b031633146112cf57600080fd5b6001600160a01b0381166112e257600080fd5b600080546040516001600160a01b03808516939216917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f91a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600154600090600160a01b900460ff161561135757600080fd5b6113623384846111cd565b90505b92915050565b600154600160a01b900460ff161561138257600080fd5b60025460408051631abcf33d60e11b81526001600160a01b03808716600483015260146024830181905260016044840152925187949190911691633579e67a916064808301926020929190829003018186803b1580156113e157600080fd5b505afa1580156113f5573d6000803e3d6000fd5b505050506040513d602081101561140b57600080fd5b50516114485760405162461bcd60e51b815260040180806020018281038252602c815260200180612af4602c913960400191505060405180910390fd5b604080516c07769746864726177455243323609c1b602080830191909152602d82018a90526bffffffffffffffffffffffff1960608a811b8216604d85015289901b166061830152607580830188905283518084039091018152609590920190925280519101206114b98185611a7c565b6114c257600080fd5b60025460408051630df49df560e21b815290516001600160a01b039092169163358177739183916337d277d491600480820192600092909190829003018186803b15801561150f57600080fd5b505afa158015611523573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561154c57600080fd5b8101908080516040519392919084600160201b82111561156b57600080fd5b90830190602082018581111561158057600080fd5b8251600160201b81118282018810171561159957600080fd5b82525081516020918201929091019080838360005b838110156115c65781810151838201526020016115ae565b50505050905090810190601f1680156115f35780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561164657818101518382015260200161162e565b50505050905090810190601f1680156116735780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561169057600080fd5b505afa1580156116a4573d6000803e3d6000fd5b505050506040513d60208110156116ba57600080fd5b50516001600160a01b03878116911614156116de576116d987866125e8565b61113c565b604080516370a0823160e01b815230600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b15801561172857600080fd5b505afa15801561173c573d6000803e3d6000fd5b505050506040513d602081101561175257600080fd5b5051905085811015611834576001600160a01b0387166340c10f193061177e898563ffffffff61288f16565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156117cd57600080fd5b505af11580156117e1573d6000803e3d6000fd5b505050506040513d60208110156117f757600080fd5b50516118345760405162461bcd60e51b815260040180806020018281038252603e815260200180612b20603e913960400191505060405180910390fd5b866001600160a01b031663a9059cbb89886040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561189457600080fd5b505af11580156118a8573d6000803e3d6000fd5b505050506040513d60208110156118be57600080fd5b5051611903576040805162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b50611148888888886121ad565b6000546001600160a01b0316331461192757600080fd5b600080546040516001600160a01b03909116917fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f91a2600080546001600160a01b0319169055565b600154600090600160a01b900460ff161561198957600080fd5b604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b038516916323b872dd91606480830192600092919082900301818387803b1580156119dd57600080fd5b505af11580156119f1573d6000803e3d6000fd5b505050506112b084846102d1856122a0565b600154600160a01b900460ff1615611a1a57600080fd5b610d118433858585610dc8565b60048181548110611a3457fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b900463ffffffff169085565b600080611a94604284516128a490919063ffffffff16565b6002546040805163393df8cb60e01b815290519293506000926001600160a01b0390921691633581777391839163393df8cb916004808201928892909190829003018186803b158015611ae657600080fd5b505afa158015611afa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611b2357600080fd5b8101908080516040519392919084600160201b821115611b4257600080fd5b908301906020820185811115611b5757600080fd5b8251600160201b811182820188101715611b7057600080fd5b82525081516020918201929091019080838360005b83811015611b9d578181015183820152602001611b85565b50505050905090810190601f168015611bca5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c1d578181015183820152602001611c05565b50505050905090810190601f168015611c4a5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015611c6757600080fd5b505afa158015611c7b573d6000803e3d6000fd5b505050506040513d6020811015611c9157600080fd5b50519050600080805b84811015611d7f576000611cc788611cb984604263ffffffff6128c316565b8b919063ffffffff6128eb16565b9050846001600160a01b031663facd743b826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611d1f57600080fd5b505afa158015611d33573d6000803e3d6000fd5b505050506040513d6020811015611d4957600080fd5b505115611d57576001909301925b826001600160a01b0316816001600160a01b031611611d7557600080fd5b9150600101611c9a565b50826001600160a01b031663dafae408836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611dc457600080fd5b505afa158015611dd8573d6000803e3d6000fd5b505050506040513d6020811015611dee57600080fd5b5051979650505050505050565b600154600090600160a01b900460ff1615611e1557600080fd5b61136233848461196f565b600154600090600160a01b900460ff1615611e3a57600080fd5b60025460408051630df49df560e21b815290516000926001600160a01b03169163358177739183916337d277d49160048083019288929190829003018186803b158015611e8657600080fd5b505afa158015611e9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611ec357600080fd5b8101908080516040519392919084600160201b821115611ee257600080fd5b908301906020820185811115611ef757600080fd5b8251600160201b811182820188101715611f1057600080fd5b82525081516020918201929091019080838360005b83811015611f3d578181015183820152602001611f25565b50505050905090810190601f168015611f6a5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611fbd578181015183820152602001611fa5565b50505050905090810190601f168015611fea5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561200757600080fd5b505afa15801561201b573d6000803e3d6000fd5b505050506040513d602081101561203157600080fd5b505160408051630d0e30db60e41b815290519192506001600160a01b0383169163d0e30db0913491600480830192600092919082900301818588803b15801561207957600080fd5b505af115801561208d573d6000803e3d6000fd5b505050505061209f83826014346122a0565b9392505050565b6000546001600160a01b031681565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000948594938a169392918291908083835b602083106121395780518252601f19909201916020918201910161211a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461219b576040519150601f19603f3d011682016040523d82523d6000602084013e6121a0565b606091505b5090979650505050505050565b600084815260056020526040902080548591906001600160a01b03161580156121e1575060018101546001600160a01b0316155b6121ea57600080fd5b6121f2612aa5565b50604080516060810182526001600160a01b0380881680835287821660208085018281528587018a815260008e815260058452889020875181549088166001600160a01b03199182161782559251600182018054919098169316929092179095559351600290940193909355845188815294519394909391928b927f86174ea401f083b9bb1bdebca3068f27fb023c7091365ed2a8a02b8d75cf0e529281900390910190a450505050505050565b60025460408051631abcf33d60e11b81526001600160a01b03808716600483015263ffffffff8616602483015260016044830152915160009387938793911691633579e67a91606480820192602092909190829003018186803b15801561230657600080fd5b505afa15801561231a573d6000803e3d6000fd5b505050506040513d602081101561233057600080fd5b505161236d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612af4602c913960400191505060405180910390fd5b6002546040805163eb96fbcd60e01b81526001600160a01b0389811660048301526001602483015291516000938493169163eb96fbcd916044808301926060929190829003018186803b1580156123c357600080fd5b505afa1580156123d7573d6000803e3d6000fd5b505050506040513d60608110156123ed57600080fd5b506020810151604090910151909250905063ffffffff8781169082161461241357600080fd5b61241b612ac5565b6040518060a001604052808b6001600160a01b031681526020018a6001600160a01b03168152602001846001600160a01b031681526020018963ffffffff1681526020018881525090506004819080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506080820151816003015550505060036000815480929190600101919050559550886001600160a01b03168a6001600160a01b0316877f72848855a2461abf0dd243723dfcc9163eec2ea5215469d101c0d9c9ef58940d868c8c60405180846001600160a01b03166001600160a01b031681526020018363ffffffff1663ffffffff168152602001828152602001935050505060405180910390a45050505050949350505050565b60025460408051630df49df560e21b815290516000926001600160a01b03169163358177739183916337d277d49160048083019288929190829003018186803b15801561263457600080fd5b505afa158015612648573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561267157600080fd5b8101908080516040519392919084600160201b82111561269057600080fd5b9083019060208201858111156126a557600080fd5b8251600160201b8111828201881017156126be57600080fd5b82525081516020918201929091019080838360005b838110156126eb5781810151838201526020016126d3565b50505050905090810190601f1680156127185780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561276b578181015183820152602001612753565b50505050905090810190601f1680156127985780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156127b557600080fd5b505afa1580156127c9573d6000803e3d6000fd5b505050506040513d60208110156127df57600080fd5b505160408051632e1a7d4d60e01b81526004810185905290519192506001600160a01b03831691632e1a7d4d9160248082019260009290919082900301818387803b15801561282d57600080fd5b505af1158015612841573d6000803e3d6000fd5b50505050612857836001600160a01b0316612aa2565b6001600160a01b03166108fc839081150290604051600060405180830381858888f19350505050158015610d11573d6000803e3d6000fd5b60008282111561289e57600080fd5b50900390565b60008082116128b257600080fd5b8183816128bb57fe5b049392505050565b6000826128d257506000611365565b50818102818382816128e057fe5b041461136557600080fd5b600081604201835110156128fe57600080fd5b600083838151811061290c57fe5b016020015160f81c600281111561291f57fe5b848401602181015160418201516042909201519293509160ff16601b81101561294657601b015b8060ff16601b148061295b57508060ff16601c145b61296457600080fd5b600184600281111561297257fe5b14156129ce578760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c01828152602001915050604051602081830303815290604052805190602001209750612a34565b60028460028111156129dc57fe5b1415612a34578760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a200000000000815250601b018281526020019150506040516020818303038152906040528051906020012097505b604080516000815260208082018084528b905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015612a8b573d6000803e3d6000fd5b5050604051601f1901519998505050505050505050565b90565b604080516060810182526000808252602082018190529181019190915290565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091529056fe4d61696e636861696e476174657761794d616e616765723a20546f6b656e206973206e6f74206d61707065644d61696e636861696e476174657761794d616e616765723a204d696e74696e6720455243323020746f6b656e20746f2067617465776179206661696c65644d61696e636861696e476174657761794d616e616765723a204552432d323020746f6b656e207472616e73666572206661696c6564546f6b656e206973206e6f74206d6170706564206f7220746f6b656e2074797065206e6f7420737570706f727465644d61696e636861696e476174657761794d616e616765723a204d696e74696e672045524337323120746f6b656e20746f2067617465776179206661696c6564a265627a7a7231582029d3448421279dd0d60222ed01650f8f655c2a56f9e21df340b52d2d8baff0bb64736f6c63430005110032

Deployed Bytecode

0x6080604052600436106101665760003560e01c80638456cb59116100d1578063a7616c3b1161008a578063c7a823e011610064578063c7a823e014610a3c578063d29a4bf614610af4578063eee3f07a14610b2d578063f851a44014610b5357610166565b8063a7616c3b146108c2578063ace77c1914610905578063b02c43d0146109d257610166565b80638456cb591461071357806385eb3a35146107285780638f2839701461076b57806397feb9261461079e578063993e1c42146107d75780639a202d47146108ad57610166565b80635a8143de116101235780635a8143de146103ec5780635c975abb146104c25780635cc07076146104eb57806367a1569b1461053f57806375af64561461060c5780637b103999146106e257610166565b80631a5da6c8146101685780632dfdf0b51461019b5780633afecb8a146101c25780633f4ba83a14610302578063439370b1146103175780634789dcb91461031f575b005b34801561017457600080fd5b506101666004803603602081101561018b57600080fd5b50356001600160a01b0316610b68565b3480156101a757600080fd5b506101b0610ba1565b60408051918252519081900360200190f35b3480156101ce57600080fd5b50610166600480360360608110156101e557600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561020f57600080fd5b82018360208201111561022157600080fd5b803590602001918460208302840111600160201b8311171561024257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561029157600080fd5b8201836020820111156102a357600080fd5b803590602001918460208302840111600160201b831117156102c457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610ba7945050505050565b34801561030e57600080fd5b50610166610d17565b6101b0610d7c565b34801561032b57600080fd5b506101666004803603608081101561034257600080fd5b8135916001600160a01b036020820135169160408201359190810190608081016060820135600160201b81111561037857600080fd5b82018360208201111561038a57600080fd5b803590602001918460018302840111600160201b831117156103ab57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610da4945050505050565b3480156103f857600080fd5b50610166600480360360a081101561040f57600080fd5b8135916001600160a01b03602082013581169260408301359091169160608101359181019060a081016080820135600160201b81111561044e57600080fd5b82018360208201111561046057600080fd5b803590602001918460018302840111600160201b8311171561048157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610dc8945050505050565b3480156104ce57600080fd5b506104d7610eae565b604080519115158252519081900360200190f35b3480156104f757600080fd5b506105156004803603602081101561050e57600080fd5b5035610ebe565b604080516001600160a01b0394851681529290931660208301528183015290519081900360600190f35b34801561054b57600080fd5b506101666004803603608081101561056257600080fd5b8135916001600160a01b036020820135169160408201359190810190608081016060820135600160201b81111561059857600080fd5b8201836020820111156105aa57600080fd5b803590602001918460018302840111600160201b831117156105cb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610eec945050505050565b34801561061857600080fd5b50610166600480360360a081101561062f57600080fd5b8135916001600160a01b03602082013581169260408301359091169160608101359181019060a081016080820135600160201b81111561066e57600080fd5b82018360208201111561068057600080fd5b803590602001918460018302840111600160201b831117156106a157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610f0c945050505050565b3480156106ee57600080fd5b506106f7611152565b604080516001600160a01b039092168252519081900360200190f35b34801561071f57600080fd5b50610166611161565b34801561073457600080fd5b506101b06004803603606081101561074b57600080fd5b506001600160a01b038135811691602081013590911690604001356111cd565b34801561077757600080fd5b506101666004803603602081101561078e57600080fd5b50356001600160a01b03166112b8565b3480156107aa57600080fd5b506101b0600480360360408110156107c157600080fd5b506001600160a01b03813516906020013561133d565b3480156107e357600080fd5b50610166600480360360a08110156107fa57600080fd5b8135916001600160a01b03602082013581169260408301359091169160608101359181019060a081016080820135600160201b81111561083957600080fd5b82018360208201111561084b57600080fd5b803590602001918460018302840111600160201b8311171561086c57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061136b945050505050565b3480156108b957600080fd5b50610166611910565b3480156108ce57600080fd5b506101b0600480360360608110156108e557600080fd5b506001600160a01b0381358116916020810135909116906040013561196f565b34801561091157600080fd5b506101666004803603608081101561092857600080fd5b8135916001600160a01b036020820135169160408201359190810190608081016060820135600160201b81111561095e57600080fd5b82018360208201111561097057600080fd5b803590602001918460018302840111600160201b8311171561099157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611a03945050505050565b3480156109de57600080fd5b506109fc600480360360208110156109f557600080fd5b5035611a27565b604080516001600160a01b0396871681529486166020860152929094168383015263ffffffff166060830152608082019290925290519081900360a00190f35b348015610a4857600080fd5b506104d760048036036040811015610a5f57600080fd5b81359190810190604081016020820135600160201b811115610a8057600080fd5b820183602082011115610a9257600080fd5b803590602001918460018302840111600160201b83111715610ab357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611a7c945050505050565b348015610b0057600080fd5b506101b060048036036040811015610b1757600080fd5b506001600160a01b038135169060200135611dfb565b6101b060048036036020811015610b4357600080fd5b50356001600160a01b0316611e20565b348015610b5f57600080fd5b506106f76120a6565b6000546001600160a01b03163314610b7f57600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60035481565b600154600160a01b900460ff1615610bbe57600080fd5b8051825114610bcc57600080fd5b60005b8251811015610d11576000838281518110610be657fe5b602002602001015190506000838381518110610bfe57fe5b60209081029190910101516002546040805163eb96fbcd60e01b81526001600160a01b038681166004830152600160248301529151939450600093919092169163eb96fbcd916044808301926060929190829003018186803b158015610c6357600080fd5b505afa158015610c77573d6000803e3d6000fd5b505050506040513d6060811015610c8d57600080fd5b50604001519050601463ffffffff82161415610cb457610cae8784846111cd565b50610d06565b8063ffffffff166102d11415610ccf57610cae87848461196f565b60405162461bcd60e51b815260040180806020018281038252602f815260200180612b93602f913960400191505060405180910390fd5b505050600101610bcf565b50505050565b6000546001600160a01b03163314610d2e57600080fd5b600154600160a01b900460ff16610d4457600080fd5b6001805460ff60a01b191690556040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d1693390600090a1565b600154600090600160a01b900460ff1615610d9657600080fd5b610d9f33611e20565b905090565b600154600160a01b900460ff1615610dbb57600080fd5b610d11843385858561136b565b600154600160a01b900460ff1615610ddf57600080fd5b6002546040805163eb96fbcd60e01b81526001600160a01b038681166004830152600160248301529151600093929092169163eb96fbcd91604480820192606092909190829003018186803b158015610e3757600080fd5b505afa158015610e4b573d6000803e3d6000fd5b505050506040513d6060811015610e6157600080fd5b50604001519050601463ffffffff82161415610e8957610e84868686868661136b565b610ea6565b8063ffffffff166102d11415610ea657610ea68686868686610f0c565b505050505050565b600154600160a01b900460ff1681565b6005602052600090815260409020805460018201546002909201546001600160a01b03918216929091169083565b600154600160a01b900460ff1615610f0357600080fd5b610d1184338585855b600154600160a01b900460ff1615610f2357600080fd5b60025460408051631abcf33d60e11b81526001600160a01b0380871660048301526102d16024830181905260016044840152925187949190911691633579e67a916064808301926020929190829003018186803b158015610f8357600080fd5b505afa158015610f97573d6000803e3d6000fd5b505050506040513d6020811015610fad57600080fd5b5051610fea5760405162461bcd60e51b815260040180806020018281038252602c815260200180612af4602c913960400191505060405180910390fd5b604080516d776974686472617745524337323160901b602080830191909152602e82018a90526bffffffffffffffffffffffff1960608a811b8216604e85015289901b1660628301526076808301889052835180840390910181526096909201909252805191012061105c8185611a7c565b61106557600080fd5b611071863089886120b5565b61113c57856001600160a01b03166340c10f1988876040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156110d557600080fd5b505af11580156110e9573d6000803e3d6000fd5b505050506040513d60208110156110ff57600080fd5b505161113c5760405162461bcd60e51b815260040180806020018281038252603f815260200180612bc2603f913960400191505060405180910390fd5b611148888888886121ad565b5050505050505050565b6002546001600160a01b031681565b6000546001600160a01b0316331461117857600080fd5b600154600160a01b900460ff161561118f57600080fd5b6001805460ff60a01b1916600160a01b1790556040517f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e75290600090a1565b600154600090600160a01b900460ff16156111e757600080fd5b604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b038516916323b872dd9160648083019260209291908290030181600087803b15801561123c57600080fd5b505af1158015611250573d6000803e3d6000fd5b505050506040513d602081101561126657600080fd5b50516112a35760405162461bcd60e51b8152600401808060200182810382526035815260200180612b5e6035913960400191505060405180910390fd5b6112b084846014856122a0565b949350505050565b6000546001600160a01b031633146112cf57600080fd5b6001600160a01b0381166112e257600080fd5b600080546040516001600160a01b03808516939216917f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f91a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600154600090600160a01b900460ff161561135757600080fd5b6113623384846111cd565b90505b92915050565b600154600160a01b900460ff161561138257600080fd5b60025460408051631abcf33d60e11b81526001600160a01b03808716600483015260146024830181905260016044840152925187949190911691633579e67a916064808301926020929190829003018186803b1580156113e157600080fd5b505afa1580156113f5573d6000803e3d6000fd5b505050506040513d602081101561140b57600080fd5b50516114485760405162461bcd60e51b815260040180806020018281038252602c815260200180612af4602c913960400191505060405180910390fd5b604080516c07769746864726177455243323609c1b602080830191909152602d82018a90526bffffffffffffffffffffffff1960608a811b8216604d85015289901b166061830152607580830188905283518084039091018152609590920190925280519101206114b98185611a7c565b6114c257600080fd5b60025460408051630df49df560e21b815290516001600160a01b039092169163358177739183916337d277d491600480820192600092909190829003018186803b15801561150f57600080fd5b505afa158015611523573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561154c57600080fd5b8101908080516040519392919084600160201b82111561156b57600080fd5b90830190602082018581111561158057600080fd5b8251600160201b81118282018810171561159957600080fd5b82525081516020918201929091019080838360005b838110156115c65781810151838201526020016115ae565b50505050905090810190601f1680156115f35780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561164657818101518382015260200161162e565b50505050905090810190601f1680156116735780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561169057600080fd5b505afa1580156116a4573d6000803e3d6000fd5b505050506040513d60208110156116ba57600080fd5b50516001600160a01b03878116911614156116de576116d987866125e8565b61113c565b604080516370a0823160e01b815230600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b15801561172857600080fd5b505afa15801561173c573d6000803e3d6000fd5b505050506040513d602081101561175257600080fd5b5051905085811015611834576001600160a01b0387166340c10f193061177e898563ffffffff61288f16565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156117cd57600080fd5b505af11580156117e1573d6000803e3d6000fd5b505050506040513d60208110156117f757600080fd5b50516118345760405162461bcd60e51b815260040180806020018281038252603e815260200180612b20603e913960400191505060405180910390fd5b866001600160a01b031663a9059cbb89886040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561189457600080fd5b505af11580156118a8573d6000803e3d6000fd5b505050506040513d60208110156118be57600080fd5b5051611903576040805162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b50611148888888886121ad565b6000546001600160a01b0316331461192757600080fd5b600080546040516001600160a01b03909116917fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f91a2600080546001600160a01b0319169055565b600154600090600160a01b900460ff161561198957600080fd5b604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b038516916323b872dd91606480830192600092919082900301818387803b1580156119dd57600080fd5b505af11580156119f1573d6000803e3d6000fd5b505050506112b084846102d1856122a0565b600154600160a01b900460ff1615611a1a57600080fd5b610d118433858585610dc8565b60048181548110611a3457fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b900463ffffffff169085565b600080611a94604284516128a490919063ffffffff16565b6002546040805163393df8cb60e01b815290519293506000926001600160a01b0390921691633581777391839163393df8cb916004808201928892909190829003018186803b158015611ae657600080fd5b505afa158015611afa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611b2357600080fd5b8101908080516040519392919084600160201b821115611b4257600080fd5b908301906020820185811115611b5757600080fd5b8251600160201b811182820188101715611b7057600080fd5b82525081516020918201929091019080838360005b83811015611b9d578181015183820152602001611b85565b50505050905090810190601f168015611bca5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c1d578181015183820152602001611c05565b50505050905090810190601f168015611c4a5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015611c6757600080fd5b505afa158015611c7b573d6000803e3d6000fd5b505050506040513d6020811015611c9157600080fd5b50519050600080805b84811015611d7f576000611cc788611cb984604263ffffffff6128c316565b8b919063ffffffff6128eb16565b9050846001600160a01b031663facd743b826040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611d1f57600080fd5b505afa158015611d33573d6000803e3d6000fd5b505050506040513d6020811015611d4957600080fd5b505115611d57576001909301925b826001600160a01b0316816001600160a01b031611611d7557600080fd5b9150600101611c9a565b50826001600160a01b031663dafae408836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611dc457600080fd5b505afa158015611dd8573d6000803e3d6000fd5b505050506040513d6020811015611dee57600080fd5b5051979650505050505050565b600154600090600160a01b900460ff1615611e1557600080fd5b61136233848461196f565b600154600090600160a01b900460ff1615611e3a57600080fd5b60025460408051630df49df560e21b815290516000926001600160a01b03169163358177739183916337d277d49160048083019288929190829003018186803b158015611e8657600080fd5b505afa158015611e9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611ec357600080fd5b8101908080516040519392919084600160201b821115611ee257600080fd5b908301906020820185811115611ef757600080fd5b8251600160201b811182820188101715611f1057600080fd5b82525081516020918201929091019080838360005b83811015611f3d578181015183820152602001611f25565b50505050905090810190601f168015611f6a5780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611fbd578181015183820152602001611fa5565b50505050905090810190601f168015611fea5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561200757600080fd5b505afa15801561201b573d6000803e3d6000fd5b505050506040513d602081101561203157600080fd5b505160408051630d0e30db60e41b815290519192506001600160a01b0383169163d0e30db0913491600480830192600092919082900301818588803b15801561207957600080fd5b505af115801561208d573d6000803e3d6000fd5b505050505061209f83826014346122a0565b9392505050565b6000546001600160a01b031681565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000948594938a169392918291908083835b602083106121395780518252601f19909201916020918201910161211a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461219b576040519150601f19603f3d011682016040523d82523d6000602084013e6121a0565b606091505b5090979650505050505050565b600084815260056020526040902080548591906001600160a01b03161580156121e1575060018101546001600160a01b0316155b6121ea57600080fd5b6121f2612aa5565b50604080516060810182526001600160a01b0380881680835287821660208085018281528587018a815260008e815260058452889020875181549088166001600160a01b03199182161782559251600182018054919098169316929092179095559351600290940193909355845188815294519394909391928b927f86174ea401f083b9bb1bdebca3068f27fb023c7091365ed2a8a02b8d75cf0e529281900390910190a450505050505050565b60025460408051631abcf33d60e11b81526001600160a01b03808716600483015263ffffffff8616602483015260016044830152915160009387938793911691633579e67a91606480820192602092909190829003018186803b15801561230657600080fd5b505afa15801561231a573d6000803e3d6000fd5b505050506040513d602081101561233057600080fd5b505161236d5760405162461bcd60e51b815260040180806020018281038252602c815260200180612af4602c913960400191505060405180910390fd5b6002546040805163eb96fbcd60e01b81526001600160a01b0389811660048301526001602483015291516000938493169163eb96fbcd916044808301926060929190829003018186803b1580156123c357600080fd5b505afa1580156123d7573d6000803e3d6000fd5b505050506040513d60608110156123ed57600080fd5b506020810151604090910151909250905063ffffffff8781169082161461241357600080fd5b61241b612ac5565b6040518060a001604052808b6001600160a01b031681526020018a6001600160a01b03168152602001846001600160a01b031681526020018963ffffffff1681526020018881525090506004819080600181540180825580915050906001820390600052602060002090600402016000909192909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506080820151816003015550505060036000815480929190600101919050559550886001600160a01b03168a6001600160a01b0316877f72848855a2461abf0dd243723dfcc9163eec2ea5215469d101c0d9c9ef58940d868c8c60405180846001600160a01b03166001600160a01b031681526020018363ffffffff1663ffffffff168152602001828152602001935050505060405180910390a45050505050949350505050565b60025460408051630df49df560e21b815290516000926001600160a01b03169163358177739183916337d277d49160048083019288929190829003018186803b15801561263457600080fd5b505afa158015612648573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561267157600080fd5b8101908080516040519392919084600160201b82111561269057600080fd5b9083019060208201858111156126a557600080fd5b8251600160201b8111828201881017156126be57600080fd5b82525081516020918201929091019080838360005b838110156126eb5781810151838201526020016126d3565b50505050905090810190601f1680156127185780820380516001836020036101000a031916815260200191505b506040525050506040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561276b578181015183820152602001612753565b50505050905090810190601f1680156127985780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156127b557600080fd5b505afa1580156127c9573d6000803e3d6000fd5b505050506040513d60208110156127df57600080fd5b505160408051632e1a7d4d60e01b81526004810185905290519192506001600160a01b03831691632e1a7d4d9160248082019260009290919082900301818387803b15801561282d57600080fd5b505af1158015612841573d6000803e3d6000fd5b50505050612857836001600160a01b0316612aa2565b6001600160a01b03166108fc839081150290604051600060405180830381858888f19350505050158015610d11573d6000803e3d6000fd5b60008282111561289e57600080fd5b50900390565b60008082116128b257600080fd5b8183816128bb57fe5b049392505050565b6000826128d257506000611365565b50818102818382816128e057fe5b041461136557600080fd5b600081604201835110156128fe57600080fd5b600083838151811061290c57fe5b016020015160f81c600281111561291f57fe5b848401602181015160418201516042909201519293509160ff16601b81101561294657601b015b8060ff16601b148061295b57508060ff16601c145b61296457600080fd5b600184600281111561297257fe5b14156129ce578760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c01828152602001915050604051602081830303815290604052805190602001209750612a34565b60028460028111156129dc57fe5b1415612a34578760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a200000000000815250601b018281526020019150506040516020818303038152906040528051906020012097505b604080516000815260208082018084528b905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015612a8b573d6000803e3d6000fd5b5050604051601f1901519998505050505050505050565b90565b604080516060810182526000808252602082018190529181019190915290565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091529056fe4d61696e636861696e476174657761794d616e616765723a20546f6b656e206973206e6f74206d61707065644d61696e636861696e476174657761794d616e616765723a204d696e74696e6720455243323020746f6b656e20746f2067617465776179206661696c65644d61696e636861696e476174657761794d616e616765723a204552432d323020746f6b656e207472616e73666572206661696c6564546f6b656e206973206e6f74206d6170706564206f7220746f6b656e2074797065206e6f7420737570706f727465644d61696e636861696e476174657761794d616e616765723a204d696e74696e672045524337323120746f6b656e20746f2067617465776179206661696c6564a265627a7a7231582029d3448421279dd0d60222ed01650f8f655c2a56f9e21df340b52d2d8baff0bb64736f6c63430005110032

Deployed Bytecode Sourcemap

20767:8862:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20434:105;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20434:105:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20434:105:0;-1:-1:-1;;;;;20434:105:0;;:::i;20306:27::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20306:27:0;;;:::i;:::-;;;;;;;;;;;;;;;;22900:705;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22900:705:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;22900:705:0;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;22900:705:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;22900:705:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;22900:705:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;22900:705:0;;;;;;;;-1:-1:-1;22900:705:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;22900:705:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;22900:705:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;22900:705:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;22900:705:0;;-1:-1:-1;22900:705:0;;-1:-1:-1;;;;;22900:705:0:i;11850:96::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11850:96:0;;;:::i;21449:139::-;;;:::i;24515:292::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24515:292:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;24515:292:0;;;-1:-1:-1;;;;;24515:292:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;24515:292:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;24515:292:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;24515:292:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;24515:292:0;;-1:-1:-1;24515:292:0;;-1:-1:-1;;;;;24515:292:0:i;23909:600::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23909:600:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;23909:600:0;;;-1:-1:-1;;;;;23909:600:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;23909:600:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;23909:600:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;23909:600:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;23909:600:0;;-1:-1:-1;23909:600:0;;-1:-1:-1;;;;;23909:600:0:i;11593:18::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11593:18:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;20373:54;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20373:54:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20373:54:0;;:::i;:::-;;;;-1:-1:-1;;;;;20373:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;25901:296;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25901:296:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;25901:296:0;;;-1:-1:-1;;;;;25901:296:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;25901:296:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;25901:296:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;25901:296:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;25901:296:0;;-1:-1:-1;25901:296:0;;-1:-1:-1;;;;;25901:296:0:i;26203:772::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26203:772:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;26203:772:0;;;-1:-1:-1;;;;;26203:772:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;26203:772:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;26203:772:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;26203:772:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;26203:772:0;;-1:-1:-1;26203:772:0;;-1:-1:-1;;;;;26203:772:0:i;20275:24::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20275:24:0;;;:::i;:::-;;;;-1:-1:-1;;;;;20275:24:0;;;;;;;;;;;;;;11750:94;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11750:94:0;;;:::i;22261:354::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22261:354:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;22261:354:0;;;;;;;;;;;;;;;;;:::i;8171:170::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8171:170:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8171:170:0;-1:-1:-1;;;;;8171:170:0;;:::i;21594:178::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21594:178:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;21594:178:0;;;;;;;;:::i;24813:1082::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24813:1082:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;24813:1082:0;;;-1:-1:-1;;;;;24813:1082:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;24813:1082:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;24813:1082:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;24813:1082:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;24813:1082:0;;-1:-1:-1;24813:1082:0;;-1:-1:-1;;;;;24813:1082:0:i;8347:104::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8347:104:0;;;:::i;22621:273::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22621:273:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;22621:273:0;;;;;;;;;;;;;;;;;:::i;23611:292::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23611:292:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;23611:292:0;;;-1:-1:-1;;;;;23611:292:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;23611:292:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;23611:292:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;23611:292:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;23611:292:0;;-1:-1:-1;23611:292:0;;-1:-1:-1;;;;;23611:292:0:i;20338:30::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20338:30:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20338:30:0;;:::i;:::-;;;;-1:-1:-1;;;;;20338:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27066:730;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27066:730:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;27066:730:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;27066:730:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;27066:730:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;27066:730:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;27066:730:0;;-1:-1:-1;27066:730:0;;-1:-1:-1;;;;;27066:730:0:i;21778:182::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21778:182:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;21778:182:0;;;;;;;;:::i;21966:289::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21966:289:0;-1:-1:-1;;;;;21966:289:0;;:::i;7967:20::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7967:20:0;;;:::i;20434:105::-;8042:5;;-1:-1:-1;;;;;8042:5:0;8028:10;:19;8020:28;;;;;;20503:8;:30;;-1:-1:-1;;;;;;20503:30:0;-1:-1:-1;;;;;20503:30:0;;;;;;;;;;20434:105::o;20306:27::-;;;;:::o;22900:705::-;11659:6;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;23084:13;:20;23066:7;:14;:38;23058:47;;;;;;23119:10;23114:486;23140:7;:14;23135:2;:19;23114:486;;;23171:14;23188:7;23196:2;23188:11;;;;;;;;;;;;;;23171:28;;23208:20;23231:13;23245:2;23231:17;;;;;;;;;;;;;;;;;;23281:8;;:37;;;-1:-1:-1;;;23281:37:0;;-1:-1:-1;;;;;23281:37:0;;;;;;;:8;:37;;;;;;23231:17;;-1:-1:-1;23261:16:0;;23281:8;;;;;:23;;:37;;;;;;;;;;;;;;:8;:37;;;5:2:-1;;;;30:1;27;20:12;5:2;23281:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;23281:37:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23281:37:0;;;;-1:-1:-1;23346:2:0;23333:15;;;;23329:264;;;23361:44;23377:5;23384:6;23392:12;23361:15;:44::i;:::-;;23329:264;;;23425:9;:16;;23438:3;23425:16;23421:172;;;23454:45;23471:5;23478:6;23486:12;23454:16;:45::i;23421:172::-;23526:57;;-1:-1:-1;;;23526:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23421:172;-1:-1:-1;;;23156:4:0;;23114:486;;;;22900:705;;;:::o;11850:96::-;8042:5;;-1:-1:-1;;;;;8042:5:0;8028:10;:19;8020:28;;;;;;11723:6;;-1:-1:-1;;;11723:6:0;;;;11715:15;;;;;;11904:6;:14;;-1:-1:-1;;;;11904:14:0;;;11930:10;;;;11913:5;;11930:10;11850:96::o;21449:139::-;11659:6;;21531:7;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;21557:25;21571:10;21557:13;:25::i;:::-;21550:32;;21449:139;:::o;24515:292::-;11659:6;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;24686:115;24711:13;24733:10;24752:6;24767:7;24783:11;24686:16;:115::i;23909:600::-;11659:6;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;24128:8;;:37;;;-1:-1:-1;;;24128:37:0;;-1:-1:-1;;;;;24128:37:0;;;;;;;:8;:37;;;;;;24107:17;;24128:8;;;;;:23;;:37;;;;;;;;;;;;;;;:8;:37;;;5:2:-1;;;;30:1;27;20:12;5:2;24128:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;24128:37:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24128:37:0;;;;-1:-1:-1;24192:2:0;24178:16;;;;24174:330;;;24205:122;24232:13;24256:5;24272:6;24289:7;24307:11;24205:16;:122::i;:::-;24174:330;;;24345:10;:17;;24359:3;24345:17;24341:163;;;24373:123;24401:13;24425:5;24441:6;24458:7;24476:11;24373:17;:123::i;:::-;11673:1;23909:600;;;;;:::o;11593:18::-;;;-1:-1:-1;;;11593:18:0;;;;;:::o;20373:54::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20373:54:0;;;;;;;;;:::o;25901:296::-;11659:6;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;26074:117;26100:13;26122:10;26141:6;26156:8;26173:11;26203:772;11659:6;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;21013:8;;:47;;;-1:-1:-1;;;21013:47:0;;-1:-1:-1;;;;;21013:47:0;;;;;;;26418:3;21013:47;;;;;;:8;:47;;;;;;26410:6;;21013:8;;;;;:22;;:47;;;;;;;;;;;;;;:8;:47;;;5:2:-1;;;;30:1;27;20:12;5:2;21013:47:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21013:47:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21013:47:0;20997:125;;;;-1:-1:-1;;;20997:125:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26467:128;;;-1:-1:-1;;;26467:128:0;;;;;;;;;;;;;;-1:-1:-1;;26467:128:0;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;26467:128:0;;;;;;;26449:153;;;;;26619:36;26449:153;26643:11;26619:16;:36::i;:::-;26611:45;;;;;;26670:62;26693:6;26709:4;26716:5;26723:8;26670:22;:62::i;:::-;26665:234;;26777:6;-1:-1:-1;;;;;26761:28:0;;26790:5;26797:8;26761:45;;;;;;;;;;;;;-1:-1:-1;;;;;26761:45:0;-1:-1:-1;;;;;26761:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26761:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;26761:45:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;26761:45:0;26743:148;;;;-1:-1:-1;;;26743:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26907:62;26930:13;26945:5;26952:6;26960:8;26907:22;:62::i;:::-;21129:1;11673;;26203:772;;;;;:::o;20275:24::-;;;-1:-1:-1;;;;;20275:24:0;;:::o;11750:94::-;8042:5;;-1:-1:-1;;;;;8042:5:0;8028:10;:19;8020:28;;;;;;11659:6;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;11814:4;11805:13;;-1:-1:-1;;;;11805:13:0;-1:-1:-1;;;11805:13:0;;;11830:8;;;;11805:13;;11830:8;11750:94::o;22261:354::-;11659:6;;22379:7;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;22414:63;;;-1:-1:-1;;;22414:63:0;;22442:10;22414:63;;;;22462:4;22414:63;;;;;;;;;;;;-1:-1:-1;;;;;22414:27:0;;;;;:63;;;;;;;;;;;;;;-1:-1:-1;22414:27:0;:63;;;5:2:-1;;;;30:1;27;20:12;5:2;22414:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22414:63:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22414:63:0;22398:150;;;;-1:-1:-1;;;22398:150:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22562:47;22582:5;22589:6;22597:2;22601:7;22562:19;:47::i;:::-;22555:54;22261:354;-1:-1:-1;;;;22261:354:0:o;8171:170::-;8042:5;;-1:-1:-1;;;;;8042:5:0;8028:10;:19;8020:28;;;;;;-1:-1:-1;;;;;8245:23:0;;8237:32;;;;;;8294:5;;;8281:30;;-1:-1:-1;;;;;8281:30:0;;;;8294:5;;;8281:30;;;8318:5;:17;;-1:-1:-1;;;;;;8318:17:0;-1:-1:-1;;;;;8318:17:0;;;;;;;;;;8171:170::o;21594:178::-;11659:6;;21696:7;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;21722:44;21738:10;21750:6;21758:7;21722:15;:44::i;:::-;21715:51;;11673:1;21594:178;;;;:::o;24813:1082::-;11659:6;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;21013:8;;:47;;;-1:-1:-1;;;21013:47:0;;-1:-1:-1;;;;;21013:47:0;;;;;;;25026:2;21013:47;;;;;;:8;:47;;;;;;25018:6;;21013:8;;;;;:22;;:47;;;;;;;;;;;;;;:8;:47;;;5:2:-1;;;;30:1;27;20:12;5:2;21013:47:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21013:47:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21013:47:0;20997:125;;;;-1:-1:-1;;;20997:125:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25074:126;;;-1:-1:-1;;;25074:126:0;;;;;;;;;;;;;;-1:-1:-1;;25074:126:0;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;25074:126:0;;;;;;;25056:151;;;;;25224:36;25056:151;25248:11;25224:16;:36::i;:::-;25216:45;;;;;;25284:8;;25305:21;;;-1:-1:-1;;;25305:21:0;;;;-1:-1:-1;;;;;25284:8:0;;;;:20;;:8;;25305:19;;:21;;;;;25284:8;;25305:21;;;;;;;;25284:8;25305:21;;;5:2:-1;;;;30:1;27;20:12;5:2;25305:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25305:21:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;25305:21:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;25305:21:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;-1:-1;;;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;25305:21:0;;420:4:-1;411:14;;;;25305:21:0;;;;;411:14:-1;25305:21:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;25305:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25284:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;25284:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25284:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25284:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25284:43:0;-1:-1:-1;;;;;25274:53:0;;;;;;25270:515;;;25338:31;25354:5;25361:7;25338:15;:31::i;:::-;25270:515;;;25418:39;;;-1:-1:-1;;;25418:39:0;;25451:4;25418:39;;;;;;25392:23;;-1:-1:-1;;;;;25418:24:0;;;;;:39;;;;;;;;;;;;;;;:24;:39;;;5:2:-1;;;;30:1;27;20:12;5:2;25418:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25418:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25418:39:0;;-1:-1:-1;25472:25:0;;;25468:232;;;-1:-1:-1;;;;;25530:27:0;;;25566:4;25573:28;:7;25585:15;25573:28;:11;:28;:::i;:::-;25530:72;;;;;;;;;;;;;-1:-1:-1;;;;;25530:72:0;-1:-1:-1;;;;;25530:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25530:72:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25530:72:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25530:72:0;25510:180;;;;-1:-1:-1;;;25510:180:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25725:6;-1:-1:-1;;;;;25718:23:0;;25742:5;25749:7;25718:39;;;;;;;;;;;;;-1:-1:-1;;;;;25718:39:0;-1:-1:-1;;;;;25718:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25718:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25718:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25718:39:0;25710:67;;;;;-1:-1:-1;;;25710:67:0;;;;;;;;;;;;-1:-1:-1;;;25710:67:0;;;;;;;;;;;;;;;25270:515;25793:96;25824:13;25846:5;25860:6;25875:7;25793:22;:96::i;8347:104::-;8042:5;;-1:-1:-1;;;;;8042:5:0;8028:10;:19;8020:28;;;;;;8414:5;;;8401:19;;-1:-1:-1;;;;;8414:5:0;;;;8401:19;;;8443:1;8427:18;;-1:-1:-1;;;;;;8427:18:0;;;8347:104::o;22621:273::-;11659:6;;22741:7;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;22760:65;;;-1:-1:-1;;;22760:65:0;;22789:10;22760:65;;;;22809:4;22760:65;;;;;;;;;;;;-1:-1:-1;;;;;22760:28:0;;;;;:65;;;;;-1:-1:-1;;22760:65:0;;;;;;;-1:-1:-1;22760:28:0;:65;;;5:2:-1;;;;30:1;27;20:12;5:2;22760:65:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22760:65:0;;;;22839:49;22859:5;22866:6;22874:3;22879:8;22839:19;:49::i;23611:292::-;11659:6;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;23782:115;23807:13;23829:10;23848:6;23863:7;23879:11;23782:16;:115::i;20338:30::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20338:30:0;;;;-1:-1:-1;20338:30:0;;;;;;;;-1:-1:-1;;;20338:30:0;;;;;;:::o;27066:730::-;27184:4;27200:23;27226:26;27249:2;27226:11;:18;:22;;:26;;;;:::i;:::-;27294:8;;27315:20;;;-1:-1:-1;;;27315:20:0;;;;27200:52;;-1:-1:-1;27261:20:0;;-1:-1:-1;;;;;27294:8:0;;;;:20;;:8;;27315:18;;:20;;;;;27261;;27315;;;;;;;;27294:8;27315:20;;;5:2:-1;;;;30:1;27;20:12;5:2;27315:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27315:20:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;27315:20:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;27315:20:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;-1:-1;;;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;27315:20:0;;420:4:-1;411:14;;;;27315:20:0;;;;;411:14:-1;27315:20:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;27315:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27294:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;27294:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27294:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27294:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27294:42:0;;-1:-1:-1;27344:23:0;;;27419:314;27443:15;27439:1;:19;27419:314;;;27474:15;27492:37;27506:11;27519:9;:1;27525:2;27519:9;:5;:9;:::i;:::-;27492:5;;:37;;:13;:37;:::i;:::-;27474:55;;27542:10;-1:-1:-1;;;;;27542:22:0;;27565:7;27542:31;;;;;;;;;;;;;-1:-1:-1;;;;;27542:31:0;-1:-1:-1;;;;;27542:31:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27542:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27542:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27542:31:0;27538:75;;;27586:17;;;;;27538:75;27683:11;-1:-1:-1;;;;;27673:21:0;:7;-1:-1:-1;;;;;27673:21:0;;27665:30;;;;;;27718:7;-1:-1:-1;27460:3:0;;27419:314;;;;27748:10;-1:-1:-1;;;;;27748:25:0;;27774:15;27748:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27748:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27748:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27748:42:0;;27066:730;-1:-1:-1;;;;;;;27066:730:0:o;21778:182::-;11659:6;;21882:7;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;21908:46;21925:10;21937:6;21945:8;21908:16;:46::i;21966:289::-;11659:6;;22063:7;;-1:-1:-1;;;11659:6:0;;;;11658:7;11650:16;;;;;;22098:8;;22119:21;;;-1:-1:-1;;;22119:21:0;;;;22082:13;;-1:-1:-1;;;;;22098:8:0;;:20;;:8;;22119:19;;:21;;;;;22082:13;;22119:21;;;;;;;22098:8;22119:21;;;5:2:-1;;;;30:1;27;20:12;5:2;22119:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22119:21:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;22119:21:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;22119:21:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;-1:-1;;;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;22119:21:0;;420:4:-1;411:14;;;;22119:21:0;;;;;411:14:-1;22119:21:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;22119:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22098:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;22098:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22098:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22098:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22098:43:0;22148:38;;;-1:-1:-1;;;22148:38:0;;;;22098:43;;-1:-1:-1;;;;;;22148:19:0;;;;;22174:9;;22148:38;;;;;;;;;;;;;;22174:9;22148:19;:38;;;5:2:-1;;;;30:1;27;20:12;5:2;22148:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22148:38:0;;;;;22200:49;22220:6;22228:5;22235:2;22239:9;22200:19;:49::i;:::-;22193:56;21966:289;-1:-1:-1;;;21966:289:0:o;7967:20::-;;;-1:-1:-1;;;;;7967:20:0;;:::o;29290:336::-;29491:101;;;-1:-1:-1;;;;;29491:101:0;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;29491:101:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;29471:128:0;;;;29437:4;;;;29471:11;;;;29491:101;29471:128;;;25:18:-1;29471:128:0;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;29471:128:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;29453:146:0;;29290:336;-1:-1:-1;;;;;;;29290:336:0:o;28516:408::-;21199:30;21232:26;;;:11;:26;;;;;21273:12;;28682:13;;21232:26;-1:-1:-1;;;;;21273:12:0;:26;:63;;;;-1:-1:-1;21303:19:0;;;;-1:-1:-1;;;;;21303:19:0;:33;21273:63;21265:72;;;;;;28707:29;;:::i;:::-;-1:-1:-1;28739:68:0;;;;;;;;-1:-1:-1;;;;;28739:68:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28816:26:0;;;:11;:26;;;;;:35;;;;;;;-1:-1:-1;;;;;;28816:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28865:53;;;;;;;28739:68;;;;;;28828:13;;28865:53;;;;;;;;;;21344:1;28516:408;;;;;;:::o;27802:708::-;21013:8;;:47;;;-1:-1:-1;;;21013:47:0;;-1:-1:-1;;;;;21013:47:0;;;;;;;;;;;;;;:8;:47;;;;;;27991:18;;27958:6;;27966:9;;21013:8;;;:22;;:47;;;;;;;;;;;;;;;:8;:47;;;5:2:-1;;;;30:1;27;20:12;5:2;21013:47:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21013:47:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21013:47:0;20997:125;;;;-1:-1:-1;;;20997:125:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28073:8;;:37;;;-1:-1:-1;;;28073:37:0;;-1:-1:-1;;;;;28073:37:0;;;;;;;:8;:37;;;;;;28023:23;;;;28073:8;;:23;;:37;;;;;;;;;;;;;;:8;:37;;;5:2:-1;;;;30:1;27;20:12;5:2;28073:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28073:37:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28073:37:0;;;;;;;;;;;-1:-1:-1;28073:37:0;-1:-1:-1;28125:27:0;;;;;;;;28117:36;;;;;;28162:26;;:::i;:::-;28191:107;;;;;;;;28212:6;-1:-1:-1;;;;;28191:107:0;;;;;28227:6;-1:-1:-1;;;;;28191:107:0;;;;;28242:15;-1:-1:-1;;;;;28191:107:0;;;;;28266:9;28191:107;;;;;;28284:7;28191:107;;;28162:136;;28307:8;28321:6;28307:21;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;28307:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28307:21:0;;;;;-1:-1:-1;;;;;28307:21:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28307:21:0;;;;;-1:-1:-1;;;;;28307:21:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28307:21:0;;;;;-1:-1:-1;;;;;28307:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28348:12;;:14;;;;;;;;;;;;28335:27;;28433:6;-1:-1:-1;;;;;28376:128:0;28418:6;-1:-1:-1;;;;;28376:128:0;28399:10;28376:128;28448:15;28472:9;28490:7;28376:128;;;;-1:-1:-1;;;;;28376:128:0;-1:-1:-1;;;;;28376:128:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21129:1;;;27802:708;;;;;;;;:::o;28930:239::-;29042:8;;29063:21;;;-1:-1:-1;;;29063:21:0;;;;29026:13;;-1:-1:-1;;;;;29042:8:0;;:20;;:8;;29063:19;;:21;;;;;29026:13;;29063:21;;;;;;;29042:8;29063:21;;;5:2:-1;;;;30:1;27;20:12;5:2;29063:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29063:21:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;29063:21:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;29063:21:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;-1:-1;;;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;29063:21:0;;420:4:-1;411:14;;;;29063:21:0;;;;;411:14:-1;29063:21:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;29063:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29042:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;29042:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29042:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29042:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;29042:43:0;29092:29;;;-1:-1:-1;;;29092:29:0;;;;;;;;;;29042:43;;-1:-1:-1;;;;;;29092:20:0;;;;;:29;;;;;-1:-1:-1;;29092:29:0;;;;;;;;-1:-1:-1;29092:20:0;:29;;;5:2:-1;;;;30:1;27;20:12;5:2;29092:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29092:29:0;;;;29128:17;:5;-1:-1:-1;;;;;29128:15:0;;:17::i;:::-;-1:-1:-1;;;;;29128:26:0;:35;29155:7;29128:35;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;1758:116:0;1816:9;1847:1;1842;:6;;1834:15;;;;;;-1:-1:-1;1863:5:0;;;1758:116::o;2048:219::-;2106:9;2240:1;2236;:5;2228:14;;;;;;2260:1;2256;:5;;;;;;;2048:219;-1:-1:-1;;;2048:219:0:o;1880:162::-;1938:9;1960:6;1956:37;;-1:-1:-1;1984:1:0;1977:8;;1956:37;-1:-1:-1;2005:5:0;;;2009:1;2005;:5;:1;2025:5;;;;;:10;2017:19;;;;;400:944;496:15;549:6;558:2;549:11;528:10;:17;:32;;520:41;;;;;;570:19;612:10;623:6;612:18;;;;;;;;;;;;;;592:40;;;;;;;;781:32;;;809:2;781:32;;775:39;862:2;834:32;;828:39;924:2;896:32;;;890:39;570:62;;-1:-1:-1;775:39:0;885:3;881:49;954:2;949:7;;945:38;;;973:2;967:8;945:38;999:2;:8;;1005:2;999:8;:20;;;;1011:2;:8;;1017:2;1011:8;999:20;991:29;;;;;;1042:18;1033:5;:27;;;;;;;;;1029:266;;;1142:5;1089:59;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;1089:59:0;;;1079:70;;;;;;1071:78;;1029:266;;;1176:20;1167:5;:29;;;;;;;;;1163:132;;;1280:5;1225:61;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;1225:61:0;;;1215:72;;;;;;1207:80;;1163:132;1310:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1310:28:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;1310:28:0;;-1:-1:-1;;1310:28:0;;;400:944;-1:-1:-1;;;;;;;;;400:944:0:o;5399:132::-;5515:8;5399:132::o;20767:8862::-;;;;;;;;;-1:-1:-1;20767:8862:0;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;-1:-1:-1;20767:8862:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

bzzr://29d3448421279dd0d60222ed01650f8f655c2a56f9e21df340b52d2d8baff0bb

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.