Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
LiquidityPoolV1Converter
Compiler Version
v0.4.26+commit.4563c3fc
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-06-29 */ // File: contracts/utility/interfaces/IOwned.sol pragma solidity 0.4.26; /* Owned contract interface */ contract IOwned { // this function isn't abstract since the compiler emits automatically generated getter functions as external function owner() public view returns (address) {this;} function transferOwnership(address _newOwner) public; function acceptOwnership() public; } // File: contracts/token/interfaces/IERC20Token.sol pragma solidity 0.4.26; /* ERC20 Standard Token interface */ contract IERC20Token { // these functions aren't abstract since the compiler emits automatically generated getter functions as external function name() public view returns (string) {this;} function symbol() public view returns (string) {this;} function decimals() public view returns (uint8) {this;} function totalSupply() public view returns (uint256) {this;} function balanceOf(address _owner) public view returns (uint256) {_owner; this;} function allowance(address _owner, address _spender) public view returns (uint256) {_owner; _spender; this;} function transfer(address _to, uint256 _value) public returns (bool success); function transferFrom(address _from, address _to, uint256 _value) public returns (bool success); function approve(address _spender, uint256 _value) public returns (bool success); } // File: contracts/utility/interfaces/ITokenHolder.sol pragma solidity 0.4.26; /* Token Holder interface */ contract ITokenHolder is IOwned { function withdrawTokens(IERC20Token _token, address _to, uint256 _amount) public; } // File: contracts/converter/interfaces/IConverterAnchor.sol pragma solidity 0.4.26; /* Converter Anchor interface */ contract IConverterAnchor is IOwned, ITokenHolder { } // File: contracts/utility/interfaces/IWhitelist.sol pragma solidity 0.4.26; /* Whitelist interface */ contract IWhitelist { function isWhitelisted(address _address) public view returns (bool); } // File: contracts/converter/interfaces/IConverter.sol pragma solidity 0.4.26; /* Converter interface */ contract IConverter is IOwned { function converterType() public pure returns (uint16); function anchor() public view returns (IConverterAnchor) {this;} function isActive() public view returns (bool); function targetAmountAndFee(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount) public view returns (uint256, uint256); function convert(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount, address _trader, address _beneficiary) public payable returns (uint256); function conversionWhitelist() public view returns (IWhitelist) {this;} function conversionFee() public view returns (uint32) {this;} function maxConversionFee() public view returns (uint32) {this;} function reserveBalance(IERC20Token _reserveToken) public view returns (uint256); function() external payable; function transferAnchorOwnership(address _newOwner) public; function acceptAnchorOwnership() public; function setConversionFee(uint32 _conversionFee) public; function setConversionWhitelist(IWhitelist _whitelist) public; function withdrawTokens(IERC20Token _token, address _to, uint256 _amount) public; function withdrawETH(address _to) public; function addReserve(IERC20Token _token, uint32 _ratio) public; // deprecated, backward compatibility function token() public view returns (IConverterAnchor); function transferTokenOwnership(address _newOwner) public; function acceptTokenOwnership() public; function connectors(address _address) public view returns (uint256, uint32, bool, bool, bool); function getConnectorBalance(IERC20Token _connectorToken) public view returns (uint256); function connectorTokens(uint256 _index) public view returns (IERC20Token); function connectorTokenCount() public view returns (uint16); } // File: contracts/converter/interfaces/IConverterUpgrader.sol pragma solidity 0.4.26; /* Converter Upgrader interface */ contract IConverterUpgrader { function upgrade(bytes32 _version) public; function upgrade(uint16 _version) public; } // File: contracts/converter/interfaces/IBancorFormula.sol pragma solidity 0.4.26; /* Bancor Formula interface */ contract IBancorFormula { function purchaseTargetAmount(uint256 _supply, uint256 _reserveBalance, uint32 _reserveWeight, uint256 _amount) public view returns (uint256); function saleTargetAmount(uint256 _supply, uint256 _reserveBalance, uint32 _reserveWeight, uint256 _amount) public view returns (uint256); function crossReserveTargetAmount(uint256 _sourceReserveBalance, uint32 _sourceReserveWeight, uint256 _targetReserveBalance, uint32 _targetReserveWeight, uint256 _amount) public view returns (uint256); function fundCost(uint256 _supply, uint256 _reserveBalance, uint32 _reserveRatio, uint256 _amount) public view returns (uint256); function fundSupplyAmount(uint256 _supply, uint256 _reserveBalance, uint32 _reserveRatio, uint256 _amount) public view returns (uint256); function liquidateReserveAmount(uint256 _supply, uint256 _reserveBalance, uint32 _reserveRatio, uint256 _amount) public view returns (uint256); } // File: contracts/IBancorNetwork.sol pragma solidity 0.4.26; /* Bancor Network interface */ contract IBancorNetwork { function convert2( IERC20Token[] _path, uint256 _amount, uint256 _minReturn, address _affiliateAccount, uint256 _affiliateFee ) public payable returns (uint256); function claimAndConvert2( IERC20Token[] _path, uint256 _amount, uint256 _minReturn, address _affiliateAccount, uint256 _affiliateFee ) public returns (uint256); function convertFor2( IERC20Token[] _path, uint256 _amount, uint256 _minReturn, address _for, address _affiliateAccount, uint256 _affiliateFee ) public payable returns (uint256); function claimAndConvertFor2( IERC20Token[] _path, uint256 _amount, uint256 _minReturn, address _for, address _affiliateAccount, uint256 _affiliateFee ) public returns (uint256); // deprecated, backward compatibility function convert( IERC20Token[] _path, uint256 _amount, uint256 _minReturn ) public payable returns (uint256); // deprecated, backward compatibility function claimAndConvert( IERC20Token[] _path, uint256 _amount, uint256 _minReturn ) public returns (uint256); // deprecated, backward compatibility function convertFor( IERC20Token[] _path, uint256 _amount, uint256 _minReturn, address _for ) public payable returns (uint256); // deprecated, backward compatibility function claimAndConvertFor( IERC20Token[] _path, uint256 _amount, uint256 _minReturn, address _for ) public returns (uint256); } // File: contracts/utility/Owned.sol pragma solidity 0.4.26; /** * @dev Provides support and utilities for contract ownership */ contract Owned is IOwned { address public owner; address public newOwner; /** * @dev triggered when the owner is updated * * @param _prevOwner previous owner * @param _newOwner new owner */ event OwnerUpdate(address indexed _prevOwner, address indexed _newOwner); /** * @dev initializes a new Owned instance */ constructor() public { owner = msg.sender; } // allows execution by the owner only modifier ownerOnly { _ownerOnly(); _; } // error message binary size optimization function _ownerOnly() internal view { require(msg.sender == owner, "ERR_ACCESS_DENIED"); } /** * @dev allows transferring the contract ownership * the new owner still needs to accept the transfer * can only be called by the contract owner * * @param _newOwner new contract owner */ function transferOwnership(address _newOwner) public ownerOnly { require(_newOwner != owner, "ERR_SAME_OWNER"); newOwner = _newOwner; } /** * @dev used by a new owner to accept an ownership transfer */ function acceptOwnership() public { require(msg.sender == newOwner, "ERR_ACCESS_DENIED"); emit OwnerUpdate(owner, newOwner); owner = newOwner; newOwner = address(0); } } // File: contracts/utility/Utils.sol pragma solidity 0.4.26; /** * @dev Utilities & Common Modifiers */ contract Utils { // verifies that a value is greater than zero modifier greaterThanZero(uint256 _value) { _greaterThanZero(_value); _; } // error message binary size optimization function _greaterThanZero(uint256 _value) internal pure { require(_value > 0, "ERR_ZERO_VALUE"); } // validates an address - currently only checks that it isn't null modifier validAddress(address _address) { _validAddress(_address); _; } // error message binary size optimization function _validAddress(address _address) internal pure { require(_address != address(0), "ERR_INVALID_ADDRESS"); } // verifies that the address is different than this contract address modifier notThis(address _address) { _notThis(_address); _; } // error message binary size optimization function _notThis(address _address) internal view { require(_address != address(this), "ERR_ADDRESS_IS_SELF"); } } // File: contracts/utility/interfaces/IContractRegistry.sol pragma solidity 0.4.26; /* Contract Registry interface */ contract IContractRegistry { function addressOf(bytes32 _contractName) public view returns (address); // deprecated, backward compatibility function getAddress(bytes32 _contractName) public view returns (address); } // File: contracts/utility/ContractRegistryClient.sol pragma solidity 0.4.26; /** * @dev Base contract for ContractRegistry clients */ contract ContractRegistryClient is Owned, Utils { bytes32 internal constant CONTRACT_REGISTRY = "ContractRegistry"; bytes32 internal constant BANCOR_NETWORK = "BancorNetwork"; bytes32 internal constant BANCOR_FORMULA = "BancorFormula"; bytes32 internal constant CONVERTER_FACTORY = "ConverterFactory"; bytes32 internal constant CONVERSION_PATH_FINDER = "ConversionPathFinder"; bytes32 internal constant CONVERTER_UPGRADER = "BancorConverterUpgrader"; bytes32 internal constant CONVERTER_REGISTRY = "BancorConverterRegistry"; bytes32 internal constant CONVERTER_REGISTRY_DATA = "BancorConverterRegistryData"; bytes32 internal constant BNT_TOKEN = "BNTToken"; bytes32 internal constant BANCOR_X = "BancorX"; bytes32 internal constant BANCOR_X_UPGRADER = "BancorXUpgrader"; IContractRegistry public registry; // address of the current contract-registry IContractRegistry public prevRegistry; // address of the previous contract-registry bool public onlyOwnerCanUpdateRegistry; // only an owner can update the contract-registry /** * @dev verifies that the caller is mapped to the given contract name * * @param _contractName contract name */ modifier only(bytes32 _contractName) { _only(_contractName); _; } // error message binary size optimization function _only(bytes32 _contractName) internal view { require(msg.sender == addressOf(_contractName), "ERR_ACCESS_DENIED"); } /** * @dev initializes a new ContractRegistryClient instance * * @param _registry address of a contract-registry contract */ constructor(IContractRegistry _registry) internal validAddress(_registry) { registry = IContractRegistry(_registry); prevRegistry = IContractRegistry(_registry); } /** * @dev updates to the new contract-registry */ function updateRegistry() public { // verify that this function is permitted require(msg.sender == owner || !onlyOwnerCanUpdateRegistry, "ERR_ACCESS_DENIED"); // get the new contract-registry IContractRegistry newRegistry = IContractRegistry(addressOf(CONTRACT_REGISTRY)); // verify that the new contract-registry is different and not zero require(newRegistry != address(registry) && newRegistry != address(0), "ERR_INVALID_REGISTRY"); // verify that the new contract-registry is pointing to a non-zero contract-registry require(newRegistry.addressOf(CONTRACT_REGISTRY) != address(0), "ERR_INVALID_REGISTRY"); // save a backup of the current contract-registry before replacing it prevRegistry = registry; // replace the current contract-registry with the new contract-registry registry = newRegistry; } /** * @dev restores the previous contract-registry */ function restoreRegistry() public ownerOnly { // restore the previous contract-registry registry = prevRegistry; } /** * @dev restricts the permission to update the contract-registry * * @param _onlyOwnerCanUpdateRegistry indicates whether or not permission is restricted to owner only */ function restrictRegistryUpdate(bool _onlyOwnerCanUpdateRegistry) public ownerOnly { // change the permission to update the contract-registry onlyOwnerCanUpdateRegistry = _onlyOwnerCanUpdateRegistry; } /** * @dev returns the address associated with the given contract name * * @param _contractName contract name * * @return contract address */ function addressOf(bytes32 _contractName) internal view returns (address) { return registry.addressOf(_contractName); } } // File: contracts/utility/ReentrancyGuard.sol pragma solidity 0.4.26; /** * @dev ReentrancyGuard * * The contract provides protection against re-entrancy - calling a function (directly or * indirectly) from within itself. */ contract ReentrancyGuard { // true while protected code is being executed, false otherwise bool private locked = false; /** * @dev ensures instantiation only by sub-contracts */ constructor() internal {} // protects a function against reentrancy attacks modifier protected() { _protected(); locked = true; _; locked = false; } // error message binary size optimization function _protected() internal view { require(!locked, "ERR_REENTRANCY"); } } // File: contracts/utility/SafeMath.sol pragma solidity 0.4.26; /** * @dev Library for basic math operations with overflow/underflow protection */ library SafeMath { /** * @dev returns the sum of _x and _y, reverts if the calculation overflows * * @param _x value 1 * @param _y value 2 * * @return sum */ function add(uint256 _x, uint256 _y) internal pure returns (uint256) { uint256 z = _x + _y; require(z >= _x, "ERR_OVERFLOW"); return z; } /** * @dev returns the difference of _x minus _y, reverts if the calculation underflows * * @param _x minuend * @param _y subtrahend * * @return difference */ function sub(uint256 _x, uint256 _y) internal pure returns (uint256) { require(_x >= _y, "ERR_UNDERFLOW"); return _x - _y; } /** * @dev returns the product of multiplying _x by _y, reverts if the calculation overflows * * @param _x factor 1 * @param _y factor 2 * * @return product */ function mul(uint256 _x, uint256 _y) internal pure returns (uint256) { // gas optimization if (_x == 0) return 0; uint256 z = _x * _y; require(z / _x == _y, "ERR_OVERFLOW"); return z; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. * * @param _x dividend * @param _y divisor * * @return quotient */ function div(uint256 _x, uint256 _y) internal pure returns (uint256) { require(_y > 0, "ERR_DIVIDE_BY_ZERO"); uint256 c = _x / _y; return c; } } // File: contracts/utility/TokenHandler.sol pragma solidity 0.4.26; contract TokenHandler { bytes4 private constant APPROVE_FUNC_SELECTOR = bytes4(keccak256("approve(address,uint256)")); bytes4 private constant TRANSFER_FUNC_SELECTOR = bytes4(keccak256("transfer(address,uint256)")); bytes4 private constant TRANSFER_FROM_FUNC_SELECTOR = bytes4(keccak256("transferFrom(address,address,uint256)")); /** * @dev executes the ERC20 token's `approve` function and reverts upon failure * the main purpose of this function is to prevent a non standard ERC20 token * from failing silently * * @param _token ERC20 token address * @param _spender approved address * @param _value allowance amount */ function safeApprove(IERC20Token _token, address _spender, uint256 _value) internal { execute(_token, abi.encodeWithSelector(APPROVE_FUNC_SELECTOR, _spender, _value)); } /** * @dev executes the ERC20 token's `transfer` function and reverts upon failure * the main purpose of this function is to prevent a non standard ERC20 token * from failing silently * * @param _token ERC20 token address * @param _to target address * @param _value transfer amount */ function safeTransfer(IERC20Token _token, address _to, uint256 _value) internal { execute(_token, abi.encodeWithSelector(TRANSFER_FUNC_SELECTOR, _to, _value)); } /** * @dev executes the ERC20 token's `transferFrom` function and reverts upon failure * the main purpose of this function is to prevent a non standard ERC20 token * from failing silently * * @param _token ERC20 token address * @param _from source address * @param _to target address * @param _value transfer amount */ function safeTransferFrom(IERC20Token _token, address _from, address _to, uint256 _value) internal { execute(_token, abi.encodeWithSelector(TRANSFER_FROM_FUNC_SELECTOR, _from, _to, _value)); } /** * @dev executes a function on the ERC20 token and reverts upon failure * the main purpose of this function is to prevent a non standard ERC20 token * from failing silently * * @param _token ERC20 token address * @param _data data to pass in to the token's contract for execution */ function execute(IERC20Token _token, bytes memory _data) private { uint256[1] memory ret = [uint256(1)]; assembly { let success := call( gas, // gas remaining _token, // destination address 0, // no ether add(_data, 32), // input buffer (starts after the first 32 bytes in the `data` array) mload(_data), // input length (loaded from the first 32 bytes in the `data` array) ret, // output buffer 32 // output length ) if iszero(success) { revert(0, 0) } } require(ret[0] != 0, "ERR_TRANSFER_FAILED"); } } // File: contracts/utility/TokenHolder.sol pragma solidity 0.4.26; /** * @dev We consider every contract to be a 'token holder' since it's currently not possible * for a contract to deny receiving tokens. * * The TokenHolder's contract sole purpose is to provide a safety mechanism that allows * the owner to send tokens that were sent to the contract by mistake back to their sender. * * Note that we use the non standard ERC-20 interface which has no return value for transfer * in order to support both non standard as well as standard token contracts. * see https://github.com/ethereum/solidity/issues/4116 */ contract TokenHolder is ITokenHolder, TokenHandler, Owned, Utils { /** * @dev withdraws tokens held by the contract and sends them to an account * can only be called by the owner * * @param _token ERC20 token contract address * @param _to account to receive the new amount * @param _amount amount to withdraw */ function withdrawTokens(IERC20Token _token, address _to, uint256 _amount) public ownerOnly validAddress(_token) validAddress(_to) notThis(_to) { safeTransfer(_token, _to, _amount); } } // File: contracts/token/interfaces/IEtherToken.sol pragma solidity 0.4.26; /* Ether Token interface */ contract IEtherToken is IERC20Token { function deposit() public payable; function withdraw(uint256 _amount) public; function depositTo(address _to) public payable; function withdrawTo(address _to, uint256 _amount) public; } // File: contracts/bancorx/interfaces/IBancorX.sol pragma solidity 0.4.26; contract IBancorX { function token() public view returns (IERC20Token) {this;} function xTransfer(bytes32 _toBlockchain, bytes32 _to, uint256 _amount, uint256 _id) public; function getXTransferAmount(uint256 _xTransferId, address _for) public view returns (uint256); } // File: contracts/converter/ConverterBase.sol pragma solidity 0.4.26; /** * @dev ConverterBase * * The converter contains the main logic for conversions between different ERC20 tokens. * * It is also the upgradable part of the mechanism (note that upgrades are opt-in). * * The anchor must be set on construction and cannot be changed afterwards. * Wrappers are provided for some of the anchor's functions, for easier access. * * Once the converter accepts ownership of the anchor, it becomes the anchor's sole controller * and can execute any of its functions. * * To upgrade the converter, anchor ownership must be transferred to a new converter, along with * any relevant data. * * Note that the converter can transfer anchor ownership to a new converter that * doesn't allow upgrades anymore, for finalizing the relationship between the converter * and the anchor. * * Converter types (defined as uint16 type) - * 0 = liquid token converter * 1 = liquidity pool v1 converter * 2 = liquidity pool v2 converter * * Note that converters don't currently support tokens with transfer fees. */ contract ConverterBase is IConverter, TokenHandler, TokenHolder, ContractRegistryClient, ReentrancyGuard { using SafeMath for uint256; uint32 internal constant WEIGHT_RESOLUTION = 1000000; uint64 internal constant CONVERSION_FEE_RESOLUTION = 1000000; address internal constant ETH_RESERVE_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; struct Reserve { uint256 balance; // reserve balance uint32 weight; // reserve weight, represented in ppm, 1-1000000 bool deprecated1; // deprecated bool deprecated2; // deprecated bool isSet; // true if the reserve is valid, false otherwise } /** * @dev version number */ uint16 public constant version = 30; IConverterAnchor public anchor; // converter anchor contract IWhitelist public conversionWhitelist; // whitelist contract with list of addresses that are allowed to use the converter IERC20Token[] public reserveTokens; // ERC20 standard token addresses (prior version 17, use 'connectorTokens' instead) mapping (address => Reserve) public reserves; // reserve token addresses -> reserve data (prior version 17, use 'connectors' instead) uint32 public reserveRatio = 0; // ratio between the reserves and the market cap, equal to the total reserve weights uint32 public maxConversionFee = 0; // maximum conversion fee for the lifetime of the contract, // represented in ppm, 0...1000000 (0 = no fee, 100 = 0.01%, 1000000 = 100%) uint32 public conversionFee = 0; // current conversion fee, represented in ppm, 0...maxConversionFee bool public constant conversionsEnabled = true; // deprecated, backward compatibility /** * @dev triggered when the converter is activated * * @param _anchor converter anchor * @param _activated true if the converter was activated, false if it was deactivated */ event Activation(IConverterAnchor _anchor, bool _activated); /** * @dev triggered when a conversion between two tokens occurs * * @param _fromToken source ERC20 token * @param _toToken target ERC20 token * @param _trader wallet that initiated the trade * @param _amount amount converted, in the source token * @param _return amount returned, minus conversion fee * @param _conversionFee conversion fee */ event Conversion( address indexed _fromToken, address indexed _toToken, address indexed _trader, uint256 _amount, uint256 _return, int256 _conversionFee ); /** * @dev triggered when the rate between two tokens in the converter changes * note that the event might be dispatched for rate updates between any two tokens in the converter * note that prior to version 28, you should use the 'PriceDataUpdate' event instead * * @param _token1 address of the first token * @param _token2 address of the second token * @param _rateN rate of 1 unit of `_token1` in `_token2` (numerator) * @param _rateD rate of 1 unit of `_token1` in `_token2` (denominator) */ event TokenRateUpdate( address indexed _token1, address indexed _token2, uint256 _rateN, uint256 _rateD ); /** * @dev triggered when the conversion fee is updated * * @param _prevFee previous fee percentage, represented in ppm * @param _newFee new fee percentage, represented in ppm */ event ConversionFeeUpdate(uint32 _prevFee, uint32 _newFee); /** * @dev used by sub-contracts to initialize a new converter * * @param _anchor anchor governed by the converter * @param _registry address of a contract registry contract * @param _maxConversionFee maximum conversion fee, represented in ppm */ constructor( IConverterAnchor _anchor, IContractRegistry _registry, uint32 _maxConversionFee ) validAddress(_anchor) ContractRegistryClient(_registry) internal validConversionFee(_maxConversionFee) { anchor = _anchor; maxConversionFee = _maxConversionFee; } // ensures that the converter is active modifier active() { _active(); _; } // error message binary size optimization function _active() internal view { require(isActive(), "ERR_INACTIVE"); } // ensures that the converter is not active modifier inactive() { _inactive(); _; } // error message binary size optimization function _inactive() internal view { require(!isActive(), "ERR_ACTIVE"); } // validates a reserve token address - verifies that the address belongs to one of the reserve tokens modifier validReserve(IERC20Token _address) { _validReserve(_address); _; } // error message binary size optimization function _validReserve(IERC20Token _address) internal view { require(reserves[_address].isSet, "ERR_INVALID_RESERVE"); } // validates conversion fee modifier validConversionFee(uint32 _conversionFee) { _validConversionFee(_conversionFee); _; } // error message binary size optimization function _validConversionFee(uint32 _conversionFee) internal pure { require(_conversionFee <= CONVERSION_FEE_RESOLUTION, "ERR_INVALID_CONVERSION_FEE"); } // validates reserve weight modifier validReserveWeight(uint32 _weight) { _validReserveWeight(_weight); _; } // error message binary size optimization function _validReserveWeight(uint32 _weight) internal pure { require(_weight > 0 && _weight <= WEIGHT_RESOLUTION, "ERR_INVALID_RESERVE_WEIGHT"); } /** * @dev deposits ether * can only be called if the converter has an ETH reserve */ function() external payable { require(reserves[ETH_RESERVE_ADDRESS].isSet, "ERR_INVALID_RESERVE"); // require(hasETHReserve(), "ERR_INVALID_RESERVE"); // a workaround for a problem when running solidity-coverage // see https://github.com/sc-forks/solidity-coverage/issues/487 } /** * @dev withdraws ether * can only be called by the owner if the converter is inactive or by upgrader contract * can only be called after the upgrader contract has accepted the ownership of this contract * can only be called if the converter has an ETH reserve * * @param _to address to send the ETH to */ function withdrawETH(address _to) public protected ownerOnly validReserve(IERC20Token(ETH_RESERVE_ADDRESS)) { address converterUpgrader = addressOf(CONVERTER_UPGRADER); // verify that the converter is inactive or that the owner is the upgrader contract require(!isActive() || owner == converterUpgrader, "ERR_ACCESS_DENIED"); _to.transfer(address(this).balance); // sync the ETH reserve balance syncReserveBalance(IERC20Token(ETH_RESERVE_ADDRESS)); } /** * @dev checks whether or not the converter version is 28 or higher * * @return true, since the converter version is 28 or higher */ function isV28OrHigher() public pure returns (bool) { return true; } /** * @dev allows the owner to update & enable the conversion whitelist contract address * when set, only addresses that are whitelisted are actually allowed to use the converter * note that the whitelist check is actually done by the BancorNetwork contract * * @param _whitelist address of a whitelist contract */ function setConversionWhitelist(IWhitelist _whitelist) public ownerOnly notThis(_whitelist) { conversionWhitelist = _whitelist; } /** * @dev returns true if the converter is active, false otherwise */ function isActive() public view returns (bool) { return anchor.owner() == address(this); } /** * @dev transfers the anchor ownership * the new owner needs to accept the transfer * can only be called by the converter upgrder while the upgrader is the owner * note that prior to version 28, you should use 'transferAnchorOwnership' instead * * @param _newOwner new token owner */ function transferAnchorOwnership(address _newOwner) public ownerOnly only(CONVERTER_UPGRADER) { anchor.transferOwnership(_newOwner); } /** * @dev accepts ownership of the anchor after an ownership transfer * most converters are also activated as soon as they accept the anchor ownership * can only be called by the contract owner * note that prior to version 28, you should use 'acceptTokenOwnership' instead */ function acceptAnchorOwnership() public ownerOnly { // verify the the converter has at least one reserve require(reserveTokenCount() > 0, "ERR_INVALID_RESERVE_COUNT"); anchor.acceptOwnership(); syncReserveBalances(); } /** * @dev withdraws tokens held by the anchor and sends them to an account * can only be called by the owner * * @param _token ERC20 token contract address * @param _to account to receive the new amount * @param _amount amount to withdraw */ function withdrawFromAnchor(IERC20Token _token, address _to, uint256 _amount) public ownerOnly { anchor.withdrawTokens(_token, _to, _amount); } /** * @dev updates the current conversion fee * can only be called by the contract owner * * @param _conversionFee new conversion fee, represented in ppm */ function setConversionFee(uint32 _conversionFee) public ownerOnly { require(_conversionFee <= maxConversionFee, "ERR_INVALID_CONVERSION_FEE"); emit ConversionFeeUpdate(conversionFee, _conversionFee); conversionFee = _conversionFee; } /** * @dev withdraws tokens held by the converter and sends them to an account * can only be called by the owner * note that reserve tokens can only be withdrawn by the owner while the converter is inactive * unless the owner is the converter upgrader contract * * @param _token ERC20 token contract address * @param _to account to receive the new amount * @param _amount amount to withdraw */ function withdrawTokens(IERC20Token _token, address _to, uint256 _amount) public protected ownerOnly { address converterUpgrader = addressOf(CONVERTER_UPGRADER); // if the token is not a reserve token, allow withdrawal // otherwise verify that the converter is inactive or that the owner is the upgrader contract require(!reserves[_token].isSet || !isActive() || owner == converterUpgrader, "ERR_ACCESS_DENIED"); super.withdrawTokens(_token, _to, _amount); // if the token is a reserve token, sync the reserve balance if (reserves[_token].isSet) syncReserveBalance(_token); } /** * @dev upgrades the converter to the latest version * can only be called by the owner * note that the owner needs to call acceptOwnership on the new converter after the upgrade */ function upgrade() public ownerOnly { IConverterUpgrader converterUpgrader = IConverterUpgrader(addressOf(CONVERTER_UPGRADER)); transferOwnership(converterUpgrader); converterUpgrader.upgrade(version); acceptOwnership(); } /** * @dev returns the number of reserve tokens defined * note that prior to version 17, you should use 'connectorTokenCount' instead * * @return number of reserve tokens */ function reserveTokenCount() public view returns (uint16) { return uint16(reserveTokens.length); } /** * @dev defines a new reserve token for the converter * can only be called by the owner while the converter is inactive * * @param _token address of the reserve token * @param _weight reserve weight, represented in ppm, 1-1000000 */ function addReserve(IERC20Token _token, uint32 _weight) public ownerOnly inactive validAddress(_token) notThis(_token) validReserveWeight(_weight) { // validate input require(_token != address(anchor) && !reserves[_token].isSet, "ERR_INVALID_RESERVE"); require(_weight <= WEIGHT_RESOLUTION - reserveRatio, "ERR_INVALID_RESERVE_WEIGHT"); require(reserveTokenCount() < uint16(-1), "ERR_INVALID_RESERVE_COUNT"); Reserve storage newReserve = reserves[_token]; newReserve.balance = 0; newReserve.weight = _weight; newReserve.isSet = true; reserveTokens.push(_token); reserveRatio += _weight; } /** * @dev returns the reserve's weight * added in version 28 * * @param _reserveToken reserve token contract address * * @return reserve weight */ function reserveWeight(IERC20Token _reserveToken) public view validReserve(_reserveToken) returns (uint32) { return reserves[_reserveToken].weight; } /** * @dev returns the reserve's balance * note that prior to version 17, you should use 'getConnectorBalance' instead * * @param _reserveToken reserve token contract address * * @return reserve balance */ function reserveBalance(IERC20Token _reserveToken) public view validReserve(_reserveToken) returns (uint256) { return reserves[_reserveToken].balance; } /** * @dev checks whether or not the converter has an ETH reserve * * @return true if the converter has an ETH reserve, false otherwise */ function hasETHReserve() public view returns (bool) { return reserves[ETH_RESERVE_ADDRESS].isSet; } /** * @dev converts a specific amount of source tokens to target tokens * can only be called by the bancor network contract * * @param _sourceToken source ERC20 token * @param _targetToken target ERC20 token * @param _amount amount of tokens to convert (in units of the source token) * @param _trader address of the caller who executed the conversion * @param _beneficiary wallet to receive the conversion result * * @return amount of tokens received (in units of the target token) */ function convert(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount, address _trader, address _beneficiary) public payable protected only(BANCOR_NETWORK) returns (uint256) { // validate input require(_sourceToken != _targetToken, "ERR_SAME_SOURCE_TARGET"); // if a whitelist is set, verify that both and trader and the beneficiary are whitelisted require(conversionWhitelist == address(0) || (conversionWhitelist.isWhitelisted(_trader) && conversionWhitelist.isWhitelisted(_beneficiary)), "ERR_NOT_WHITELISTED"); return doConvert(_sourceToken, _targetToken, _amount, _trader, _beneficiary); } /** * @dev converts a specific amount of source tokens to target tokens * called by ConverterBase and allows the inherited contracts to implement custom conversion logic * * @param _sourceToken source ERC20 token * @param _targetToken target ERC20 token * @param _amount amount of tokens to convert (in units of the source token) * @param _trader address of the caller who executed the conversion * @param _beneficiary wallet to receive the conversion result * * @return amount of tokens received (in units of the target token) */ function doConvert(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount, address _trader, address _beneficiary) internal returns (uint256); /** * @dev returns the conversion fee for a given return amount * * @param _amount return amount * * @return conversion fee */ function calculateFee(uint256 _amount) internal view returns (uint256) { return _amount.mul(conversionFee).div(CONVERSION_FEE_RESOLUTION); } /** * @dev syncs the stored reserve balance for a given reserve with the real reserve balance * * @param _reserveToken address of the reserve token */ function syncReserveBalance(IERC20Token _reserveToken) internal validReserve(_reserveToken) { if (_reserveToken == ETH_RESERVE_ADDRESS) reserves[_reserveToken].balance = address(this).balance; else reserves[_reserveToken].balance = _reserveToken.balanceOf(this); } /** * @dev syncs all stored reserve balances */ function syncReserveBalances() internal { uint256 reserveCount = reserveTokens.length; for (uint256 i = 0; i < reserveCount; i++) syncReserveBalance(reserveTokens[i]); } /** * @dev helper, dispatches the Conversion event * * @param _sourceToken source ERC20 token * @param _targetToken target ERC20 token * @param _trader address of the caller who executed the conversion * @param _amount amount purchased/sold (in the source token) * @param _returnAmount amount returned (in the target token) */ function dispatchConversionEvent( IERC20Token _sourceToken, IERC20Token _targetToken, address _trader, uint256 _amount, uint256 _returnAmount, uint256 _feeAmount) internal { // fee amount is converted to 255 bits - // negative amount means the fee is taken from the source token, positive amount means its taken from the target token // currently the fee is always taken from the target token // since we convert it to a signed number, we first ensure that it's capped at 255 bits to prevent overflow assert(_feeAmount < 2 ** 255); emit Conversion(_sourceToken, _targetToken, _trader, _amount, _returnAmount, int256(_feeAmount)); } /** * @dev deprecated since version 28, backward compatibility - use only for earlier versions */ function token() public view returns (IConverterAnchor) { return anchor; } /** * @dev deprecated, backward compatibility */ function transferTokenOwnership(address _newOwner) public ownerOnly { transferAnchorOwnership(_newOwner); } /** * @dev deprecated, backward compatibility */ function acceptTokenOwnership() public ownerOnly { acceptAnchorOwnership(); } /** * @dev deprecated, backward compatibility */ function connectors(address _address) public view returns (uint256, uint32, bool, bool, bool) { Reserve memory reserve = reserves[_address]; return(reserve.balance, reserve.weight, false, false, reserve.isSet); } /** * @dev deprecated, backward compatibility */ function connectorTokens(uint256 _index) public view returns (IERC20Token) { return ConverterBase.reserveTokens[_index]; } /** * @dev deprecated, backward compatibility */ function connectorTokenCount() public view returns (uint16) { return reserveTokenCount(); } /** * @dev deprecated, backward compatibility */ function getConnectorBalance(IERC20Token _connectorToken) public view returns (uint256) { return reserveBalance(_connectorToken); } /** * @dev deprecated, backward compatibility */ function getReturn(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount) public view returns (uint256, uint256) { return targetAmountAndFee(_sourceToken, _targetToken, _amount); } } // File: contracts/converter/LiquidityPoolConverter.sol pragma solidity 0.4.26; /** * @dev Liquidity Pool Converter * * The liquidity pool converter is the base contract for specific types of converters that * manage liquidity pools. * * Liquidity pools have 2 reserves or more and they allow converting between them. * * Note that TokenRateUpdate events are dispatched for pool tokens as well. * The pool token is the first token in the event in that case. */ contract LiquidityPoolConverter is ConverterBase { /** * @dev triggered after liquidity is added * * @param _provider liquidity provider * @param _reserveToken reserve token address * @param _amount reserve token amount * @param _newBalance reserve token new balance * @param _newSupply pool token new supply */ event LiquidityAdded( address indexed _provider, address indexed _reserveToken, uint256 _amount, uint256 _newBalance, uint256 _newSupply ); /** * @dev triggered after liquidity is removed * * @param _provider liquidity provider * @param _reserveToken reserve token address * @param _amount reserve token amount * @param _newBalance reserve token new balance * @param _newSupply pool token new supply */ event LiquidityRemoved( address indexed _provider, address indexed _reserveToken, uint256 _amount, uint256 _newBalance, uint256 _newSupply ); /** * @dev initializes a new LiquidityPoolConverter instance * * @param _anchor anchor governed by the converter * @param _registry address of a contract registry contract * @param _maxConversionFee maximum conversion fee, represented in ppm */ constructor( IConverterAnchor _anchor, IContractRegistry _registry, uint32 _maxConversionFee ) ConverterBase(_anchor, _registry, _maxConversionFee) internal { } /** * @dev accepts ownership of the anchor after an ownership transfer * also activates the converter * can only be called by the contract owner * note that prior to version 28, you should use 'acceptTokenOwnership' instead */ function acceptTokenOwnership() public { // verify that the converter has at least 2 reserves require(reserveTokenCount() > 1, "ERR_INVALID_RESERVE_COUNT"); super.acceptTokenOwnership(); } } // File: contracts/converter/interfaces/ITypedConverterFactory.sol pragma solidity 0.4.26; /* Typed Converter Factory interface */ contract ITypedConverterFactory { function converterType() public pure returns (uint16); function createConverter(IConverterAnchor _anchor, IContractRegistry _registry, uint32 _maxConversionFee) public returns (IConverter); } // File: contracts/token/interfaces/ISmartToken.sol pragma solidity 0.4.26; /* Smart Token interface */ contract ISmartToken is IConverterAnchor, IERC20Token { function disableTransfers(bool _disable) public; function issue(address _to, uint256 _amount) public; function destroy(address _from, uint256 _amount) public; } // File: contracts/converter/LiquidityPoolV1Converter.sol pragma solidity 0.4.26; /* LiquidityPoolV1Converter Factory */ contract LiquidityPoolV1ConverterFactory is ITypedConverterFactory { /** * @dev returns the converter type the factory is associated with * * @return converter type */ function converterType() public pure returns (uint16) { return 1; } /** * @dev creates a new converter with the given arguments and transfers * the ownership to the caller * * @param _anchor anchor governed by the converter * @param _registry address of a contract registry contract * @param _maxConversionFee maximum conversion fee, represented in ppm * * @return a new converter */ function createConverter(IConverterAnchor _anchor, IContractRegistry _registry, uint32 _maxConversionFee) public returns (IConverter) { ConverterBase converter = new LiquidityPoolV1Converter(ISmartToken(_anchor), _registry, _maxConversionFee); converter.transferOwnership(msg.sender); return converter; } } /** * @dev Liquidity Pool v1 Converter * * The liquidity pool v1 converter is a specialized version of a converter that manages * a classic bancor liquidity pool. * * Even though classic pools can have many reserves, the most common configuration of * the pool has 2 reserves with 50%/50% weights. */ contract LiquidityPoolV1Converter is LiquidityPoolConverter { IEtherToken internal etherToken = IEtherToken(0xc0829421C1d260BD3cB3E0F06cfE2D52db2cE315); /** * @dev triggered after a conversion with new price data * deprecated, use `TokenRateUpdate` from version 28 and up * * @param _connectorToken reserve token * @param _tokenSupply smart token supply * @param _connectorBalance reserve balance * @param _connectorWeight reserve weight */ event PriceDataUpdate( address indexed _connectorToken, uint256 _tokenSupply, uint256 _connectorBalance, uint32 _connectorWeight ); /** * @dev initializes a new LiquidityPoolV1Converter instance * * @param _token pool token governed by the converter * @param _registry address of a contract registry contract * @param _maxConversionFee maximum conversion fee, represented in ppm */ constructor( ISmartToken _token, IContractRegistry _registry, uint32 _maxConversionFee ) LiquidityPoolConverter(_token, _registry, _maxConversionFee) public { } /** * @dev returns the converter type * * @return see the converter types in the the main contract doc */ function converterType() public pure returns (uint16) { return 1; } /** * @dev accepts ownership of the anchor after an ownership transfer * also activates the converter * can only be called by the contract owner * note that prior to version 28, you should use 'acceptTokenOwnership' instead */ function acceptAnchorOwnership() public ownerOnly { super.acceptAnchorOwnership(); emit Activation(anchor, true); } /** * @dev returns the expected target amount of converting one reserve to another along with the fee * * @param _sourceToken contract address of the source reserve token * @param _targetToken contract address of the target reserve token * @param _amount amount of tokens received from the user * * @return expected target amount * @return expected fee */ function targetAmountAndFee(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount) public view active validReserve(_sourceToken) validReserve(_targetToken) returns (uint256, uint256) { // validate input require(_sourceToken != _targetToken, "ERR_SAME_SOURCE_TARGET"); uint256 amount = IBancorFormula(addressOf(BANCOR_FORMULA)).crossReserveTargetAmount( reserveBalance(_sourceToken), reserves[_sourceToken].weight, reserveBalance(_targetToken), reserves[_targetToken].weight, _amount ); // return the amount minus the conversion fee and the conversion fee uint256 fee = calculateFee(amount); return (amount - fee, fee); } /** * @dev converts a specific amount of source tokens to target tokens * can only be called by the bancor network contract * * @param _sourceToken source ERC20 token * @param _targetToken target ERC20 token * @param _amount amount of tokens to convert (in units of the source token) * @param _trader address of the caller who executed the conversion * @param _beneficiary wallet to receive the conversion result * * @return amount of tokens received (in units of the target token) */ function doConvert(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount, address _trader, address _beneficiary) internal returns (uint256) { // get expected target amount and fee (uint256 amount, uint256 fee) = targetAmountAndFee(_sourceToken, _targetToken, _amount); // ensure that the trade gives something in return require(amount != 0, "ERR_ZERO_TARGET_AMOUNT"); // ensure that the trade won't deplete the reserve balance uint256 targetReserveBalance = reserveBalance(_targetToken); assert(amount < targetReserveBalance); // ensure that the input amount was already deposited if (_sourceToken == ETH_RESERVE_ADDRESS) require(msg.value == _amount, "ERR_ETH_AMOUNT_MISMATCH"); else require(msg.value == 0 && _sourceToken.balanceOf(this).sub(reserveBalance(_sourceToken)) >= _amount, "ERR_INVALID_AMOUNT"); // sync the reserve balances syncReserveBalance(_sourceToken); reserves[_targetToken].balance = reserves[_targetToken].balance.sub(amount); // transfer funds to the beneficiary in the to reserve token if (_targetToken == ETH_RESERVE_ADDRESS) _beneficiary.transfer(amount); else safeTransfer(_targetToken, _beneficiary, amount); // dispatch the conversion event dispatchConversionEvent(_sourceToken, _targetToken, _trader, _amount, amount, fee); // dispatch rate updates dispatchRateEvents(_sourceToken, _targetToken); return amount; } /** * @dev increases the pool's liquidity and mints new shares in the pool to the caller * note that prior to version 28, you should use 'fund' instead * * @param _reserveTokens address of each reserve token * @param _reserveAmounts amount of each reserve token * @param _minReturn token minimum return-amount */ function addLiquidity(IERC20Token[] memory _reserveTokens, uint256[] memory _reserveAmounts, uint256 _minReturn) public payable protected active { // verify the user input verifyLiquidityInput(_reserveTokens, _reserveAmounts, _minReturn); // if one of the reserves is ETH, then verify that the input amount of ETH is equal to the input value of ETH for (uint256 i = 0; i < _reserveTokens.length; i++) if (_reserveTokens[i] == ETH_RESERVE_ADDRESS) require(_reserveAmounts[i] == msg.value, "ERR_ETH_AMOUNT_MISMATCH"); // if the input value of ETH is larger than zero, then verify that one of the reserves is ETH if (msg.value > 0) require(reserves[ETH_RESERVE_ADDRESS].isSet, "ERR_NO_ETH_RESERVE"); // get the total supply uint256 totalSupply = ISmartToken(anchor).totalSupply(); // transfer from the user an equally-worth amount of each one of the reserve tokens uint256 amount = addLiquidityToPool(_reserveTokens, _reserveAmounts, totalSupply); // verify that the equivalent amount of tokens is equal to or larger than the user's expectation require(amount >= _minReturn, "ERR_RETURN_TOO_LOW"); // issue the tokens to the user ISmartToken(anchor).issue(msg.sender, amount); } /** * @dev decreases the pool's liquidity and burns the caller's shares in the pool * note that prior to version 28, you should use 'liquidate' instead * * @param _amount token amount * @param _reserveTokens address of each reserve token * @param _reserveMinReturnAmounts minimum return-amount of each reserve token */ function removeLiquidity(uint256 _amount, IERC20Token[] memory _reserveTokens, uint256[] memory _reserveMinReturnAmounts) public protected active { // verify the user input verifyLiquidityInput(_reserveTokens, _reserveMinReturnAmounts, _amount); // get the total supply BEFORE destroying the user tokens uint256 totalSupply = ISmartToken(anchor).totalSupply(); // destroy the user tokens ISmartToken(anchor).destroy(msg.sender, _amount); // transfer to the user an equivalent amount of each one of the reserve tokens removeLiquidityFromPool(_reserveTokens, _reserveMinReturnAmounts, totalSupply, _amount); } /** * @dev increases the pool's liquidity and mints new shares in the pool to the caller * for example, if the caller increases the supply by 10%, * then it will cost an amount equal to 10% of each reserve token balance * note that starting from version 28, you should use 'addLiquidity' instead * * @param _amount amount to increase the supply by (in the pool token) */ function fund(uint256 _amount) public payable protected { syncReserveBalances(); reserves[ETH_RESERVE_ADDRESS].balance = reserves[ETH_RESERVE_ADDRESS].balance.sub(msg.value); uint256 supply = ISmartToken(anchor).totalSupply(); IBancorFormula formula = IBancorFormula(addressOf(BANCOR_FORMULA)); // iterate through the reserve tokens and transfer a percentage equal to the weight between // _amount and the total supply in each reserve from the caller to the converter uint256 reserveCount = reserveTokens.length; for (uint256 i = 0; i < reserveCount; i++) { IERC20Token reserveToken = reserveTokens[i]; uint256 rsvBalance = reserves[reserveToken].balance; uint256 reserveAmount = formula.fundCost(supply, rsvBalance, reserveRatio, _amount); // transfer funds from the caller in the reserve token if (reserveToken == ETH_RESERVE_ADDRESS) { if (msg.value > reserveAmount) { msg.sender.transfer(msg.value - reserveAmount); } else if (msg.value < reserveAmount) { require(msg.value == 0, "ERR_INVALID_ETH_VALUE"); safeTransferFrom(etherToken, msg.sender, this, reserveAmount); etherToken.withdraw(reserveAmount); } } else { safeTransferFrom(reserveToken, msg.sender, this, reserveAmount); } // sync the reserve balance uint256 newReserveBalance = rsvBalance.add(reserveAmount); reserves[reserveToken].balance = newReserveBalance; uint256 newPoolTokenSupply = supply.add(_amount); // dispatch liquidity update for the pool token/reserve emit LiquidityAdded(msg.sender, reserveToken, reserveAmount, newReserveBalance, newPoolTokenSupply); // dispatch the `TokenRateUpdate` event for the pool token uint32 reserveWeight = reserves[reserveToken].weight; dispatchPoolTokenRateEvent(newPoolTokenSupply, reserveToken, newReserveBalance, reserveWeight); } // issue new funds to the caller in the pool token ISmartToken(anchor).issue(msg.sender, _amount); } /** * @dev decreases the pool's liquidity and burns the caller's shares in the pool * for example, if the holder sells 10% of the supply, * then they will receive 10% of each reserve token balance in return * note that starting from version 28, you should use 'removeLiquidity' instead * * @param _amount amount to liquidate (in the pool token) */ function liquidate(uint256 _amount) public protected { require(_amount > 0, "ERR_ZERO_AMOUNT"); uint256 totalSupply = ISmartToken(anchor).totalSupply(); ISmartToken(anchor).destroy(msg.sender, _amount); uint256[] memory reserveMinReturnAmounts = new uint256[](reserveTokens.length); for (uint256 i = 0; i < reserveMinReturnAmounts.length; i++) reserveMinReturnAmounts[i] = 1; removeLiquidityFromPool(reserveTokens, reserveMinReturnAmounts, totalSupply, _amount); } /** * @dev verifies that a given array of tokens is identical to the converter's array of reserve tokens * we take this input in order to allow specifying the corresponding reserve amounts in any order * * @param _reserveTokens array of reserve tokens * @param _reserveAmounts array of reserve amounts * @param _amount token amount */ function verifyLiquidityInput(IERC20Token[] memory _reserveTokens, uint256[] memory _reserveAmounts, uint256 _amount) private view { uint256 i; uint256 j; uint256 length = reserveTokens.length; require(length == _reserveTokens.length, "ERR_INVALID_RESERVE"); require(length == _reserveAmounts.length, "ERR_INVALID_AMOUNT"); for (i = 0; i < length; i++) { // verify that every input reserve token is included in the reserve tokens require(reserves[_reserveTokens[i]].isSet, "ERR_INVALID_RESERVE"); for (j = 0; j < length; j++) { if (reserveTokens[i] == _reserveTokens[j]) break; } // verify that every reserve token is included in the input reserve tokens require(j < length, "ERR_INVALID_RESERVE"); // verify that every input reserve token amount is larger than zero require(_reserveAmounts[i] > 0, "ERR_INVALID_AMOUNT"); } // verify that the input token amount is larger than zero require(_amount > 0, "ERR_ZERO_AMOUNT"); } /** * @dev adds liquidity (reserve) to the pool * * @param _reserveTokens address of each reserve token * @param _reserveAmounts amount of each reserve token * @param _totalSupply token total supply */ function addLiquidityToPool(IERC20Token[] memory _reserveTokens, uint256[] memory _reserveAmounts, uint256 _totalSupply) private returns (uint256) { if (_totalSupply == 0) return addLiquidityToEmptyPool(_reserveTokens, _reserveAmounts); return addLiquidityToNonEmptyPool(_reserveTokens, _reserveAmounts, _totalSupply); } /** * @dev adds liquidity (reserve) to the pool when it's empty * * @param _reserveTokens address of each reserve token * @param _reserveAmounts amount of each reserve token */ function addLiquidityToEmptyPool(IERC20Token[] memory _reserveTokens, uint256[] memory _reserveAmounts) private returns (uint256) { // calculate the geometric-mean of the reserve amounts approved by the user uint256 amount = geometricMean(_reserveAmounts); // transfer each one of the reserve amounts from the user to the pool for (uint256 i = 0; i < _reserveTokens.length; i++) { if (_reserveTokens[i] != ETH_RESERVE_ADDRESS) // ETH has already been transferred as part of the transaction safeTransferFrom(_reserveTokens[i], msg.sender, this, _reserveAmounts[i]); reserves[_reserveTokens[i]].balance = _reserveAmounts[i]; emit LiquidityAdded(msg.sender, _reserveTokens[i], _reserveAmounts[i], _reserveAmounts[i], amount); // dispatch the `TokenRateUpdate` event for the pool token uint32 reserveWeight = reserves[_reserveTokens[i]].weight; dispatchPoolTokenRateEvent(amount, _reserveTokens[i], _reserveAmounts[i], reserveWeight); } return amount; } /** * @dev adds liquidity (reserve) to the pool when it's not empty * * @param _reserveTokens address of each reserve token * @param _reserveAmounts amount of each reserve token * @param _totalSupply token total supply */ function addLiquidityToNonEmptyPool(IERC20Token[] memory _reserveTokens, uint256[] memory _reserveAmounts, uint256 _totalSupply) private returns (uint256) { syncReserveBalances(); reserves[ETH_RESERVE_ADDRESS].balance = reserves[ETH_RESERVE_ADDRESS].balance.sub(msg.value); IBancorFormula formula = IBancorFormula(addressOf(BANCOR_FORMULA)); uint256 amount = getMinShare(formula, _totalSupply, _reserveTokens, _reserveAmounts); uint256 newPoolTokenSupply = _totalSupply.add(amount); for (uint256 i = 0; i < _reserveTokens.length; i++) { IERC20Token reserveToken = _reserveTokens[i]; uint256 rsvBalance = reserves[reserveToken].balance; uint256 reserveAmount = formula.fundCost(_totalSupply, rsvBalance, reserveRatio, amount); require(reserveAmount > 0, "ERR_ZERO_TARGET_AMOUNT"); assert(reserveAmount <= _reserveAmounts[i]); // transfer each one of the reserve amounts from the user to the pool if (reserveToken != ETH_RESERVE_ADDRESS) // ETH has already been transferred as part of the transaction safeTransferFrom(reserveToken, msg.sender, this, reserveAmount); else if (_reserveAmounts[i] > reserveAmount) // transfer the extra amount of ETH back to the user msg.sender.transfer(_reserveAmounts[i] - reserveAmount); uint256 newReserveBalance = rsvBalance.add(reserveAmount); reserves[reserveToken].balance = newReserveBalance; emit LiquidityAdded(msg.sender, reserveToken, reserveAmount, newReserveBalance, newPoolTokenSupply); // dispatch the `TokenRateUpdate` event for the pool token uint32 reserveWeight = reserves[_reserveTokens[i]].weight; dispatchPoolTokenRateEvent(newPoolTokenSupply, _reserveTokens[i], newReserveBalance, reserveWeight); } return amount; } /** * @dev removes liquidity (reserve) from the pool * * @param _reserveTokens address of each reserve token * @param _reserveMinReturnAmounts minimum return-amount of each reserve token * @param _totalSupply token total supply * @param _amount token amount */ function removeLiquidityFromPool(IERC20Token[] memory _reserveTokens, uint256[] memory _reserveMinReturnAmounts, uint256 _totalSupply, uint256 _amount) private { syncReserveBalances(); IBancorFormula formula = IBancorFormula(addressOf(BANCOR_FORMULA)); uint256 newPoolTokenSupply = _totalSupply.sub(_amount); for (uint256 i = 0; i < _reserveTokens.length; i++) { IERC20Token reserveToken = _reserveTokens[i]; uint256 rsvBalance = reserves[reserveToken].balance; uint256 reserveAmount = formula.liquidateReserveAmount(_totalSupply, rsvBalance, reserveRatio, _amount); require(reserveAmount >= _reserveMinReturnAmounts[i], "ERR_ZERO_TARGET_AMOUNT"); uint256 newReserveBalance = rsvBalance.sub(reserveAmount); reserves[reserveToken].balance = newReserveBalance; // transfer each one of the reserve amounts from the pool to the user if (reserveToken == ETH_RESERVE_ADDRESS) msg.sender.transfer(reserveAmount); else safeTransfer(reserveToken, msg.sender, reserveAmount); emit LiquidityRemoved(msg.sender, reserveToken, reserveAmount, newReserveBalance, newPoolTokenSupply); // dispatch the `TokenRateUpdate` event for the pool token uint32 reserveWeight = reserves[reserveToken].weight; dispatchPoolTokenRateEvent(newPoolTokenSupply, reserveToken, newReserveBalance, reserveWeight); } } function getMinShare(IBancorFormula formula, uint256 _totalSupply, IERC20Token[] memory _reserveTokens, uint256[] memory _reserveAmounts) private view returns (uint256) { uint256 minIndex = 0; for (uint256 i = 1; i < _reserveTokens.length; i++) { if (_reserveAmounts[i].mul(reserves[_reserveTokens[minIndex]].balance) < _reserveAmounts[minIndex].mul(reserves[_reserveTokens[i]].balance)) minIndex = i; } return formula.fundSupplyAmount(_totalSupply, reserves[_reserveTokens[minIndex]].balance, reserveRatio, _reserveAmounts[minIndex]); } /** * @dev calculates the number of decimal digits in a given value * * @param _x value (assumed positive) * @return the number of decimal digits in the given value */ function decimalLength(uint256 _x) public pure returns (uint256) { uint256 y = 0; for (uint256 x = _x; x > 0; x /= 10) y++; return y; } /** * @dev calculates the nearest integer to a given quotient * * @param _n quotient numerator * @param _d quotient denominator * @return the nearest integer to the given quotient */ function roundDiv(uint256 _n, uint256 _d) public pure returns (uint256) { return (_n + _d / 2) / _d; } /** * @dev calculates the average number of decimal digits in a given list of values * * @param _values list of values (each of which assumed positive) * @return the average number of decimal digits in the given list of values */ function geometricMean(uint256[] memory _values) public pure returns (uint256) { uint256 numOfDigits = 0; uint256 length = _values.length; for (uint256 i = 0; i < length; i++) numOfDigits += decimalLength(_values[i]); return uint256(10) ** (roundDiv(numOfDigits, length) - 1); } /** * @dev dispatches rate events for both reserves / pool tokens * only used to circumvent the `stack too deep` compiler error * * @param _sourceToken address of the source reserve token * @param _targetToken address of the target reserve token */ function dispatchRateEvents(IERC20Token _sourceToken, IERC20Token _targetToken) private { uint256 poolTokenSupply = ISmartToken(anchor).totalSupply(); uint256 sourceReserveBalance = reserveBalance(_sourceToken); uint256 targetReserveBalance = reserveBalance(_targetToken); uint32 sourceReserveWeight = reserves[_sourceToken].weight; uint32 targetReserveWeight = reserves[_targetToken].weight; // dispatch token rate update event uint256 rateN = targetReserveBalance.mul(sourceReserveWeight); uint256 rateD = sourceReserveBalance.mul(targetReserveWeight); emit TokenRateUpdate(_sourceToken, _targetToken, rateN, rateD); // dispatch the `TokenRateUpdate` event for the pool token dispatchPoolTokenRateEvent(poolTokenSupply, _sourceToken, sourceReserveBalance, sourceReserveWeight); dispatchPoolTokenRateEvent(poolTokenSupply, _targetToken, targetReserveBalance, targetReserveWeight); // dispatch price data update events (deprecated events) emit PriceDataUpdate(_sourceToken, poolTokenSupply, sourceReserveBalance, sourceReserveWeight); emit PriceDataUpdate(_targetToken, poolTokenSupply, targetReserveBalance, targetReserveWeight); } /** * @dev dispatches the `TokenRateUpdate` for the pool token * only used to circumvent the `stack too deep` compiler error * * @param _poolTokenSupply total pool token supply * @param _reserveToken address of the reserve token * @param _reserveBalance reserve balance * @param _reserveWeight reserve weight */ function dispatchPoolTokenRateEvent(uint256 _poolTokenSupply, IERC20Token _reserveToken, uint256 _reserveBalance, uint32 _reserveWeight) private { emit TokenRateUpdate(anchor, _reserveToken, _reserveBalance.mul(WEIGHT_RESOLUTION), _poolTokenSupply.mul(_reserveWeight)); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"name":"_onlyOwnerCanUpdateRegistry","type":"bool"}],"name":"restrictRegistryUpdate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"reserveRatio","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"connectors","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint32"},{"name":"","type":"bool"},{"name":"","type":"bool"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"hasETHReserve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"connectorTokens","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_reserveToken","type":"address"}],"name":"reserveWeight","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sourceToken","type":"address"},{"name":"_targetToken","type":"address"},{"name":"_amount","type":"uint256"}],"name":"getReturn","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferTokenOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isActive","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"onlyOwnerCanUpdateRegistry","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptTokenOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"withdrawFromAnchor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"converterType","outputs":[{"name":"","type":"uint16"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"liquidate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"updateRegistry","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_whitelist","type":"address"}],"name":"setConversionWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"conversionFee","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"withdrawTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"prevRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferAnchorOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"}],"name":"withdrawETH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_weight","type":"uint32"}],"name":"addReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_x","type":"uint256"}],"name":"decimalLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"connectorTokenCount","outputs":[{"name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"registry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_reserveTokens","type":"address[]"},{"name":"_reserveAmounts","type":"uint256[]"},{"name":"_minReturn","type":"uint256"}],"name":"addLiquidity","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxConversionFee","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"reserveTokenCount","outputs":[{"name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_values","type":"uint256[]"}],"name":"geometricMean","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"_sourceToken","type":"address"},{"name":"_targetToken","type":"address"},{"name":"_amount","type":"uint256"}],"name":"targetAmountAndFee","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"},{"name":"_reserveTokens","type":"address[]"},{"name":"_reserveMinReturnAmounts","type":"uint256[]"}],"name":"removeLiquidity","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"restoreRegistry","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_n","type":"uint256"},{"name":"_d","type":"uint256"}],"name":"roundDiv","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"conversionsEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"conversionWhitelist","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"fund","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"acceptAnchorOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"reserveTokens","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isV28OrHigher","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"anchor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"newOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"reserves","outputs":[{"name":"balance","type":"uint256"},{"name":"weight","type":"uint32"},{"name":"deprecated1","type":"bool"},{"name":"deprecated2","type":"bool"},{"name":"isSet","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_connectorToken","type":"address"}],"name":"getConnectorBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_reserveToken","type":"address"}],"name":"reserveBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sourceToken","type":"address"},{"name":"_targetToken","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_trader","type":"address"},{"name":"_beneficiary","type":"address"}],"name":"convert","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_conversionFee","type":"uint32"}],"name":"setConversionFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_token","type":"address"},{"name":"_registry","type":"address"},{"name":"_maxConversionFee","type":"uint32"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_connectorToken","type":"address"},{"indexed":false,"name":"_tokenSupply","type":"uint256"},{"indexed":false,"name":"_connectorBalance","type":"uint256"},{"indexed":false,"name":"_connectorWeight","type":"uint32"}],"name":"PriceDataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_provider","type":"address"},{"indexed":true,"name":"_reserveToken","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_newBalance","type":"uint256"},{"indexed":false,"name":"_newSupply","type":"uint256"}],"name":"LiquidityAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_provider","type":"address"},{"indexed":true,"name":"_reserveToken","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_newBalance","type":"uint256"},{"indexed":false,"name":"_newSupply","type":"uint256"}],"name":"LiquidityRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_anchor","type":"address"},{"indexed":false,"name":"_activated","type":"bool"}],"name":"Activation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_fromToken","type":"address"},{"indexed":true,"name":"_toToken","type":"address"},{"indexed":true,"name":"_trader","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_return","type":"uint256"},{"indexed":false,"name":"_conversionFee","type":"int256"}],"name":"Conversion","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_token1","type":"address"},{"indexed":true,"name":"_token2","type":"address"},{"indexed":false,"name":"_rateN","type":"uint256"},{"indexed":false,"name":"_rateD","type":"uint256"}],"name":"TokenRateUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_prevFee","type":"uint32"},{"indexed":false,"name":"_newFee","type":"uint32"}],"name":"ConversionFeeUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_prevOwner","type":"address"},{"indexed":true,"name":"_newOwner","type":"address"}],"name":"OwnerUpdate","type":"event"}]
Contract Creation Code
60806040526003805460a860020a60ff02191690557fc0829421c1d260bd3cb3e0f06cfe2d52db2ce3150000000000000000000000006008553480156200004557600080fd5b5060405160608062004bb883398101604090815281516020830151919092015160008054600160a060020a031916331790558282828282828180620000938164010000000062000140810204565b5060028054600160a060020a03909216600160a060020a031992831681179091556003805490921617905582620000d38164010000000062000140810204565b81620000e881640100000000620001bb810204565b505060048054600160a060020a03909416600160a060020a031990941693909317909255506008805463ffffffff9092166401000000000267ffffffff00000000199092169190911790555062000234945050505050565b600160a060020a0381161515620001b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4552525f494e56414c49445f4144445245535300000000000000000000000000604482015290519081900360640190fd5b50565b620f424063ffffffff82161115620001b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4552525f494e56414c49445f434f4e56455253494f4e5f464545000000000000604482015290519081900360640190fd5b61497480620002446000396000f3006080604052600436106102585763ffffffff60e060020a600035041663024c7ec781146102e45780630c7d5cd8146102fe5780630e53aae91461032c57806312c2aca41461038157806319b64015146103aa5780631cfab290146103de5780631e1401f8146103ff57806321e6b53d1461044257806322f3e2d4146104635780632fe8a6ad1461047857806338a5e0161461048d578063395900d4146104a25780633e8ff43f146104cc578063415f1240146104f857806349d10b64146105105780634af80f0e1461052557806354fd4d5014610546578063579cd3ca1461055b5780635e35359e1461057057806361cd756e1461059a57806367b6d57c146105af578063690d8320146105d05780636a49d2c4146105f15780636aa5332c1461061b57806371f52bf31461064557806379ba50971461065a5780637b1039991461066f5780637d8916bd146106845780638da5cb5b1461070757806394c275ad1461071c5780639b99a8e214610731578063a60e772414610746578063af94b8d81461079b578063b127c0a5146107c5578063b4a176d314610858578063bbb7e5d81461086d578063bf75455814610888578063c45d3d921461089d578063ca1d209d146108b2578063cdc91c69146108bd578063d031370b146108d2578063d260529c146108ea578063d3fb73b4146108ff578063d4ee1d9014610914578063d55ec69714610929578063d66bd5241461093e578063d89595121461095f578063dc8de37914610980578063e8dc12ff146109a1578063ecbca55d146109cb578063f2fde38b146109e9578063fc0c546a14610a0a575b6000805160206148c983398151915260005260076020527fb2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0f546601000000000000900460ff1615156102e2576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b005b3480156102f057600080fd5b506102e26004351515610a1f565b34801561030a57600080fd5b50610313610a67565b6040805163ffffffff9092168252519081900360200190f35b34801561033857600080fd5b5061034d600160a060020a0360043516610a73565b6040805195865263ffffffff9094166020860152911515848401521515606084015215156080830152519081900360a00190f35b34801561038d57600080fd5b50610396610b0e565b604080519115158252519081900360200190f35b3480156103b657600080fd5b506103c2600435610b57565b60408051600160a060020a039092168252519081900360200190f35b3480156103ea57600080fd5b50610313600160a060020a0360043516610b83565b34801561040b57600080fd5b50610429600160a060020a0360043581169060243516604435610bb5565b6040805192835260208301919091528051918290030190f35b34801561044e57600080fd5b506102e2600160a060020a0360043516610bcf565b34801561046f57600080fd5b50610396610be3565b34801561048457600080fd5b50610396610c7c565b34801561049957600080fd5b506102e2610c9d565b3480156104ae57600080fd5b506102e2600160a060020a0360043581169060243516604435610d0a565b3480156104d857600080fd5b506104e1610da9565b6040805161ffff9092168252519081900360200190f35b34801561050457600080fd5b506102e2600435610dae565b34801561051c57600080fd5b506102e2611002565b34801561053157600080fd5b506102e2600160a060020a036004351661126f565b34801561055257600080fd5b506104e16112b1565b34801561056757600080fd5b506103136112b6565b34801561057c57600080fd5b506102e2600160a060020a03600435811690602435166044356112ce565b3480156105a657600080fd5b506103c26113e8565b3480156105bb57600080fd5b506102e2600160a060020a03600435166113f7565b3480156105dc57600080fd5b506102e2600160a060020a036004351661149e565b3480156105fd57600080fd5b506102e2600160a060020a036004351663ffffffff602435166115bf565b34801561062757600080fd5b506106336004356117fe565b60408051918252519081900360200190f35b34801561065157600080fd5b506104e1611823565b34801561066657600080fd5b506102e2611832565b34801561067b57600080fd5b506103c26118f3565b604080516020600480358082013583810280860185019096528085526102e295369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975050933594506119029350505050565b34801561071357600080fd5b506103c2611c12565b34801561072857600080fd5b50610313611c21565b34801561073d57600080fd5b506104e1611c35565b34801561075257600080fd5b506040805160206004803580820135838102808601850190965280855261063395369593946024949385019291829185019084908082843750949750611c3b9650505050505050565b3480156107a757600080fd5b50610429600160a060020a0360043581169060243516604435611c91565b3480156107d157600080fd5b506040805160206004602480358281013584810280870186019097528086526102e296843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750611e369650505050505050565b34801561086457600080fd5b506102e2611f6f565b34801561087957600080fd5b50610633600435602435611fa8565b34801561089457600080fd5b50610396611fc2565b3480156108a957600080fd5b506103c2611fc7565b6102e2600435611fd6565b3480156108c957600080fd5b506102e26124ec565b3480156108de57600080fd5b506103c2600435612545565b3480156108f657600080fd5b50610396610da9565b34801561090b57600080fd5b506103c261256d565b34801561092057600080fd5b506103c261257c565b34801561093557600080fd5b506102e261258b565b34801561094a57600080fd5b5061034d600160a060020a0360043516612638565b34801561096b57600080fd5b50610633600160a060020a036004351661267e565b34801561098c57600080fd5b50610633600160a060020a036004351661268f565b610633600160a060020a0360043581169060243581169060443590606435811690608435166126b8565b3480156109d757600080fd5b506102e263ffffffff60043516612927565b3480156109f557600080fd5b506102e2600160a060020a0360043516612a1c565b348015610a1657600080fd5b506103c2612ab9565b610a27612ac8565b60038054911515740100000000000000000000000000000000000000000274ff000000000000000000000000000000000000000019909216919091179055565b60085463ffffffff1681565b6000806000806000610a8361483b565b50505050600160a060020a03929092166000908152600760209081526040808320815160a081018352815480825260019092015463ffffffff811694820185905260ff64010000000082048116151594830194909452650100000000008104841615156060830152660100000000000090049092161515608090920182905295919450919250829190565b6000805160206148c983398151915260005260076020527fb2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0f546601000000000000900460ff1690565b6000600682815481101515610b6857fe5b600091825260209091200154600160a060020a031692915050565b600081610b8f81612b18565b5050600160a060020a031660009081526007602052604090206001015463ffffffff1690565b600080610bc3858585611c91565b91509150935093915050565b610bd7612ac8565b610be0816113f7565b50565b60048054604080517f8da5cb5b00000000000000000000000000000000000000000000000000000000815290516000933093600160a060020a031692638da5cb5b928183019260209282900301818887803b158015610c4157600080fd5b505af1158015610c55573d6000803e3d6000fd5b505050506040513d6020811015610c6b57600080fd5b5051600160a060020a031614905090565b60035474010000000000000000000000000000000000000000900460ff1681565b6001610ca7611c35565b61ffff1611610d00576040805160e560020a62461bcd02815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f434f554e5400000000000000604482015290519081900360640190fd5b610d08612b85565b565b610d12612ac8565b60048054604080517f5e35359e000000000000000000000000000000000000000000000000000000008152600160a060020a038781169482019490945285841660248201526044810185905290519290911691635e35359e9160648082019260009290919082900301818387803b158015610d8c57600080fd5b505af1158015610da0573d6000803e3d6000fd5b50505050505050565b600190565b600060606000610dbc612b95565b6003805460a860020a60ff02191660a860020a17905560008411610e2a576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f5a45524f5f414d4f554e540000000000000000000000000000000000604482015290519081900360640190fd5b600480546040805160e060020a6318160ddd0281529051600160a060020a03909216926318160ddd9282820192602092908290030181600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b505050506040513d6020811015610e9b57600080fd5b505160048054604080517fa24835d100000000000000000000000000000000000000000000000000000000815233938101939093526024830188905251929550600160a060020a03169163a24835d19160448082019260009290919082900301818387803b158015610f0c57600080fd5b505af1158015610f20573d6000803e3d6000fd5b50505050600680549050604051908082528060200260200182016040528015610f53578160200160208202803883390190505b509150600090505b8151811015610f865760018282815181101515610f7457fe5b60209081029091010152600101610f5b565b610fec6006805480602002602001604051908101604052809291908181526020018280548015610fdf57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610fc1575b5050505050838587612bf7565b50506003805460a860020a60ff02191690555050565b60008054600160a060020a0316331480611037575060035474010000000000000000000000000000000000000000900460ff16155b151561107b576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b6110a47f436f6e7472616374526567697374727900000000000000000000000000000000612ebc565b600254909150600160a060020a038083169116148015906110cd5750600160a060020a03811615155b1515611123576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e56414c49445f5245474953545259000000000000000000000000604482015290519081900360640190fd5b604080517fbb34534c0000000000000000000000000000000000000000000000000000000081527f436f6e747261637452656769737472790000000000000000000000000000000060048201529051600091600160a060020a0384169163bb34534c9160248082019260209290919082900301818787803b1580156111a757600080fd5b505af11580156111bb573d6000803e3d6000fd5b505050506040513d60208110156111d157600080fd5b5051600160a060020a03161415611232576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e56414c49445f5245474953545259000000000000000000000000604482015290519081900360640190fd5b6002805460038054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff19928316179092559091169216919091179055565b611277612ac8565b8061128181612f54565b506005805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b601e81565b60085468010000000000000000900463ffffffff1681565b60006112d8612b95565b6003805460a860020a60ff02191660a860020a1790556112f6612ac8565b61130d6000805160206148e9833981519152612ebc565b600160a060020a0385166000908152600760205260409020600101549091506601000000000000900460ff16158061134a5750611348610be3565b155b806113625750600054600160a060020a038281169116145b15156113a6576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b6113b1848484612fb5565b600160a060020a0384166000908152600760205260409020600101546601000000000000900460ff1615610fec57610fec84612fe6565b600354600160a060020a031681565b6113ff612ac8565b6000805160206148e9833981519152611417816130db565b60048054604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a03868116948201949094529051929091169163f2fde38b9160248082019260009290919082900301818387803b15801561148257600080fd5b505af1158015611496573d6000803e3d6000fd5b505050505050565b60006114a8612b95565b6003805460a860020a60ff02191660a860020a1790556114c6612ac8565b6000805160206148c98339815191526114de81612b18565b6114f56000805160206148e9833981519152612ebc565b91506114ff610be3565b15806115185750600054600160a060020a038381169116145b151561155c576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b604051600160a060020a03841690303180156108fc02916000818181858888f19350505050158015611592573d6000803e3d6000fd5b506115aa6000805160206148c9833981519152612fe6565b50506003805460a860020a60ff021916905550565b60006115c9612ac8565b6115d1613131565b826115db8161318e565b836115e581612f54565b836115ef816131ee565b600454600160a060020a038781169116148015906116335750600160a060020a0386166000908152600760205260409020600101546601000000000000900460ff16155b1515611677576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b60085463ffffffff908116620f424003811690861611156116e2576040805160e560020a62461bcd02815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f574549474854000000000000604482015290519081900360640190fd5b61ffff6116ed611c35565b61ffff1610611746576040805160e560020a62461bcd02815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f434f554e5400000000000000604482015290519081900360640190fd5b505050600160a060020a0390921660008181526007602052604081208181556001908101805466ff0000000000001963ffffffff80881663ffffffff1993841617919091166601000000000000179092556006805493840181559093527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f909101805473ffffffffffffffffffffffffffffffffffffffff191690931790925560088054808416909401909216921691909117905550565b600080825b600081111561181c5760019190910190600a9004611803565b5092915050565b600061182d611c35565b905090565b600154600160a060020a03163314611882576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b60015460008054604051600160a060020a0393841693909116917f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a91a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b600254600160a060020a031681565b600080600061190f612b95565b6003805460a860020a60ff02191660a860020a17905561192d613263565b6119388686866132c1565b600092505b85518310156119f65785516000805160206148c98339815191529087908590811061196457fe5b90602001906020020151600160a060020a031614156119eb5734858481518110151561198c57fe5b60209081029091010151146119eb576040805160e560020a62461bcd02815260206004820152601760248201527f4552525f4554485f414d4f554e545f4d49534d41544348000000000000000000604482015290519081900360640190fd5b60019092019161193d565b6000341115611a9b576000805160206148c983398151915260005260076020527fb2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0f546601000000000000900460ff161515611a9b576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f4e4f5f4554485f524553455256450000000000000000000000000000604482015290519081900360640190fd5b600480546040805160e060020a6318160ddd0281529051600160a060020a03909216926318160ddd9282820192602092908290030181600087803b158015611ae257600080fd5b505af1158015611af6573d6000803e3d6000fd5b505050506040513d6020811015611b0c57600080fd5b50519150611b1b86868461357d565b905083811015611b75576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f52455455524e5f544f4f5f4c4f570000000000000000000000000000604482015290519081900360640190fd5b60048054604080517f867904b400000000000000000000000000000000000000000000000000000000815233938101939093526024830184905251600160a060020a039091169163867904b491604480830192600092919082900301818387803b158015611be257600080fd5b505af1158015611bf6573d6000803e3d6000fd5b50506003805460a860020a60ff02191690555050505050505050565b600054600160a060020a031681565b600854640100000000900463ffffffff1681565b60065490565b80516000908190815b81811015611c7857611c6c8582815181101515611c5d57fe5b906020019060200201516117fe565b90920191600101611c44565b6001611c848484611fa8565b03600a0a95945050505050565b600080600080611c9f613263565b86611ca981612b18565b86611cb381612b18565b600160a060020a038981169089161415611d17576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f53414d455f534f555243455f54415247455400000000000000000000604482015290519081900360640190fd5b611d2e6000805160206148a9833981519152612ebc565b600160a060020a03166394491fab611d458b61268f565b600160a060020a038c1660009081526007602052604090206001015463ffffffff16611d708c61268f565b600160a060020a038d16600090815260076020908152604080832060010154815163ffffffff89811660e060020a028252600482019890985295871660248701526044860194909452949092166064840152608483018d9052925160a48084019492939192918390030190829087803b158015611dec57600080fd5b505af1158015611e00573d6000803e3d6000fd5b505050506040513d6020811015611e1657600080fd5b50519350611e23846135ac565b9384900399939850929650505050505050565b6000611e40612b95565b6003805460a860020a60ff02191660a860020a179055611e5e613263565b611e698383866132c1565b600480546040805160e060020a6318160ddd0281529051600160a060020a03909216926318160ddd9282820192602092908290030181600087803b158015611eb057600080fd5b505af1158015611ec4573d6000803e3d6000fd5b505050506040513d6020811015611eda57600080fd5b505160048054604080517fa24835d100000000000000000000000000000000000000000000000000000000815233938101939093526024830188905251929350600160a060020a03169163a24835d19160448082019260009290919082900301818387803b158015611f4b57600080fd5b505af1158015611f5f573d6000803e3d6000fd5b50505050610fec83838387612bf7565b611f77612ac8565b6003546002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909216919091179055565b600081600281048401811515611fba57fe5b049392505050565b600181565b600554600160a060020a031681565b600080600080600080600080600080611fed612b95565b6003805460a860020a60ff02191660a860020a17905561200b6135e8565b6000805160206148c9833981519152600052600760205260008051602061492983398151915254612042903463ffffffff61362a16565b6000805160206148c983398151915260009081526007602090815260008051602061492983398151915292909255600480546040805160e060020a6318160ddd0281529051600160a060020a03909216946318160ddd948285019491939283900390910190829087803b1580156120b857600080fd5b505af11580156120cc573d6000803e3d6000fd5b505050506040513d60208110156120e257600080fd5b505199506120fd6000805160206148a9833981519152612ebc565b6006549099509750600096505b8787101561244a57600680548890811061212057fe5b9060005260206000200160009054906101000a9004600160a060020a031695506007600087600160a060020a0316600160a060020a0316815260200190815260200160002060000154945088600160a060020a031663ebbb21588b87600860009054906101000a900463ffffffff168f6040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b1580156121ea57600080fd5b505af11580156121fe573d6000803e3d6000fd5b505050506040513d602081101561221457600080fd5b50519350600160a060020a0386166000805160206148c9833981519152141561237657833411156122745760405133903486900380156108fc02916000818181858888f1935050505015801561226e573d6000803e3d6000fd5b50612371565b833410156123715734156122d2576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f494e56414c49445f4554485f56414c55450000000000000000000000604482015290519081900360640190fd5b6008546122fa906c010000000000000000000000009004600160a060020a031633308761368a565b6008600c9054906101000a9004600160a060020a0316600160a060020a0316632e1a7d4d856040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b15801561235857600080fd5b505af115801561236c573d6000803e3d6000fd5b505050505b612382565b6123828633308761368a565b612392858563ffffffff61377216565b600160a060020a038716600090815260076020526040902081905592506123bf8a8c63ffffffff61377216565b60408051868152602081018690528082018390529051919350600160a060020a0388169133917f4a1a2a6176e9646d9e3157f7c2ab3c499f18337c0b0828cfb28e0a61de4a11f7919081900360600190a350600160a060020a03851660009081526007602052604090206001015463ffffffff1661243f828785846137cf565b60019096019561210a565b60048054604080517f867904b40000000000000000000000000000000000000000000000000000000081523393810193909352602483018e905251600160a060020a039091169163867904b491604480830192600092919082900301818387803b1580156124b757600080fd5b505af11580156124cb573d6000803e3d6000fd5b50506003805460a860020a60ff021916905550505050505050505050505050565b6124f4612ac8565b6124fc61383e565b60045460408051600160a060020a0390921682526001602083015280517fa170412ae067fdeca19fd2204ce7eb66f723d827f4af15433b6f33f7fdc642bb9281900390910190a1565b600680548290811061255357fe5b600091825260209091200154600160a060020a0316905081565b600454600160a060020a031681565b600154600160a060020a031681565b6000612595612ac8565b6125ac6000805160206148e9833981519152612ebc565b90506125b781612a1c565b604080517f90f58c96000000000000000000000000000000000000000000000000000000008152601e60048201529051600160a060020a038316916390f58c9691602480830192600092919082900301818387803b15801561261857600080fd5b505af115801561262c573d6000803e3d6000fd5b50505050610be0611832565b6007602052600090815260409020805460019091015463ffffffff81169060ff640100000000820481169165010000000000810482169166010000000000009091041685565b60006126898261268f565b92915050565b60008161269b81612b18565b5050600160a060020a031660009081526007602052604090205490565b60006126c2612b95565b6003805460a860020a60ff02191660a860020a1790557f42616e636f724e6574776f726b00000000000000000000000000000000000000612702816130db565b600160a060020a038781169087161415612766576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f53414d455f534f555243455f54415247455400000000000000000000604482015290519081900360640190fd5b600554600160a060020a031615806128a95750600554604080517f3af32abf000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015291519190921691633af32abf9160248083019260209291908290030181600087803b1580156127e157600080fd5b505af11580156127f5573d6000803e3d6000fd5b505050506040513d602081101561280b57600080fd5b505180156128a95750600554604080517f3af32abf000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015291519190921691633af32abf9160248083019260209291908290030181600087803b15801561287c57600080fd5b505af1158015612890573d6000803e3d6000fd5b505050506040513d60208110156128a657600080fd5b50515b15156128ff576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f4e4f545f57484954454c495354454400000000000000000000000000604482015290519081900360640190fd5b61290c8787878787613925565b6003805460a860020a60ff0219169055979650505050505050565b61292f612ac8565b60085463ffffffff6401000000009091048116908216111561299b576040805160e560020a62461bcd02815260206004820152601a60248201527f4552525f494e56414c49445f434f4e56455253494f4e5f464545000000000000604482015290519081900360640190fd5b6008546040805163ffffffff6801000000000000000090930483168152918316602083015280517f81cd2ffb37dd237c0e4e2a3de5265fcf9deb43d3e7801e80db9f1ccfba7ee6009281900390910190a16008805463ffffffff90921668010000000000000000026bffffffff000000000000000019909216919091179055565b612a24612ac8565b600054600160a060020a0382811691161415612a8a576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f53414d455f4f574e4552000000000000000000000000000000000000604482015290519081900360640190fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600454600160a060020a031690565b600054600160a060020a03163314610d08576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b600160a060020a0381166000908152600760205260409020600101546601000000000000900460ff161515610be0576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b612b8d612ac8565b610d086124ec565b60035460a860020a900460ff1615610d08576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f5245454e5452414e4359000000000000000000000000000000000000604482015290519081900360640190fd5b600080600080600080600080612c0b6135e8565b612c226000805160206148a9833981519152612ebc565b9750612c348a8a63ffffffff61362a16565b9650600095505b8b51861015612eae578b86815181101515612c5257fe5b9060200190602002015194506007600086600160a060020a0316600160a060020a0316815260200190815260200160002060000154935087600160a060020a0316638074590a8b86600860009054906101000a900463ffffffff168d6040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b158015612d0857600080fd5b505af1158015612d1c573d6000803e3d6000fd5b505050506040513d6020811015612d3257600080fd5b50518b519093508b9087908110612d4557fe5b60209081029091010151831015612da6576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f5a45524f5f5441524745545f414d4f554e5400000000000000000000604482015290519081900360640190fd5b612db6848463ffffffff61362a16565b600160a060020a03861660008181526007602052604090208290559092506000805160206148c98339815191521415612e1c57604051339084156108fc029085906000818181858888f19350505050158015612e16573d6000803e3d6000fd5b50612e27565b612e27853385613bf8565b60408051848152602081018490528082018990529051600160a060020a0387169133917fbc7d19d505c7ec4db83f3b51f19fb98c4c8a99922e7839d1ee608dfbee29501b9181900360600190a350600160a060020a03841660009081526007602052604090206001015463ffffffff16612ea3878684846137cf565b600190950194612c3b565b505050505050505050505050565b600254604080517fbb34534c000000000000000000000000000000000000000000000000000000008152600481018490529051600092600160a060020a03169163bb34534c91602480830192602092919082900301818787803b158015612f2257600080fd5b505af1158015612f36573d6000803e3d6000fd5b505050506040513d6020811015612f4c57600080fd5b505192915050565b600160a060020a038116301415610be0576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f414444524553535f49535f53454c4600000000000000000000000000604482015290519081900360640190fd5b612fbd612ac8565b82612fc78161318e565b82612fd18161318e565b83612fdb81612f54565b611496868686613bf8565b80612ff081612b18565b600160a060020a0382166000805160206148c9833981519152141561303057600160a060020a0382166000908152600760205260409020303190556130d7565b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038416916370a082319160248083019260209291908290030181600087803b15801561309157600080fd5b505af11580156130a5573d6000803e3d6000fd5b505050506040513d60208110156130bb57600080fd5b5051600160a060020a0383166000908152600760205260409020555b5050565b6130e481612ebc565b600160a060020a03163314610be0576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b613139610be3565b15610d08576040805160e560020a62461bcd02815260206004820152600a60248201527f4552525f41435449564500000000000000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0381161515610be0576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f494e56414c49445f4144445245535300000000000000000000000000604482015290519081900360640190fd5b60008163ffffffff1611801561320d5750620f424063ffffffff821611155b1515610be0576040805160e560020a62461bcd02815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f574549474854000000000000604482015290519081900360640190fd5b61326b610be3565b1515610d08576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f494e4143544956450000000000000000000000000000000000000000604482015290519081900360640190fd5b60065483516000918291811461330f576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b84518114613367576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f494e56414c49445f414d4f554e540000000000000000000000000000604482015290519081900360640190fd5b600092505b808310156135255760076000878581518110151561338657fe5b6020908102909101810151600160a060020a031682528101919091526040016000206001015460ff66010000000000009091041615156133fe576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b600091505b8082101561346657858281518110151561341957fe5b90602001906020020151600160a060020a031660068481548110151561343b57fe5b600091825260209091200154600160a060020a0316141561345b57613466565b600190910190613403565b8082106134ab576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b600085848151811015156134bb57fe5b602090810290910101511161351a576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f494e56414c49445f414d4f554e540000000000000000000000000000604482015290519081900360640190fd5b60019092019161336c565b60008411611496576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f5a45524f5f414d4f554e540000000000000000000000000000000000604482015290519081900360640190fd5b6000811515613597576135908484613caf565b90506135a5565b6135a2848484613eb6565b90505b9392505050565b60085460009061268990620f4240906135dc90859063ffffffff6801000000000000000090910481169061427616565b9063ffffffff6142ef16565b60065460005b818110156130d75761362260068281548110151561360857fe5b600091825260209091200154600160a060020a0316612fe6565b6001016135ee565b600081831015613684576040805160e560020a62461bcd02815260206004820152600d60248201527f4552525f554e444552464c4f5700000000000000000000000000000000000000604482015290519081900360640190fd5b50900390565b604080517f7472616e7366657246726f6d28616464726573732c616464726573732c75696e81527f74323536290000000000000000000000000000000000000000000000000000006020808301919091528251918290036025018220600160a060020a038088166024850152861660448401526064808401869052845180850390910181526084909301909352810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff199093169290921790915261376c90859061435d565b50505050565b6000828201838110156135a5576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b600454600160a060020a0380851691167f77f29993cf2c084e726f7e802da0719d6a0ade3e204badc7a3ffd57ecb768c2461380d85620f4240614276565b6138208863ffffffff8088169061427616565b6040805192835260208301919091528051918290030190a350505050565b613846612ac8565b6000613850611c35565b61ffff16116138a9576040805160e560020a62461bcd02815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f434f554e5400000000000000604482015290519081900360640190fd5b60048054604080517f79ba50970000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216926379ba509792828201926000929082900301818387803b15801561390557600080fd5b505af1158015613919573d6000803e3d6000fd5b50505050610d086135e8565b600080600080613936898989611c91565b9093509150821515613992576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f5a45524f5f5441524745545f414d4f554e5400000000000000000000604482015290519081900360640190fd5b61399b8861268f565b90508083106139a657fe5b600160a060020a0389166000805160206148c98339815191521415613a2157348714613a1c576040805160e560020a62461bcd02815260206004820152601760248201527f4552525f4554485f414d4f554e545f4d49534d41544348000000000000000000604482015290519081900360640190fd5b613b29565b34158015613ad3575086613ad0613a378b61268f565b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038e16916370a082319160248083019260209291908290030181600087803b158015613a9857600080fd5b505af1158015613aac573d6000803e3d6000fd5b505050506040513d6020811015613ac257600080fd5b50519063ffffffff61362a16565b10155b1515613b29576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f494e56414c49445f414d4f554e540000000000000000000000000000604482015290519081900360640190fd5b613b3289612fe6565b600160a060020a038816600090815260076020526040902054613b5b908463ffffffff61362a16565b600160a060020a0389166000818152600760205260409020919091556000805160206148c98339815191521415613bc857604051600160a060020a0386169084156108fc029085906000818181858888f19350505050158015613bc2573d6000803e3d6000fd5b50613bd3565b613bd3888685613bf8565b613be18989888a87876143eb565b613beb8989614470565b5090979650505050505050565b604080517f7472616e7366657228616464726573732c75696e74323536290000000000000081528151908190036019018120600160a060020a038516602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1990931692909217909152613caa90849061435d565b505050565b600080600080613cbe85611c3b565b9250600091505b8551821015613eac5785516000805160206148c983398151915290879084908110613cec57fe5b60209081029091010151600160a060020a031614613d3e57613d3e8683815181101515613d1557fe5b9060200190602002015133308886815181101515613d2f57fe5b9060200190602002015161368a565b8482815181101515613d4c57fe5b90602001906020020151600760008885815181101515613d6857fe5b6020908102909101810151600160a060020a03168252810191909152604001600020558551869083908110613d9957fe5b90602001906020020151600160a060020a031633600160a060020a03167f4a1a2a6176e9646d9e3157f7c2ab3c499f18337c0b0828cfb28e0a61de4a11f78785815181101515613de557fe5b906020019060200201518886815181101515613dfd57fe5b60209081029091018101516040805193845291830152818101889052519081900360600190a3600760008784815181101515613e3557fe5b6020908102909101810151600160a060020a0316825281019190915260400160002060010154865163ffffffff9091169150613ea1908490889085908110613e7957fe5b906020019060200201518785815181101515613e9157fe5b90602001906020020151846137cf565b600190910190613cc5565b5090949350505050565b600080600080600080600080600080613ecd6135e8565b6000805160206148c9833981519152600052600760205260008051602061492983398151915254613f04903463ffffffff61362a16565b6000805160206148c9833981519152600052600760205260008051602061492983398151915255613f426000805160206148a9833981519152612ebc565b9850613f50898c8f8f61467e565b9750613f628b8963ffffffff61377216565b9650600095505b8c51861015614265578c86815181101515613f8057fe5b9060200190602002015194506007600086600160a060020a0316600160a060020a0316815260200190815260200160002060000154935088600160a060020a031663ebbb21588c86600860009054906101000a900463ffffffff168c6040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b15801561403657600080fd5b505af115801561404a573d6000803e3d6000fd5b505050506040513d602081101561406057600080fd5b50519250600083116140bc576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f5a45524f5f5441524745545f414d4f554e5400000000000000000000604482015290519081900360640190fd5b8b868151811015156140ca57fe5b602090810290910101518311156140dd57fe5b600160a060020a0385166000805160206148c98339815191521461410c576141078533308661368a565b61417f565b828c8781518110151561411b57fe5b90602001906020020151111561417f5733600160a060020a03166108fc848e8981518110151561414757fe5b90602001906020020151039081150290604051600060405180830381858888f1935050505015801561417d573d6000803e3d6000fd5b505b61418f848463ffffffff61377216565b600160a060020a03861660008181526007602090815260409182902084905581518781529081018490528082018b90529051929450909133917f4a1a2a6176e9646d9e3157f7c2ab3c499f18337c0b0828cfb28e0a61de4a11f7919081900360600190a3600760008e8881518110151561420557fe5b6020908102909101810151600160a060020a03168252810191909152604001600020600101548d5163ffffffff909116915061425a9088908f908990811061424957fe5b9060200190602002015184846137cf565b600190950194613f69565b50959b9a5050505050505050505050565b600080831515614289576000915061181c565b5082820282848281151561429957fe5b04146135a5576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b600080808311614349576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f4449564944455f42595f5a45524f0000000000000000000000000000604482015290519081900360640190fd5b828481151561435457fe5b04949350505050565b614365614869565b602060405190810160405280600181525090506020818351602085016000875af180151561439257600080fd5b5080511515613caa576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f5452414e534645525f4641494c454400000000000000000000000000604482015290519081900360640190fd5b7f8000000000000000000000000000000000000000000000000000000000000000811061441457fe5b60408051848152602081018490528082018390529051600160a060020a038087169288821692918a16917f276856b36cbc45526a0ba64f44611557a2a8b68662c5388e9fe6d72e86e1c8cb9181900360600190a4505050505050565b6000806000806000806000600460009054906101000a9004600160a060020a0316600160a060020a03166318160ddd6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156144ce57600080fd5b505af11580156144e2573d6000803e3d6000fd5b505050506040513d60208110156144f857600080fd5b505196506145058961268f565b95506145108861268f565b600160a060020a03808b16600090815260076020526040808220600190810154938d1683529120015491965063ffffffff90811695509081169350614559908690869061427616565b915061456e8663ffffffff8086169061427616565b60408051848152602081018390528151929350600160a060020a03808c1693908d16927f77f29993cf2c084e726f7e802da0719d6a0ade3e204badc7a3ffd57ecb768c24928290030190a36145c5878a88876137cf565b6145d1878987866137cf565b604080518881526020810188905263ffffffff8616818301529051600160a060020a038b16917f8a6a7f53b3c8fa1dc4b83e3f1be668c1b251ff8d44cdcb83eb3acec3fec6a788919081900360600190a2604080518881526020810187905263ffffffff8516818301529051600160a060020a038a16917f8a6a7f53b3c8fa1dc4b83e3f1be668c1b251ff8d44cdcb83eb3acec3fec6a788919081900360600190a2505050505050505050565b60008060015b8451811015614741576146e96007600087848151811015156146a257fe5b6020908102909101810151600160a060020a031682528101919091526040016000205485518690859081106146d357fe5b602090810290910101519063ffffffff61427616565b61472f6007600088868151811015156146fe57fe5b6020908102909101810151600160a060020a031682528101919091526040016000205486518790859081106146d357fe5b1015614739578091505b600101614684565b86600160a060020a0316632f55bdb58760076000898781518110151561476357fe5b6020908102909101810151600160a060020a0316825281019190915260400160002054600854885163ffffffff909116908990889081106147a057fe5b906020019060200201516040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b15801561480457600080fd5b505af1158015614818573d6000803e3d6000fd5b505050506040513d602081101561482e57600080fd5b5051979650505050505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b602060405190810160405280600190602082028038833950919291505056004552525f494e56414c49445f524553455256450000000000000000000000000042616e636f72466f726d756c6100000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee42616e636f72436f6e76657274657255706772616465720000000000000000004552525f4143434553535f44454e494544000000000000000000000000000000b2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0ea165627a7a723058208ac6a9739e89dc82908965c8f0959f549da7cb06de5a581cb9b21b2afd9ede1d0029000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000052ae12abe5d8bd778bd5397f99ca900624cfadd40000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102585763ffffffff60e060020a600035041663024c7ec781146102e45780630c7d5cd8146102fe5780630e53aae91461032c57806312c2aca41461038157806319b64015146103aa5780631cfab290146103de5780631e1401f8146103ff57806321e6b53d1461044257806322f3e2d4146104635780632fe8a6ad1461047857806338a5e0161461048d578063395900d4146104a25780633e8ff43f146104cc578063415f1240146104f857806349d10b64146105105780634af80f0e1461052557806354fd4d5014610546578063579cd3ca1461055b5780635e35359e1461057057806361cd756e1461059a57806367b6d57c146105af578063690d8320146105d05780636a49d2c4146105f15780636aa5332c1461061b57806371f52bf31461064557806379ba50971461065a5780637b1039991461066f5780637d8916bd146106845780638da5cb5b1461070757806394c275ad1461071c5780639b99a8e214610731578063a60e772414610746578063af94b8d81461079b578063b127c0a5146107c5578063b4a176d314610858578063bbb7e5d81461086d578063bf75455814610888578063c45d3d921461089d578063ca1d209d146108b2578063cdc91c69146108bd578063d031370b146108d2578063d260529c146108ea578063d3fb73b4146108ff578063d4ee1d9014610914578063d55ec69714610929578063d66bd5241461093e578063d89595121461095f578063dc8de37914610980578063e8dc12ff146109a1578063ecbca55d146109cb578063f2fde38b146109e9578063fc0c546a14610a0a575b6000805160206148c983398151915260005260076020527fb2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0f546601000000000000900460ff1615156102e2576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b005b3480156102f057600080fd5b506102e26004351515610a1f565b34801561030a57600080fd5b50610313610a67565b6040805163ffffffff9092168252519081900360200190f35b34801561033857600080fd5b5061034d600160a060020a0360043516610a73565b6040805195865263ffffffff9094166020860152911515848401521515606084015215156080830152519081900360a00190f35b34801561038d57600080fd5b50610396610b0e565b604080519115158252519081900360200190f35b3480156103b657600080fd5b506103c2600435610b57565b60408051600160a060020a039092168252519081900360200190f35b3480156103ea57600080fd5b50610313600160a060020a0360043516610b83565b34801561040b57600080fd5b50610429600160a060020a0360043581169060243516604435610bb5565b6040805192835260208301919091528051918290030190f35b34801561044e57600080fd5b506102e2600160a060020a0360043516610bcf565b34801561046f57600080fd5b50610396610be3565b34801561048457600080fd5b50610396610c7c565b34801561049957600080fd5b506102e2610c9d565b3480156104ae57600080fd5b506102e2600160a060020a0360043581169060243516604435610d0a565b3480156104d857600080fd5b506104e1610da9565b6040805161ffff9092168252519081900360200190f35b34801561050457600080fd5b506102e2600435610dae565b34801561051c57600080fd5b506102e2611002565b34801561053157600080fd5b506102e2600160a060020a036004351661126f565b34801561055257600080fd5b506104e16112b1565b34801561056757600080fd5b506103136112b6565b34801561057c57600080fd5b506102e2600160a060020a03600435811690602435166044356112ce565b3480156105a657600080fd5b506103c26113e8565b3480156105bb57600080fd5b506102e2600160a060020a03600435166113f7565b3480156105dc57600080fd5b506102e2600160a060020a036004351661149e565b3480156105fd57600080fd5b506102e2600160a060020a036004351663ffffffff602435166115bf565b34801561062757600080fd5b506106336004356117fe565b60408051918252519081900360200190f35b34801561065157600080fd5b506104e1611823565b34801561066657600080fd5b506102e2611832565b34801561067b57600080fd5b506103c26118f3565b604080516020600480358082013583810280860185019096528085526102e295369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975050933594506119029350505050565b34801561071357600080fd5b506103c2611c12565b34801561072857600080fd5b50610313611c21565b34801561073d57600080fd5b506104e1611c35565b34801561075257600080fd5b506040805160206004803580820135838102808601850190965280855261063395369593946024949385019291829185019084908082843750949750611c3b9650505050505050565b3480156107a757600080fd5b50610429600160a060020a0360043581169060243516604435611c91565b3480156107d157600080fd5b506040805160206004602480358281013584810280870186019097528086526102e296843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750611e369650505050505050565b34801561086457600080fd5b506102e2611f6f565b34801561087957600080fd5b50610633600435602435611fa8565b34801561089457600080fd5b50610396611fc2565b3480156108a957600080fd5b506103c2611fc7565b6102e2600435611fd6565b3480156108c957600080fd5b506102e26124ec565b3480156108de57600080fd5b506103c2600435612545565b3480156108f657600080fd5b50610396610da9565b34801561090b57600080fd5b506103c261256d565b34801561092057600080fd5b506103c261257c565b34801561093557600080fd5b506102e261258b565b34801561094a57600080fd5b5061034d600160a060020a0360043516612638565b34801561096b57600080fd5b50610633600160a060020a036004351661267e565b34801561098c57600080fd5b50610633600160a060020a036004351661268f565b610633600160a060020a0360043581169060243581169060443590606435811690608435166126b8565b3480156109d757600080fd5b506102e263ffffffff60043516612927565b3480156109f557600080fd5b506102e2600160a060020a0360043516612a1c565b348015610a1657600080fd5b506103c2612ab9565b610a27612ac8565b60038054911515740100000000000000000000000000000000000000000274ff000000000000000000000000000000000000000019909216919091179055565b60085463ffffffff1681565b6000806000806000610a8361483b565b50505050600160a060020a03929092166000908152600760209081526040808320815160a081018352815480825260019092015463ffffffff811694820185905260ff64010000000082048116151594830194909452650100000000008104841615156060830152660100000000000090049092161515608090920182905295919450919250829190565b6000805160206148c983398151915260005260076020527fb2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0f546601000000000000900460ff1690565b6000600682815481101515610b6857fe5b600091825260209091200154600160a060020a031692915050565b600081610b8f81612b18565b5050600160a060020a031660009081526007602052604090206001015463ffffffff1690565b600080610bc3858585611c91565b91509150935093915050565b610bd7612ac8565b610be0816113f7565b50565b60048054604080517f8da5cb5b00000000000000000000000000000000000000000000000000000000815290516000933093600160a060020a031692638da5cb5b928183019260209282900301818887803b158015610c4157600080fd5b505af1158015610c55573d6000803e3d6000fd5b505050506040513d6020811015610c6b57600080fd5b5051600160a060020a031614905090565b60035474010000000000000000000000000000000000000000900460ff1681565b6001610ca7611c35565b61ffff1611610d00576040805160e560020a62461bcd02815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f434f554e5400000000000000604482015290519081900360640190fd5b610d08612b85565b565b610d12612ac8565b60048054604080517f5e35359e000000000000000000000000000000000000000000000000000000008152600160a060020a038781169482019490945285841660248201526044810185905290519290911691635e35359e9160648082019260009290919082900301818387803b158015610d8c57600080fd5b505af1158015610da0573d6000803e3d6000fd5b50505050505050565b600190565b600060606000610dbc612b95565b6003805460a860020a60ff02191660a860020a17905560008411610e2a576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f5a45524f5f414d4f554e540000000000000000000000000000000000604482015290519081900360640190fd5b600480546040805160e060020a6318160ddd0281529051600160a060020a03909216926318160ddd9282820192602092908290030181600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b505050506040513d6020811015610e9b57600080fd5b505160048054604080517fa24835d100000000000000000000000000000000000000000000000000000000815233938101939093526024830188905251929550600160a060020a03169163a24835d19160448082019260009290919082900301818387803b158015610f0c57600080fd5b505af1158015610f20573d6000803e3d6000fd5b50505050600680549050604051908082528060200260200182016040528015610f53578160200160208202803883390190505b509150600090505b8151811015610f865760018282815181101515610f7457fe5b60209081029091010152600101610f5b565b610fec6006805480602002602001604051908101604052809291908181526020018280548015610fdf57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610fc1575b5050505050838587612bf7565b50506003805460a860020a60ff02191690555050565b60008054600160a060020a0316331480611037575060035474010000000000000000000000000000000000000000900460ff16155b151561107b576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b6110a47f436f6e7472616374526567697374727900000000000000000000000000000000612ebc565b600254909150600160a060020a038083169116148015906110cd5750600160a060020a03811615155b1515611123576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e56414c49445f5245474953545259000000000000000000000000604482015290519081900360640190fd5b604080517fbb34534c0000000000000000000000000000000000000000000000000000000081527f436f6e747261637452656769737472790000000000000000000000000000000060048201529051600091600160a060020a0384169163bb34534c9160248082019260209290919082900301818787803b1580156111a757600080fd5b505af11580156111bb573d6000803e3d6000fd5b505050506040513d60208110156111d157600080fd5b5051600160a060020a03161415611232576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e56414c49445f5245474953545259000000000000000000000000604482015290519081900360640190fd5b6002805460038054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff19928316179092559091169216919091179055565b611277612ac8565b8061128181612f54565b506005805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b601e81565b60085468010000000000000000900463ffffffff1681565b60006112d8612b95565b6003805460a860020a60ff02191660a860020a1790556112f6612ac8565b61130d6000805160206148e9833981519152612ebc565b600160a060020a0385166000908152600760205260409020600101549091506601000000000000900460ff16158061134a5750611348610be3565b155b806113625750600054600160a060020a038281169116145b15156113a6576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b6113b1848484612fb5565b600160a060020a0384166000908152600760205260409020600101546601000000000000900460ff1615610fec57610fec84612fe6565b600354600160a060020a031681565b6113ff612ac8565b6000805160206148e9833981519152611417816130db565b60048054604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a03868116948201949094529051929091169163f2fde38b9160248082019260009290919082900301818387803b15801561148257600080fd5b505af1158015611496573d6000803e3d6000fd5b505050505050565b60006114a8612b95565b6003805460a860020a60ff02191660a860020a1790556114c6612ac8565b6000805160206148c98339815191526114de81612b18565b6114f56000805160206148e9833981519152612ebc565b91506114ff610be3565b15806115185750600054600160a060020a038381169116145b151561155c576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b604051600160a060020a03841690303180156108fc02916000818181858888f19350505050158015611592573d6000803e3d6000fd5b506115aa6000805160206148c9833981519152612fe6565b50506003805460a860020a60ff021916905550565b60006115c9612ac8565b6115d1613131565b826115db8161318e565b836115e581612f54565b836115ef816131ee565b600454600160a060020a038781169116148015906116335750600160a060020a0386166000908152600760205260409020600101546601000000000000900460ff16155b1515611677576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b60085463ffffffff908116620f424003811690861611156116e2576040805160e560020a62461bcd02815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f574549474854000000000000604482015290519081900360640190fd5b61ffff6116ed611c35565b61ffff1610611746576040805160e560020a62461bcd02815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f434f554e5400000000000000604482015290519081900360640190fd5b505050600160a060020a0390921660008181526007602052604081208181556001908101805466ff0000000000001963ffffffff80881663ffffffff1993841617919091166601000000000000179092556006805493840181559093527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f909101805473ffffffffffffffffffffffffffffffffffffffff191690931790925560088054808416909401909216921691909117905550565b600080825b600081111561181c5760019190910190600a9004611803565b5092915050565b600061182d611c35565b905090565b600154600160a060020a03163314611882576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b60015460008054604051600160a060020a0393841693909116917f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a91a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b600254600160a060020a031681565b600080600061190f612b95565b6003805460a860020a60ff02191660a860020a17905561192d613263565b6119388686866132c1565b600092505b85518310156119f65785516000805160206148c98339815191529087908590811061196457fe5b90602001906020020151600160a060020a031614156119eb5734858481518110151561198c57fe5b60209081029091010151146119eb576040805160e560020a62461bcd02815260206004820152601760248201527f4552525f4554485f414d4f554e545f4d49534d41544348000000000000000000604482015290519081900360640190fd5b60019092019161193d565b6000341115611a9b576000805160206148c983398151915260005260076020527fb2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0f546601000000000000900460ff161515611a9b576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f4e4f5f4554485f524553455256450000000000000000000000000000604482015290519081900360640190fd5b600480546040805160e060020a6318160ddd0281529051600160a060020a03909216926318160ddd9282820192602092908290030181600087803b158015611ae257600080fd5b505af1158015611af6573d6000803e3d6000fd5b505050506040513d6020811015611b0c57600080fd5b50519150611b1b86868461357d565b905083811015611b75576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f52455455524e5f544f4f5f4c4f570000000000000000000000000000604482015290519081900360640190fd5b60048054604080517f867904b400000000000000000000000000000000000000000000000000000000815233938101939093526024830184905251600160a060020a039091169163867904b491604480830192600092919082900301818387803b158015611be257600080fd5b505af1158015611bf6573d6000803e3d6000fd5b50506003805460a860020a60ff02191690555050505050505050565b600054600160a060020a031681565b600854640100000000900463ffffffff1681565b60065490565b80516000908190815b81811015611c7857611c6c8582815181101515611c5d57fe5b906020019060200201516117fe565b90920191600101611c44565b6001611c848484611fa8565b03600a0a95945050505050565b600080600080611c9f613263565b86611ca981612b18565b86611cb381612b18565b600160a060020a038981169089161415611d17576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f53414d455f534f555243455f54415247455400000000000000000000604482015290519081900360640190fd5b611d2e6000805160206148a9833981519152612ebc565b600160a060020a03166394491fab611d458b61268f565b600160a060020a038c1660009081526007602052604090206001015463ffffffff16611d708c61268f565b600160a060020a038d16600090815260076020908152604080832060010154815163ffffffff89811660e060020a028252600482019890985295871660248701526044860194909452949092166064840152608483018d9052925160a48084019492939192918390030190829087803b158015611dec57600080fd5b505af1158015611e00573d6000803e3d6000fd5b505050506040513d6020811015611e1657600080fd5b50519350611e23846135ac565b9384900399939850929650505050505050565b6000611e40612b95565b6003805460a860020a60ff02191660a860020a179055611e5e613263565b611e698383866132c1565b600480546040805160e060020a6318160ddd0281529051600160a060020a03909216926318160ddd9282820192602092908290030181600087803b158015611eb057600080fd5b505af1158015611ec4573d6000803e3d6000fd5b505050506040513d6020811015611eda57600080fd5b505160048054604080517fa24835d100000000000000000000000000000000000000000000000000000000815233938101939093526024830188905251929350600160a060020a03169163a24835d19160448082019260009290919082900301818387803b158015611f4b57600080fd5b505af1158015611f5f573d6000803e3d6000fd5b50505050610fec83838387612bf7565b611f77612ac8565b6003546002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909216919091179055565b600081600281048401811515611fba57fe5b049392505050565b600181565b600554600160a060020a031681565b600080600080600080600080600080611fed612b95565b6003805460a860020a60ff02191660a860020a17905561200b6135e8565b6000805160206148c9833981519152600052600760205260008051602061492983398151915254612042903463ffffffff61362a16565b6000805160206148c983398151915260009081526007602090815260008051602061492983398151915292909255600480546040805160e060020a6318160ddd0281529051600160a060020a03909216946318160ddd948285019491939283900390910190829087803b1580156120b857600080fd5b505af11580156120cc573d6000803e3d6000fd5b505050506040513d60208110156120e257600080fd5b505199506120fd6000805160206148a9833981519152612ebc565b6006549099509750600096505b8787101561244a57600680548890811061212057fe5b9060005260206000200160009054906101000a9004600160a060020a031695506007600087600160a060020a0316600160a060020a0316815260200190815260200160002060000154945088600160a060020a031663ebbb21588b87600860009054906101000a900463ffffffff168f6040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b1580156121ea57600080fd5b505af11580156121fe573d6000803e3d6000fd5b505050506040513d602081101561221457600080fd5b50519350600160a060020a0386166000805160206148c9833981519152141561237657833411156122745760405133903486900380156108fc02916000818181858888f1935050505015801561226e573d6000803e3d6000fd5b50612371565b833410156123715734156122d2576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f494e56414c49445f4554485f56414c55450000000000000000000000604482015290519081900360640190fd5b6008546122fa906c010000000000000000000000009004600160a060020a031633308761368a565b6008600c9054906101000a9004600160a060020a0316600160a060020a0316632e1a7d4d856040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b15801561235857600080fd5b505af115801561236c573d6000803e3d6000fd5b505050505b612382565b6123828633308761368a565b612392858563ffffffff61377216565b600160a060020a038716600090815260076020526040902081905592506123bf8a8c63ffffffff61377216565b60408051868152602081018690528082018390529051919350600160a060020a0388169133917f4a1a2a6176e9646d9e3157f7c2ab3c499f18337c0b0828cfb28e0a61de4a11f7919081900360600190a350600160a060020a03851660009081526007602052604090206001015463ffffffff1661243f828785846137cf565b60019096019561210a565b60048054604080517f867904b40000000000000000000000000000000000000000000000000000000081523393810193909352602483018e905251600160a060020a039091169163867904b491604480830192600092919082900301818387803b1580156124b757600080fd5b505af11580156124cb573d6000803e3d6000fd5b50506003805460a860020a60ff021916905550505050505050505050505050565b6124f4612ac8565b6124fc61383e565b60045460408051600160a060020a0390921682526001602083015280517fa170412ae067fdeca19fd2204ce7eb66f723d827f4af15433b6f33f7fdc642bb9281900390910190a1565b600680548290811061255357fe5b600091825260209091200154600160a060020a0316905081565b600454600160a060020a031681565b600154600160a060020a031681565b6000612595612ac8565b6125ac6000805160206148e9833981519152612ebc565b90506125b781612a1c565b604080517f90f58c96000000000000000000000000000000000000000000000000000000008152601e60048201529051600160a060020a038316916390f58c9691602480830192600092919082900301818387803b15801561261857600080fd5b505af115801561262c573d6000803e3d6000fd5b50505050610be0611832565b6007602052600090815260409020805460019091015463ffffffff81169060ff640100000000820481169165010000000000810482169166010000000000009091041685565b60006126898261268f565b92915050565b60008161269b81612b18565b5050600160a060020a031660009081526007602052604090205490565b60006126c2612b95565b6003805460a860020a60ff02191660a860020a1790557f42616e636f724e6574776f726b00000000000000000000000000000000000000612702816130db565b600160a060020a038781169087161415612766576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f53414d455f534f555243455f54415247455400000000000000000000604482015290519081900360640190fd5b600554600160a060020a031615806128a95750600554604080517f3af32abf000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015291519190921691633af32abf9160248083019260209291908290030181600087803b1580156127e157600080fd5b505af11580156127f5573d6000803e3d6000fd5b505050506040513d602081101561280b57600080fd5b505180156128a95750600554604080517f3af32abf000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015291519190921691633af32abf9160248083019260209291908290030181600087803b15801561287c57600080fd5b505af1158015612890573d6000803e3d6000fd5b505050506040513d60208110156128a657600080fd5b50515b15156128ff576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f4e4f545f57484954454c495354454400000000000000000000000000604482015290519081900360640190fd5b61290c8787878787613925565b6003805460a860020a60ff0219169055979650505050505050565b61292f612ac8565b60085463ffffffff6401000000009091048116908216111561299b576040805160e560020a62461bcd02815260206004820152601a60248201527f4552525f494e56414c49445f434f4e56455253494f4e5f464545000000000000604482015290519081900360640190fd5b6008546040805163ffffffff6801000000000000000090930483168152918316602083015280517f81cd2ffb37dd237c0e4e2a3de5265fcf9deb43d3e7801e80db9f1ccfba7ee6009281900390910190a16008805463ffffffff90921668010000000000000000026bffffffff000000000000000019909216919091179055565b612a24612ac8565b600054600160a060020a0382811691161415612a8a576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f53414d455f4f574e4552000000000000000000000000000000000000604482015290519081900360640190fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600454600160a060020a031690565b600054600160a060020a03163314610d08576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b600160a060020a0381166000908152600760205260409020600101546601000000000000900460ff161515610be0576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b612b8d612ac8565b610d086124ec565b60035460a860020a900460ff1615610d08576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f5245454e5452414e4359000000000000000000000000000000000000604482015290519081900360640190fd5b600080600080600080600080612c0b6135e8565b612c226000805160206148a9833981519152612ebc565b9750612c348a8a63ffffffff61362a16565b9650600095505b8b51861015612eae578b86815181101515612c5257fe5b9060200190602002015194506007600086600160a060020a0316600160a060020a0316815260200190815260200160002060000154935087600160a060020a0316638074590a8b86600860009054906101000a900463ffffffff168d6040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b158015612d0857600080fd5b505af1158015612d1c573d6000803e3d6000fd5b505050506040513d6020811015612d3257600080fd5b50518b519093508b9087908110612d4557fe5b60209081029091010151831015612da6576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f5a45524f5f5441524745545f414d4f554e5400000000000000000000604482015290519081900360640190fd5b612db6848463ffffffff61362a16565b600160a060020a03861660008181526007602052604090208290559092506000805160206148c98339815191521415612e1c57604051339084156108fc029085906000818181858888f19350505050158015612e16573d6000803e3d6000fd5b50612e27565b612e27853385613bf8565b60408051848152602081018490528082018990529051600160a060020a0387169133917fbc7d19d505c7ec4db83f3b51f19fb98c4c8a99922e7839d1ee608dfbee29501b9181900360600190a350600160a060020a03841660009081526007602052604090206001015463ffffffff16612ea3878684846137cf565b600190950194612c3b565b505050505050505050505050565b600254604080517fbb34534c000000000000000000000000000000000000000000000000000000008152600481018490529051600092600160a060020a03169163bb34534c91602480830192602092919082900301818787803b158015612f2257600080fd5b505af1158015612f36573d6000803e3d6000fd5b505050506040513d6020811015612f4c57600080fd5b505192915050565b600160a060020a038116301415610be0576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f414444524553535f49535f53454c4600000000000000000000000000604482015290519081900360640190fd5b612fbd612ac8565b82612fc78161318e565b82612fd18161318e565b83612fdb81612f54565b611496868686613bf8565b80612ff081612b18565b600160a060020a0382166000805160206148c9833981519152141561303057600160a060020a0382166000908152600760205260409020303190556130d7565b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038416916370a082319160248083019260209291908290030181600087803b15801561309157600080fd5b505af11580156130a5573d6000803e3d6000fd5b505050506040513d60208110156130bb57600080fd5b5051600160a060020a0383166000908152600760205260409020555b5050565b6130e481612ebc565b600160a060020a03163314610be0576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b613139610be3565b15610d08576040805160e560020a62461bcd02815260206004820152600a60248201527f4552525f41435449564500000000000000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0381161515610be0576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f494e56414c49445f4144445245535300000000000000000000000000604482015290519081900360640190fd5b60008163ffffffff1611801561320d5750620f424063ffffffff821611155b1515610be0576040805160e560020a62461bcd02815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f574549474854000000000000604482015290519081900360640190fd5b61326b610be3565b1515610d08576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f494e4143544956450000000000000000000000000000000000000000604482015290519081900360640190fd5b60065483516000918291811461330f576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b84518114613367576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f494e56414c49445f414d4f554e540000000000000000000000000000604482015290519081900360640190fd5b600092505b808310156135255760076000878581518110151561338657fe5b6020908102909101810151600160a060020a031682528101919091526040016000206001015460ff66010000000000009091041615156133fe576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b600091505b8082101561346657858281518110151561341957fe5b90602001906020020151600160a060020a031660068481548110151561343b57fe5b600091825260209091200154600160a060020a0316141561345b57613466565b600190910190613403565b8082106134ab576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b600085848151811015156134bb57fe5b602090810290910101511161351a576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f494e56414c49445f414d4f554e540000000000000000000000000000604482015290519081900360640190fd5b60019092019161336c565b60008411611496576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f5a45524f5f414d4f554e540000000000000000000000000000000000604482015290519081900360640190fd5b6000811515613597576135908484613caf565b90506135a5565b6135a2848484613eb6565b90505b9392505050565b60085460009061268990620f4240906135dc90859063ffffffff6801000000000000000090910481169061427616565b9063ffffffff6142ef16565b60065460005b818110156130d75761362260068281548110151561360857fe5b600091825260209091200154600160a060020a0316612fe6565b6001016135ee565b600081831015613684576040805160e560020a62461bcd02815260206004820152600d60248201527f4552525f554e444552464c4f5700000000000000000000000000000000000000604482015290519081900360640190fd5b50900390565b604080517f7472616e7366657246726f6d28616464726573732c616464726573732c75696e81527f74323536290000000000000000000000000000000000000000000000000000006020808301919091528251918290036025018220600160a060020a038088166024850152861660448401526064808401869052845180850390910181526084909301909352810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff199093169290921790915261376c90859061435d565b50505050565b6000828201838110156135a5576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b600454600160a060020a0380851691167f77f29993cf2c084e726f7e802da0719d6a0ade3e204badc7a3ffd57ecb768c2461380d85620f4240614276565b6138208863ffffffff8088169061427616565b6040805192835260208301919091528051918290030190a350505050565b613846612ac8565b6000613850611c35565b61ffff16116138a9576040805160e560020a62461bcd02815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f434f554e5400000000000000604482015290519081900360640190fd5b60048054604080517f79ba50970000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216926379ba509792828201926000929082900301818387803b15801561390557600080fd5b505af1158015613919573d6000803e3d6000fd5b50505050610d086135e8565b600080600080613936898989611c91565b9093509150821515613992576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f5a45524f5f5441524745545f414d4f554e5400000000000000000000604482015290519081900360640190fd5b61399b8861268f565b90508083106139a657fe5b600160a060020a0389166000805160206148c98339815191521415613a2157348714613a1c576040805160e560020a62461bcd02815260206004820152601760248201527f4552525f4554485f414d4f554e545f4d49534d41544348000000000000000000604482015290519081900360640190fd5b613b29565b34158015613ad3575086613ad0613a378b61268f565b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038e16916370a082319160248083019260209291908290030181600087803b158015613a9857600080fd5b505af1158015613aac573d6000803e3d6000fd5b505050506040513d6020811015613ac257600080fd5b50519063ffffffff61362a16565b10155b1515613b29576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f494e56414c49445f414d4f554e540000000000000000000000000000604482015290519081900360640190fd5b613b3289612fe6565b600160a060020a038816600090815260076020526040902054613b5b908463ffffffff61362a16565b600160a060020a0389166000818152600760205260409020919091556000805160206148c98339815191521415613bc857604051600160a060020a0386169084156108fc029085906000818181858888f19350505050158015613bc2573d6000803e3d6000fd5b50613bd3565b613bd3888685613bf8565b613be18989888a87876143eb565b613beb8989614470565b5090979650505050505050565b604080517f7472616e7366657228616464726573732c75696e74323536290000000000000081528151908190036019018120600160a060020a038516602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1990931692909217909152613caa90849061435d565b505050565b600080600080613cbe85611c3b565b9250600091505b8551821015613eac5785516000805160206148c983398151915290879084908110613cec57fe5b60209081029091010151600160a060020a031614613d3e57613d3e8683815181101515613d1557fe5b9060200190602002015133308886815181101515613d2f57fe5b9060200190602002015161368a565b8482815181101515613d4c57fe5b90602001906020020151600760008885815181101515613d6857fe5b6020908102909101810151600160a060020a03168252810191909152604001600020558551869083908110613d9957fe5b90602001906020020151600160a060020a031633600160a060020a03167f4a1a2a6176e9646d9e3157f7c2ab3c499f18337c0b0828cfb28e0a61de4a11f78785815181101515613de557fe5b906020019060200201518886815181101515613dfd57fe5b60209081029091018101516040805193845291830152818101889052519081900360600190a3600760008784815181101515613e3557fe5b6020908102909101810151600160a060020a0316825281019190915260400160002060010154865163ffffffff9091169150613ea1908490889085908110613e7957fe5b906020019060200201518785815181101515613e9157fe5b90602001906020020151846137cf565b600190910190613cc5565b5090949350505050565b600080600080600080600080600080613ecd6135e8565b6000805160206148c9833981519152600052600760205260008051602061492983398151915254613f04903463ffffffff61362a16565b6000805160206148c9833981519152600052600760205260008051602061492983398151915255613f426000805160206148a9833981519152612ebc565b9850613f50898c8f8f61467e565b9750613f628b8963ffffffff61377216565b9650600095505b8c51861015614265578c86815181101515613f8057fe5b9060200190602002015194506007600086600160a060020a0316600160a060020a0316815260200190815260200160002060000154935088600160a060020a031663ebbb21588c86600860009054906101000a900463ffffffff168c6040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b15801561403657600080fd5b505af115801561404a573d6000803e3d6000fd5b505050506040513d602081101561406057600080fd5b50519250600083116140bc576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f5a45524f5f5441524745545f414d4f554e5400000000000000000000604482015290519081900360640190fd5b8b868151811015156140ca57fe5b602090810290910101518311156140dd57fe5b600160a060020a0385166000805160206148c98339815191521461410c576141078533308661368a565b61417f565b828c8781518110151561411b57fe5b90602001906020020151111561417f5733600160a060020a03166108fc848e8981518110151561414757fe5b90602001906020020151039081150290604051600060405180830381858888f1935050505015801561417d573d6000803e3d6000fd5b505b61418f848463ffffffff61377216565b600160a060020a03861660008181526007602090815260409182902084905581518781529081018490528082018b90529051929450909133917f4a1a2a6176e9646d9e3157f7c2ab3c499f18337c0b0828cfb28e0a61de4a11f7919081900360600190a3600760008e8881518110151561420557fe5b6020908102909101810151600160a060020a03168252810191909152604001600020600101548d5163ffffffff909116915061425a9088908f908990811061424957fe5b9060200190602002015184846137cf565b600190950194613f69565b50959b9a5050505050505050505050565b600080831515614289576000915061181c565b5082820282848281151561429957fe5b04146135a5576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b600080808311614349576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f4449564944455f42595f5a45524f0000000000000000000000000000604482015290519081900360640190fd5b828481151561435457fe5b04949350505050565b614365614869565b602060405190810160405280600181525090506020818351602085016000875af180151561439257600080fd5b5080511515613caa576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f5452414e534645525f4641494c454400000000000000000000000000604482015290519081900360640190fd5b7f8000000000000000000000000000000000000000000000000000000000000000811061441457fe5b60408051848152602081018490528082018390529051600160a060020a038087169288821692918a16917f276856b36cbc45526a0ba64f44611557a2a8b68662c5388e9fe6d72e86e1c8cb9181900360600190a4505050505050565b6000806000806000806000600460009054906101000a9004600160a060020a0316600160a060020a03166318160ddd6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156144ce57600080fd5b505af11580156144e2573d6000803e3d6000fd5b505050506040513d60208110156144f857600080fd5b505196506145058961268f565b95506145108861268f565b600160a060020a03808b16600090815260076020526040808220600190810154938d1683529120015491965063ffffffff90811695509081169350614559908690869061427616565b915061456e8663ffffffff8086169061427616565b60408051848152602081018390528151929350600160a060020a03808c1693908d16927f77f29993cf2c084e726f7e802da0719d6a0ade3e204badc7a3ffd57ecb768c24928290030190a36145c5878a88876137cf565b6145d1878987866137cf565b604080518881526020810188905263ffffffff8616818301529051600160a060020a038b16917f8a6a7f53b3c8fa1dc4b83e3f1be668c1b251ff8d44cdcb83eb3acec3fec6a788919081900360600190a2604080518881526020810187905263ffffffff8516818301529051600160a060020a038a16917f8a6a7f53b3c8fa1dc4b83e3f1be668c1b251ff8d44cdcb83eb3acec3fec6a788919081900360600190a2505050505050505050565b60008060015b8451811015614741576146e96007600087848151811015156146a257fe5b6020908102909101810151600160a060020a031682528101919091526040016000205485518690859081106146d357fe5b602090810290910101519063ffffffff61427616565b61472f6007600088868151811015156146fe57fe5b6020908102909101810151600160a060020a031682528101919091526040016000205486518790859081106146d357fe5b1015614739578091505b600101614684565b86600160a060020a0316632f55bdb58760076000898781518110151561476357fe5b6020908102909101810151600160a060020a0316825281019190915260400160002054600854885163ffffffff909116908990889081106147a057fe5b906020019060200201516040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b15801561480457600080fd5b505af1158015614818573d6000803e3d6000fd5b505050506040513d602081101561482e57600080fd5b5051979650505050505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b602060405190810160405280600190602082028038833950919291505056004552525f494e56414c49445f524553455256450000000000000000000000000042616e636f72466f726d756c6100000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee42616e636f72436f6e76657274657255706772616465720000000000000000004552525f4143434553535f44454e494544000000000000000000000000000000b2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0ea165627a7a723058208ac6a9739e89dc82908965c8f0959f549da7cb06de5a581cb9b21b2afd9ede1d0029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000052ae12abe5d8bd778bd5397f99ca900624cfadd40000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _token (address): 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF
Arg [1] : _registry (address): 0x52Ae12ABe5D8BD778BD5397F99cA900624CfADD4
Arg [2] : _maxConversionFee (uint32): 0
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
Arg [1] : 00000000000000000000000052ae12abe5d8bd778bd5397f99ca900624cfadd4
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
50358:24032:0:-;;;;;;;;-1:-1:-1;50358:24032:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30816:29:0;;:8;:29;;:35;;;;;;;30808:67;;;;;;;-1:-1:-1;;;;;30808:67:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;30808:67:0;;;;;;;;;;;;;;;50358:24032;14809:224;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;14809:224:0;;;;;;;25747:30;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25747:30:0;;;;;;;;;;;;;;;;;;;;;;;44285:235;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;44285:235:0;;;-1:-1:-1;;;;;44285:235:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39114:113;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39114:113:0;;;;;;;;;;;;;;;;;;;;;;44594:136;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;44594:136:0;;;;;;;;;-1:-1:-1;;;;;44594:136:0;;;;;;;;;;;;;;38256:204;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;38256:204:0;;;-1:-1:-1;;;;;38256:204:0;;;45202:208;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;45202:208:0;-1:-1:-1;;;;;45202:208:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43925:121;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;43925:121:0;;;-1:-1:-1;;;;;43925:121:0;;;32901:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32901:104:0;;;;12496:38;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12496:38:0;;;;47879:220;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47879:220:0;;;;34428:157;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;34428:157:0;-1:-1:-1;;;;;34428:157:0;;;;;;;;;;;;51758:81;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51758:81:0;;;;;;;;;;;;;;;;;;;;;;;61849:542;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61849:542:0;;;;;13454:925;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13454:925:0;;;;32630:175;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;32630:175:0;;;-1:-1:-1;;;;;32630:175:0;;;25207:35;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25207:35:0;;;;26128:31;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26128:31:0;;;;35529:660;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;35529:660:0;-1:-1:-1;;;;;35529:660:0;;;;;;;;;;;;12406:37;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12406:37:0;;;;33355:180;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;33355:180:0;;;-1:-1:-1;;;;;33355:180:0;;;31448:554;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;31448:554:0;;;-1:-1:-1;;;;;31448:554:0;;;37301:744;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;37301:744:0;;;-1:-1:-1;;;;;37301:744:0;;;;;;;70991:180;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;70991:180:0;;;;;;;;;;;;;;;;;;;;;44804:105;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44804:105:0;;;;9587:208;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9587:208:0;;;;12317:33;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12317:33:0;;;;56124:1402;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56124:1402:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56124:1402:0;;;;-1:-1:-1;56124:1402:0;-1:-1:-1;56124:1402:0;;-1:-1:-1;56124:1402:0;;;;;;;;;-1:-1:-1;56124:1402:0;;-1:-1:-1;;56124:1402:0;;;-1:-1:-1;56124:1402:0;;-1:-1:-1;;;;56124:1402:0;8402:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8402:20:0;;;;25885:34;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25885:34:0;;;;36897:112;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36897:112:0;;;;71804:332;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;71804:332:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71804:332:0;;-1:-1:-1;71804:332:0;;-1:-1:-1;;;;;;;71804:332:0;52687:830;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;52687:830:0;-1:-1:-1;;;;;52687:830:0;;;;;;;;;;;;57932:722;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;57932:722:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57932:722:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57932:722:0;;;;-1:-1:-1;57932:722:0;-1:-1:-1;57932:722:0;;-1:-1:-1;57932:722:0;;;;;;;;;-1:-1:-1;57932:722:0;;-1:-1:-1;57932:722:0;;-1:-1:-1;;;;;;;57932:722:0;14458:137;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14458:137:0;;;;71411:116;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;71411:116:0;;;;;;;26249:46;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26249:46:0;;;;25333:37;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25333:37:0;;;;59086:2354;;;;;;52112:140;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52112:140:0;;;;25469:34;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;25469:34:0;;;;;32177:82;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32177:82:0;;;;25251:30;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25251:30:0;;;;8429:23;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8429:23:0;;;;36412:265;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36412:265:0;;;;25606:44;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;25606:44:0;;;-1:-1:-1;;;;;25606:44:0;;;44983:145;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;44983:145:0;;;-1:-1:-1;;;;;44983:145:0;;;38729:207;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;38729:207:0;;;-1:-1:-1;;;;;38729:207:0;;;39810:747;;-1:-1:-1;;;;;39810:747:0;;;;;;;;;;;;;;;;;;;;;;;34788:265;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;34788:265:0;;;;;;;9338:158;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9338:158:0;;;-1:-1:-1;;;;;9338:158:0;;;43763:88;;8:9:-1;5:2;;;30:1;27;20:12;5:2;43763:88:0;;;;14809:224;8900:12;:10;:12::i;:::-;14969:26;:56;;;;;;;-1:-1:-1;;14969:56:0;;;;;;;;;14809:224::o;25747:30::-;;;;;;:::o;44285:235::-;44344:7;44353:6;44361:4;44367;44373;44390:22;;:::i;:::-;-1:-1:-1;;;;;;;;;44415:18:0;;;;;;;;:8;:18;;;;;;;;44390:43;;-1:-1:-1;44390:43:0;;;;;;;;;-1:-1:-1;44390:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44415:18:0;;-1:-1:-1;44415:18:0;;44390:43;44285:235::o;39114:113::-;-1:-1:-1;;;;;;;;;;;39160:4:0;39184:29;:8;:29;;:35;;;;;;;;39114:113::o;44594:136::-;44656:11;44687:27;44715:6;44687:35;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;44687:35:0;;;-1:-1:-1;;44594:136:0:o;38256:204::-;38391:6;38358:13;29680:23;29694:8;29680:13;:23::i;:::-;-1:-1:-1;;;;;;;38422:23:0;;;;;:8;:23;;;;;-1:-1:-1;38422:30:0;;;;;38256:204::o;45202:208::-;45311:7;45320;45347:55;45366:12;45380;45394:7;45347:18;:55::i;:::-;45340:62;;;;45202:208;;;;;;:::o;43925:121::-;8900:12;:10;:12::i;:::-;44004:34;44028:9;44004:23;:34::i;:::-;43925:121;:::o;32901:104::-;32966:6;;;:14;;;;;;;;32942:4;;32992;;-1:-1:-1;;;;;32966:6:0;;:12;;:14;;;;;;;;;;;32942:4;32966:6;:14;;;5:2:-1;;;;30:1;27;20:12;5:2;32966:14:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32966:14:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;32966:14:0;-1:-1:-1;;;;;32966:31:0;;;32901:104;-1:-1:-1;32901:104:0:o;12496:38::-;;;;;;;;;:::o;47879:220::-;48021:1;47999:19;:17;:19::i;:::-;:23;;;47991:61;;;;;-1:-1:-1;;;;;47991:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48063:28;:26;:28::i;:::-;47879:220::o;34428:157::-;8900:12;:10;:12::i;:::-;34534:6;;;:43;;;;;;-1:-1:-1;;;;;34534:43:0;;;;;;;;;;;;;;;;;;;;;;;;;:6;;;;;:21;;:43;;;;;-1:-1:-1;;34534:43:0;;;;;;;;-1:-1:-1;34534:6:0;:43;;;5:2:-1;;;;30:1;27;20:12;5:2;34534:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;34534:43:0;;;;34428:157;;;:::o;51758:81::-;51830:1;51758:81;:::o;61849:542::-;61965:19;62092:40;62186:9;15949:12;:10;:12::i;:::-;15972:6;:13;;-1:-1:-1;;;;;;15972:13:0;-1:-1:-1;;;15972:13:0;;;-1:-1:-1;61921:11:0;;61913:39;;;;;-1:-1:-1;;;;;61913:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;61999:6;;;61987:33;;;-1:-1:-1;;;;;61987:33:0;;;;-1:-1:-1;;;;;61999:6:0;;;;-1:-1:-1;;61987:33:0;;;;;;;;;;;;61999:6;;61987:33;;;5:2:-1;;;;30:1;27;20:12;5:2;61987:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61987:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61987:33:0;62043:6;;;62031:48;;;;;;62059:10;62031:48;;;;;;;;;;;;;;61987:33;;-1:-1:-1;;;;;;62043:6:0;;62031:27;;:48;;;;;-1:-1:-1;;62031:48:0;;;;;;;;-1:-1:-1;62043:6:0;62031:48;;;5:2:-1;;;;30:1;27;20:12;5:2;62031:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62031:48:0;;;;62149:13;:20;;;;62135:35;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;62135:35:0;;62092:78;;62198:1;62186:13;;62181:104;62205:23;:30;62201:1;:34;62181:104;;;62284:1;62255:23;62279:1;62255:26;;;;;;;;;;;;;;;;;;:30;62237:3;;62181:104;;;62298:85;62322:13;62298:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62298:85:0;;;-1:-1:-1;62298:85:0;;;;;;;;;;;;;;;;;62337:23;62362:11;62375:7;62298:23;:85::i;:::-;-1:-1:-1;;16008:6:0;:14;;-1:-1:-1;;;;;;16008:14:0;;;-1:-1:-1;;61849:542:0:o;13454:925::-;13684:29;13571:5;;-1:-1:-1;;;;;13571:5:0;13557:10;:19;;:50;;-1:-1:-1;13581:26:0;;;;;;;13580:27;13557:50;13549:80;;;;;;;-1:-1:-1;;;;;13549:80:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;13549:80:0;;;;;;;;;;;;;;;13734:28;13744:17;13734:9;:28::i;:::-;13883:8;;13684:79;;-1:-1:-1;;;;;;13860:32:0;;;13883:8;;13860:32;;;;:61;;-1:-1:-1;;;;;;13896:25:0;;;;13860:61;13852:94;;;;;;;-1:-1:-1;;;;;13852:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14061:40;;;;;;14083:17;14061:40;;;;;;-1:-1:-1;;;;;;;14061:21:0;;;;;:40;;;;;;;;;;;;;;;-1:-1:-1;14061:21:0;:40;;;5:2:-1;;;;30:1;27;20:12;5:2;14061:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;14061:40:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;14061:40:0;-1:-1:-1;;;;;14061:54:0;;;14053:87;;;;;-1:-1:-1;;;;;14053:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14247:8;;;14232:12;:23;;-1:-1:-1;;;;;14247:8:0;;;-1:-1:-1;;14232:23:0;;;;;;;14349:22;;;;;;;;;;;13454:925::o;32630:175::-;8900:12;:10;:12::i;:::-;32737:10;10738:18;10747:8;10738;:18::i;:::-;-1:-1:-1;32765:19:0;:32;;-1:-1:-1;;32765:32:0;-1:-1:-1;;;;;32765:32:0;;;;;;;;;;32630:175::o;25207:35::-;25240:2;25207:35;:::o;26128:31::-;;;;;;;;;:::o;35529:660::-;35641:25;15949:12;:10;:12::i;:::-;15972:6;:13;;-1:-1:-1;;;;;;15972:13:0;-1:-1:-1;;;15972:13:0;;;8900:12;:10;:12::i;:::-;35669:29;-1:-1:-1;;;;;;;;;;;35669:9:0;:29::i;:::-;-1:-1:-1;;;;;35889:16:0;;;;;;:8;:16;;;;;-1:-1:-1;35889:22:0;;35641:57;;-1:-1:-1;35889:22:0;;;;;35888:23;;:38;;;35916:10;:8;:10::i;:::-;35915:11;35888:38;:68;;;-1:-1:-1;35930:5:0;;-1:-1:-1;;;;;35930:26:0;;;:5;;:26;35888:68;35880:98;;;;;;;-1:-1:-1;;;;;35880:98:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;35880:98:0;;;;;;;;;;;;;;;35989:42;36010:6;36018:3;36023:7;35989:20;:42::i;:::-;-1:-1:-1;;;;;36118:16:0;;;;;;:8;:16;;;;;-1:-1:-1;36118:22:0;;;;;;;36114:67;;;36155:26;36174:6;36155:18;:26::i;12406:37::-;;;-1:-1:-1;;;;;12406:37:0;;:::o;33355:180::-;8900:12;:10;:12::i;:::-;-1:-1:-1;;;;;;;;;;;12790:20:0;12796:13;12790:5;:20::i;:::-;33492:6;;;:35;;;;;;-1:-1:-1;;;;;33492:35:0;;;;;;;;;;;;:6;;;;;:24;;:35;;;;;-1:-1:-1;;33492:35:0;;;;;;;;-1:-1:-1;33492:6:0;:35;;;5:2:-1;;;;30:1;27;20:12;5:2;33492:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33492:35:0;;;;8923:1;33355:180;:::o;31448:554::-;31608:25;15949:12;:10;:12::i;:::-;15972:6;:13;;-1:-1:-1;;;;;;15972:13:0;-1:-1:-1;;;15972:13:0;;;8900:12;:10;:12::i;:::-;-1:-1:-1;;;;;;;;;;;29680:23:0;29694:8;29680:13;:23::i;:::-;31636:29;-1:-1:-1;;;;;;;;;;;31636:9:0;:29::i;:::-;31608:57;;31780:10;:8;:10::i;:::-;31779:11;:41;;;-1:-1:-1;31794:5:0;;-1:-1:-1;;;;;31794:26:0;;;:5;;:26;31779:41;31771:71;;;;;;;-1:-1:-1;;;;;31771:71:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;31771:71:0;;;;;;;;;;;;;;;31853:35;;-1:-1:-1;;;;;31853:12:0;;;31874:4;31866:21;31853:35;;;;;;;;;31866:21;31853:12;:35;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31853:35:0;31942:52;-1:-1:-1;;;;;;;;;;;31942:18:0;:52::i;:::-;-1:-1:-1;;16008:6:0;:14;;-1:-1:-1;;;;;;16008:14:0;;;-1:-1:-1;31448:554:0:o;37301:744::-;37816:26;8900:12;:10;:12::i;:::-;29336:11;:9;:11::i;:::-;37432:6;10384:23;10398:8;10384:13;:23::i;:::-;37457:6;10738:18;10747:8;10738;:18::i;:::-;37493:7;30388:28;30408:7;30388:19;:28::i;:::-;37571:6;;-1:-1:-1;;;;;37553:25:0;;;37571:6;;37553:25;;;;:52;;-1:-1:-1;;;;;;37583:16:0;;;;;;:8;:16;;;;;-1:-1:-1;37583:22:0;;;;;;;37582:23;37553:52;37545:84;;;;;;;-1:-1:-1;;;;;37545:84:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;37545:84:0;;;;;;;;;;;;;;;37679:12;;;;;;24660:7;37659:32;37648:43;;;;;;;37640:82;;;;;-1:-1:-1;;;;;37640:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;37741:32;:19;:17;:19::i;:::-;:32;;;37733:70;;;;;-1:-1:-1;;;;;37733:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;37845:16:0;;;;;;;;:8;:16;;;;;37872:22;;;-1:-1:-1;37905:17:0;;;:27;;-1:-1:-1;;37905:27:0;;;;-1:-1:-1;;37905:27:0;;;;37943:23;;;;;;;;;:16;27:10:-1;;23:18;;;45:23;;37977:26:0;;;;;;;;;-1:-1:-1;;37977:26:0;;;;;;;38014:12;:23;;;;;;;;;;;;;;;;;;;37301:744::o;70991:180::-;71047:7;;71108:2;71091:53;71116:1;71112;:5;71091:53;;;71141:3;;;;;;71124:2;71119:7;;71091:53;;;-1:-1:-1;71162:1:0;70991:180;-1:-1:-1;;70991:180:0:o;44804:105::-;44856:6;44882:19;:17;:19::i;:::-;44875:26;;44804:105;:::o;9587:208::-;9654:8;;-1:-1:-1;;;;;9654:8:0;9640:10;:22;9632:52;;;;;-1:-1:-1;;;;;9632:52:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;9632:52:0;;;;;;;;;;;;;;;9719:8;;;9712:5;;9700:28;;-1:-1:-1;;;;;9719:8:0;;;;9712:5;;;;9700:28;;;9747:8;;;;9739:16;;-1:-1:-1;;;;;9747:8:0;;-1:-1:-1;;9739:16:0;;;;;;;9766:21;;;9587:208::o;12317:33::-;;;-1:-1:-1;;;;;12317:33:0;;:::o;56124:1402::-;56557:9;57007:19;57168:14;15949:12;:10;:12::i;:::-;15972:6;:13;;-1:-1:-1;;;;;;15972:13:0;-1:-1:-1;;;15972:13:0;;;29077:9;:7;:9::i;:::-;56355:65;56376:14;56392:15;56409:10;56355:20;:65::i;:::-;56569:1;56557:13;;56552:195;56576:14;:21;56572:1;:25;56552:195;;;56621:17;;-1:-1:-1;;;;;;;;;;;24789:42:0;56621:14;;56636:1;;56621:17;;;;;;;;;;;;;;;-1:-1:-1;;;;;56621:40:0;;56617:130;;;56710:9;56688:15;56704:1;56688:18;;;;;;;;;;;;;;;;;;;:31;56680:67;;;;;-1:-1:-1;;;;;56680:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;56599:3;;;;;56552:195;;;56879:1;56867:9;:13;56863:98;;;-1:-1:-1;;;;;;;;;;;56903:29:0;;:8;:29;;:35;;;;;;;56895:66;;;;;;;-1:-1:-1;;;;;56895:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;57041:6;;;57029:33;;;-1:-1:-1;;;;;57029:33:0;;;;-1:-1:-1;;;;;57041:6:0;;;;-1:-1:-1;;57029:33:0;;;;;;;;;;;;57041:6;;57029:33;;;5:2:-1;;;;30:1;27;20:12;5:2;57029:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57029:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57029:33:0;;-1:-1:-1;57185:64:0;57204:14;57220:15;57029:33;57185:18;:64::i;:::-;57168:81;-1:-1:-1;57376:20:0;;;;57368:51;;;;;-1:-1:-1;;;;;57368:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;57485:6;;;57473:45;;;;;;57499:10;57473:45;;;;;;;;;;;;;;-1:-1:-1;;;;;57485:6:0;;;;57473:25;;:45;;;;;-1:-1:-1;;57473:45:0;;;;;;;-1:-1:-1;57485:6:0;57473:45;;;5:2:-1;;;;30:1;27;20:12;5:2;57473:45:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;16008:6:0;:14;;-1:-1:-1;;;;;;16008:14:0;;;-1:-1:-1;;;;;;;;56124:1402:0:o;8402:20::-;;;-1:-1:-1;;;;;8402:20:0;;:::o;25885:34::-;;;;;;;;;:::o;36897:112::-;36980:13;:20;36897:112;:::o;71804:332::-;71945:14;;71874:7;;;;;71970:90;71994:6;71990:1;:10;71970:90;;;72035:25;72049:7;72057:1;72049:10;;;;;;;;;;;;;;;;;;72035:13;:25::i;:::-;72020:40;;;;72002:3;;71970:90;;;72126:1;72094:29;72103:11;72116:6;72094:8;:29::i;:::-;:33;72086:2;72078:50;;71804:332;-1:-1:-1;;;;;71804:332:0:o;52687:830::-;52920:7;52929;53057:14;53438:11;29077:9;:7;:9::i;:::-;52852:12;29680:23;29694:8;29680:13;:23::i;:::-;52888:12;29680:23;29694:8;29680:13;:23::i;:::-;-1:-1:-1;;;;;52989:28:0;;;;;;;;52981:63;;;;;-1:-1:-1;;;;;52981:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53089:25;-1:-1:-1;;;;;;;;;;;53089:9:0;:25::i;:::-;-1:-1:-1;;;;;53074:66:0;;53155:28;53170:12;53155:14;:28::i;:::-;-1:-1:-1;;;;;53198:22:0;;;;;;:8;:22;;;;;-1:-1:-1;53198:29:0;;;;53242:28;53257:12;53242:14;:28::i;:::-;-1:-1:-1;;;;;53285:22:0;;;;;;:8;:22;;;;;;;;-1:-1:-1;53285:29:0;;53074:273;;53285:29;53074:273;;;-1:-1:-1;53074:273:0;;;;;;;;;;;;;;;;;;;;;;;;53285:29;;;;53074:273;;;;;;;;;;;;;;;;;53285:22;;53074:273;;;;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;53074:273:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53074:273:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53074:273:0;;-1:-1:-1;53452:20:0;53074:273;53452:12;:20::i;:::-;53491:12;;;;;53438:34;;-1:-1:-1;52687:830:0;;-1:-1:-1;;;;;;;52687:830:0:o;57932:722::-;58306:19;15949:12;:10;:12::i;:::-;15972:6;:13;;-1:-1:-1;;;;;;15972:13:0;-1:-1:-1;;;15972:13:0;;;29077:9;:7;:9::i;:::-;58155:71;58176:14;58192:24;58218:7;58155:20;:71::i;:::-;58340:6;;;58328:33;;;-1:-1:-1;;;;;58328:33:0;;;;-1:-1:-1;;;;;58340:6:0;;;;-1:-1:-1;;58328:33:0;;;;;;;;;;;;58340:6;;58328:33;;;5:2:-1;;;;30:1;27;20:12;5:2;58328:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58328:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58328:33:0;58422:6;;;58410:48;;;;;;58438:10;58410:48;;;;;;;;;;;;;;58328:33;;-1:-1:-1;;;;;;58422:6:0;;58410:27;;:48;;;;;-1:-1:-1;;58410:48:0;;;;;;;;-1:-1:-1;58422:6:0;58410:48;;;5:2:-1;;;;30:1;27;20:12;5:2;58410:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58410:48:0;;;;58559:87;58583:14;58599:24;58625:11;58638:7;58559:23;:87::i;14458:137::-;8900:12;:10;:12::i;:::-;14575;;14564:8;:23;;-1:-1:-1;;14564:23:0;-1:-1:-1;;;;;14575:12:0;;;14564:23;;;;;;14458:137::o;71411:116::-;71474:7;71517:2;71512:1;71517:2;71507:6;71502:2;:11;71501:18;;;;;;;;;71411:116;-1:-1:-1;;;71411:116:0:o;26249:46::-;26291:4;26249:46;:::o;25333:37::-;;;-1:-1:-1;;;;;25333:37:0;;:::o;59086:2354::-;59290:14;59351:22;59621:20;59680:9;59733:24;59791:18;59857:21;60680:25;60819:26;61141:20;15949:12;:10;:12::i;:::-;15972:6;:13;;-1:-1:-1;;;;;;15972:13:0;-1:-1:-1;;;15972:13:0;;;59153:21;:19;:21::i;:::-;-1:-1:-1;;;;;;;;;;;59225:29:0;;:8;:29;;-1:-1:-1;;;;;;;;;;;59225:37:0;:52;;59267:9;59225:52;:41;:52;:::i;:::-;-1:-1:-1;;;;;;;;;;;59185:29:0;;;;:8;:29;;;;-1:-1:-1;;;;;;;;;;;59185:92:0;;;;59319:6;;;59185:29;59307:33;;-1:-1:-1;;;;;59307:33:0;;;;-1:-1:-1;;;;;59319:6:0;;;;-1:-1:-1;;59307:33:0;;;;59185:92;;59307:33;;;;;;;;;;59319:6;59307:33;;;5:2:-1;;;;30:1;27;20:12;5:2;59307:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59307:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59307:33:0;;-1:-1:-1;59391:25:0;-1:-1:-1;;;;;;;;;;;59391:9:0;:25::i;:::-;59644:13;:20;59351:66;;-1:-1:-1;59644:20:0;-1:-1:-1;59692:1:0;;-1:-1:-1;59675:1639:0;59699:12;59695:1;:16;59675:1639;;;59760:13;:16;;59774:1;;59760:16;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59760:16:0;59733:43;;59812:8;:22;59821:12;-1:-1:-1;;;;;59812:22:0;-1:-1:-1;;;;;59812:22:0;;;;;;;;;;;;:30;;;59791:51;;59881:7;-1:-1:-1;;;;;59881:16:0;;59898:6;59906:10;59918:12;;;;;;;;;;;59932:7;59881:59;;;;;-1:-1:-1;;;59881:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59881:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59881:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59881:59:0;-1:-1:-1;;;59881:59:0;;-1:-1:-1;;;;;;60029:35:0;;;-1:-1:-1;;;;;;;;60029:35:0;60025:598;;;60101:13;60089:9;:25;60085:406;;;60139:46;;:10;;60159:9;:25;;;60139:46;;;;;;;;;60159:25;60139:10;:46;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60139:46:0;60085:406;;;60244:13;60232:9;:25;60228:263;;;60290:9;:14;60282:48;;;;;-1:-1:-1;;;;;60282:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;60370:10;;60353:61;;60370:10;;;-1:-1:-1;;;;;60370:10:0;60382;60394:4;60400:13;60353:16;:61::i;:::-;60437:10;;:34;;;;;;;;;;;;;;:10;;;;-1:-1:-1;;;;;60437:10:0;;:19;;:34;;;;;-1:-1:-1;;60437:34:0;;;;;;;;-1:-1:-1;60437:10:0;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;60437:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60437:34:0;;;;60228:263;60025:598;;;60544:63;60561:12;60575:10;60587:4;60593:13;60544:16;:63::i;:::-;60708:29;:10;60723:13;60708:29;:14;:29;:::i;:::-;-1:-1:-1;;;;;60752:22:0;;;;;;:8;:22;;;;;:50;;;;-1:-1:-1;60848:19:0;:6;60859:7;60848:10;:19::i;:::-;60958:94;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;60958:94:0;;;60973:10;;60958:94;;;;;;;;;;-1:-1:-1;;;;;;61164:22:0;;;;;;:8;:22;;;;;-1:-1:-1;61164:29:0;;;;61208:94;61235:18;61164:22;61269:17;61164:29;61208:26;:94::i;:::-;59713:3;;;;;59675:1639;;;61398:6;;;61386:46;;;;;;61412:10;61386:46;;;;;;;;;;;;;;-1:-1:-1;;;;;61398:6:0;;;;61386:25;;:46;;;;;-1:-1:-1;;61386:46:0;;;;;;;-1:-1:-1;61398:6:0;61386:46;;;5:2:-1;;;;30:1;27;20:12;5:2;61386:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;16008:6:0;:14;;-1:-1:-1;;;;;;16008:14:0;;;-1:-1:-1;;;;;;;;;;;;;59086:2354:0:o;52112:140::-;8900:12;:10;:12::i;:::-;52173:29;:27;:29::i;:::-;52231:6;;52220:24;;;-1:-1:-1;;;;;52231:6:0;;;52220:24;;-1:-1:-1;52220:24:0;;;;;;;;;;;;;;;;52112:140::o;25469:34::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;25469:34:0;;-1:-1:-1;25469:34:0;:::o;25251:30::-;;;-1:-1:-1;;;;;25251:30:0;;:::o;8429:23::-;;;-1:-1:-1;;;;;8429:23:0;;:::o;36412:265::-;36459:36;8900:12;:10;:12::i;:::-;36517:29;-1:-1:-1;;;;;;;;;;;36517:9:0;:29::i;:::-;36459:88;;36560:36;36578:17;36560;:36::i;:::-;36607:34;;;;;;25240:2;36607:34;;;;;;-1:-1:-1;;;;;36607:25:0;;;;;:34;;;;;-1:-1:-1;;36607:34:0;;;;;;;-1:-1:-1;36607:25:0;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;36607:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36607:34:0;;;;36652:17;:15;:17::i;25606:44::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;44983:145::-;45062:7;45089:31;45104:15;45089:14;:31::i;:::-;45082:38;44983:145;-1:-1:-1;;44983:145:0:o;38729:207::-;38865:7;38832:13;29680:23;29694:8;29680:13;:23::i;:::-;-1:-1:-1;;;;;;;38897:23:0;;;;;:8;:23;;;;;:31;;38729:207::o;39810:747::-;40035:7;15949:12;:10;:12::i;:::-;15972:6;:13;;-1:-1:-1;;;;;;15972:13:0;-1:-1:-1;;;15972:13:0;;;40001:14;12790:20;40001:14;12790:5;:20::i;:::-;-1:-1:-1;;;;;40095:28:0;;;;;;;;40087:63;;;;;-1:-1:-1;;;;;40087:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;40270:19;;-1:-1:-1;;;;;40270:19:0;:33;;:149;;-1:-1:-1;40325:19:0;;:42;;;;;;-1:-1:-1;;;;;40325:42:0;;;;;;;;;:19;;;;;:33;;:42;;;;;;;;;;;;;;-1:-1:-1;40325:19:0;:42;;;5:2:-1;;;;30:1;27;20:12;5:2;40325:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40325:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40325:42:0;:93;;;;-1:-1:-1;40371:19:0;;:47;;;;;;-1:-1:-1;;;;;40371:47:0;;;;;;;;;:19;;;;;:33;;:47;;;;;;;;;;;;;;-1:-1:-1;40371:19:0;:47;;;5:2:-1;;;;30:1;27;20:12;5:2;40371:47:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40371:47:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40371:47:0;40325:93;40262:198;;;;;;;-1:-1:-1;;;;;40262:198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;40480:69;40490:12;40504;40518:7;40527;40536:12;40480:9;:69::i;:::-;16008:6;:14;;-1:-1:-1;;;;;;16008:14:0;;;40473:76;;-1:-1:-1;;;;;;;39810:747:0:o;34788:265::-;8900:12;:10;:12::i;:::-;34891:16;;;;;;;;;34873:34;;;;;34865:73;;;;;-1:-1:-1;;;;;34865:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;34974:13;;34954:50;;;34974:13;;;;;;;34954:50;;;;;;;;;;;;;;;;;;;;;35015:13;:30;;;;;;;;-1:-1:-1;;35015:30:0;;;;;;;;;34788:265::o;9338:158::-;8900:12;:10;:12::i;:::-;9433:5;;-1:-1:-1;;;;;9420:18:0;;;9433:5;;9420:18;;9412:45;;;;;-1:-1:-1;;;;;9412:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;9468:8;:20;;-1:-1:-1;;9468:20:0;-1:-1:-1;;;;;9468:20:0;;;;;;;;;;9338:158::o;43763:88::-;43837:6;;-1:-1:-1;;;;;43837:6:0;;43763:88::o;8987:104::-;9056:5;;-1:-1:-1;;;;;9056:5:0;9042:10;:19;9034:49;;;;;-1:-1:-1;;;;;9034:49:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;9034:49:0;;;;;;;;;;;;;;29778:134;-1:-1:-1;;;;;29856:18:0;;;;;;:8;:18;;;;;-1:-1:-1;29856:24:0;;;;;;;29848:56;;;;;;;-1:-1:-1;;;;;29848:56:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;29848:56:0;;;;;;;;;;;;;;44120:91;8900:12;:10;:12::i;:::-;44180:23;:21;:23::i;16085:89::-;16141:6;;-1:-1:-1;;;16141:6:0;;;;16140:7;16132:34;;;;;-1:-1:-1;;;;;16132:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;68599:1560;68818:22;68895:26;68967:9;69029:24;69088:18;69154:21;69368:25;69979:20;68784:21;:19;:21::i;:::-;68858:25;-1:-1:-1;;;;;;;;;;;68858:9:0;:25::i;:::-;68818:66;-1:-1:-1;68924:25:0;:12;68941:7;68924:25;:16;:25;:::i;:::-;68895:54;;68979:1;68967:13;;68962:1190;68986:14;:21;68982:1;:25;68962:1190;;;69056:14;69071:1;69056:17;;;;;;;;;;;;;;;;;;69029:44;;69109:8;:22;69118:12;-1:-1:-1;;;;;69109:22:0;-1:-1:-1;;;;;69109:22:0;;;;;;;;;;;;:30;;;69088:51;;69178:7;-1:-1:-1;;;;;69178:30:0;;69209:12;69223:10;69235:12;;;;;;;;;;;69249:7;69178:79;;;;;-1:-1:-1;;;69178:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69178:79:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69178:79:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69178:79:0;69297:27;;69178:79;;-1:-1:-1;69297:24:0;;69322:1;;69297:27;;;;;;;;;;;;;;;69280:44;;;69272:79;;;;;-1:-1:-1;;;;;69272:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;69396:29;:10;69411:13;69396:29;:14;:29;:::i;:::-;-1:-1:-1;;;;;69440:22:0;;;;;;:8;:22;;;;;;;:50;;;;;-1:-1:-1;69440:22:0;;;;-1:-1:-1;69440:22:0;-1:-1:-1;;;;;69594:35:0;69590:182;;;69648:34;;:10;;:34;;;;;69668:13;;69648:34;;;;69668:13;69648:10;:34;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69648:34:0;69590:182;;;69719:53;69732:12;69746:10;69758:13;69719:12;:53::i;:::-;69794:96;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;69794:96:0;;;69811:10;;69794:96;;;;;;;;;-1:-1:-1;;;;;;70002:22:0;;;;;;:8;:22;;;;;-1:-1:-1;70002:29:0;;;;70046:94;70073:18;70002:22;70107:17;70002:29;70046:26;:94::i;:::-;69009:3;;;;;68962:1190;;;68599:1560;;;;;;;;;;;;:::o;15231:133::-;15323:8;;:33;;;;;;;;;;;;;;-1:-1:-1;;;;;;;15323:8:0;;:18;;:33;;;;;;;;;;;;;;-1:-1:-1;15323:8:0;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;15323:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15323:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15323:33:0;;15231:133;-1:-1:-1;;15231:133:0:o;10831:126::-;10920:4;-1:-1:-1;;;;;10900:25:0;;;;10892:57;;;;;-1:-1:-1;;;;;10892:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;22277:246;8900:12;:10;:12::i;:::-;22408:6;10384:23;10398:8;10384:13;:23::i;:::-;22438:3;10384:23;10398:8;10384:13;:23::i;:::-;22460:3;10738:18;10747:8;10738;:18::i;:::-;22481:34;22494:6;22502:3;22507:7;22481:12;:34::i;41868:313::-;41945:13;29680:23;29694:8;29680:13;:23::i;:::-;-1:-1:-1;;;;;;;;41975:36:0;;;-1:-1:-1;;;;;;;;;41975:36:0;41971:202;;;-1:-1:-1;;;;;42026:23:0;;;;;;:8;:23;;;;;42068:4;42060:21;42026:55;;41971:202;;;42144:29;;;;;;42168:4;42144:29;;;;;;-1:-1:-1;;;;;42144:23:0;;;;;:29;;;;;;;;;;;;;;-1:-1:-1;42144:23:0;:29;;;5:2:-1;;;;30:1;27;20:12;5:2;42144:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;42144:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;42144:29:0;-1:-1:-1;;;;;42110:23:0;;;;;;:8;42144:29;42110:23;;;;:63;41971:202;41868:313;;:::o;12885:139::-;12970:24;12980:13;12970:9;:24::i;:::-;-1:-1:-1;;;;;12956:38:0;:10;:38;12948:68;;;;;-1:-1:-1;;;;;12948:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;12948:68:0;;;;;;;;;;;;;;29422:88;29477:10;:8;:10::i;:::-;29476:11;29468:34;;;;;-1:-1:-1;;;;;29468:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;10482:128;-1:-1:-1;;;;;10556:22:0;;;;10548:54;;;;;-1:-1:-1;;;;;10548:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;30491:160;30579:1;30569:7;:11;;;:43;;;;-1:-1:-1;24660:7:0;30584:28;;;;;30569:43;30561:82;;;;;;;-1:-1:-1;;;;;30561:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;29161:87;29213:10;:8;:10::i;:::-;29205:35;;;;;;;-1:-1:-1;;;;;29205:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;62798:1158;62999:13;:20;63048:21;;62940:9;;;;63038:31;;63030:63;;;;;-1:-1:-1;;;;;63030:63:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;63030:63:0;;;;;;;;;;;;;;;63122:22;;63112:32;;63104:63;;;;;-1:-1:-1;;;;;63104:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;63189:1;63185:5;;63180:650;63196:6;63192:1;:10;63180:650;;;63320:8;:27;63329:14;63344:1;63329:17;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63320:27:0;;;;;;;;;;;-1:-1:-1;63320:27:0;-1:-1:-1;63320:33:0;;;;;;;63312:65;;;;;;;-1:-1:-1;;;;;63312:65:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;63312:65:0;;;;;;;;;;;;;;;63401:1;63397:5;;63392:133;63408:6;63404:1;:10;63392:133;;;63464:14;63479:1;63464:17;;;;;;;;;;;;;;;;;;;63444:13;:16;;-1:-1:-1;;;;;63444:37:0;;;;63458:1;;63444:16;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63444:16:0;:37;63440:69;;;63504:5;;63440:69;63416:3;;;;;63392:133;;;63635:10;;;63627:42;;;;;-1:-1:-1;;;;;63627:42:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;63627:42:0;;;;;;;;;;;;;;;63794:1;63773:15;63789:1;63773:18;;;;;;;;;;;;;;;;;;;:22;63765:53;;;;;-1:-1:-1;;;;;63765:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;63204:3;;;;;63180:650;;;63927:1;63917:11;;63909:39;;;;;-1:-1:-1;;;;;63909:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;64218:379;64374:7;64403:17;;64399:99;;;64442:56;64466:14;64482:15;64442:23;:56::i;:::-;64435:63;;;;64399:99;64516:73;64543:14;64559:15;64576:12;64516:26;:73::i;:::-;64509:80;;64218:379;;;;;;:::o;41521:154::-;41622:13;;41583:7;;41610:57;;24727:7;;41610:26;;:7;;41622:13;;;;;;;;41610:11;:26;:::i;:::-;:30;:57;:30;:57;:::i;42254:205::-;42328:13;:20;42305;42359:92;42383:12;42379:1;:16;42359:92;;;42415:36;42434:13;42448:1;42434:16;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;42434:16:0;42415:18;:36::i;:::-;42397:3;;42359:92;;16950:147;17010:7;17038:8;;;;17030:34;;;;;-1:-1:-1;;;;;17030:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17082:7:0;;;16950:147::o;19885:205::-;18348:50;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20010:71:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;20010:71:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;20010:71:0;;;179:29:-1;;;;160:49;;;19994:88:0;;20002:6;;19994:7;:88::i;:::-;19885:205;;;;:::o;16558:169::-;16618:7;16650;;;16676;;;;16668:32;;;;;-1:-1:-1;;;;;16668:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;74102:285;74279:6;;-1:-1:-1;;;;;74263:116:0;;;;74279:6;74263:116;74302:38;:15;24660:7;74302:19;:38::i;:::-;74342:36;:16;:36;;;;;:20;:36;:::i;:::-;74263:116;;;;;;;;;;;;;;;;;;;;;;74102:285;;;;:::o;33858:259::-;8900:12;:10;:12::i;:::-;34011:1;33989:19;:17;:19::i;:::-;:23;;;33981:61;;;;;-1:-1:-1;;;;;33981:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;34053:6;;;:24;;;;;;;;-1:-1:-1;;;;;34053:6:0;;;;:22;;:24;;;;:6;;:24;;;;;;:6;;:24;;;5:2:-1;;;;30:1;27;20:12;5:2;34053:24:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;34053:24:0;;;;34088:21;:19;:21::i;54100:1642::-;54263:7;54336:14;54352:11;54622:28;54367:55;54386:12;54400;54414:7;54367:18;:55::i;:::-;54335:87;;-1:-1:-1;54335:87:0;-1:-1:-1;54503:11:0;;;54495:46;;;;;-1:-1:-1;;;;;54495:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;54653:28;54668:12;54653:14;:28::i;:::-;54622:59;-1:-1:-1;54699:29:0;;;54692:37;;;;-1:-1:-1;;;;;;;;54809:35:0;;;-1:-1:-1;;;;;;;;;54809:35:0;54805:261;;;54867:9;:20;;54859:56;;;;;-1:-1:-1;;;;;54859:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;54805:261;;;54952:9;:14;:91;;;;;55036:7;54970:62;55003:28;55018:12;55003:14;:28::i;:::-;54970;;;;;;54993:4;54970:28;;;;;;-1:-1:-1;;;;;54970:22:0;;;;;:28;;;;;;;;;;;;;;-1:-1:-1;54970:22:0;:28;;;5:2:-1;;;;30:1;27;20:12;5:2;54970:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;54970:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54970:28:0;;:62;:32;:62;:::i;:::-;:73;;54952:91;54944:122;;;;;;;-1:-1:-1;;;;;54944:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55117:32;55136:12;55117:18;:32::i;:::-;-1:-1:-1;;;;;55193:22:0;;;;;;:8;:22;;;;;:30;:42;;55228:6;55193:34;:42::i;:::-;-1:-1:-1;;;;;55160:22:0;;;;;;:8;:22;;;;;;;:75;;;;:22;;;;-1:-1:-1;55160:22:0;-1:-1:-1;;;;;55322:35:0;55318:160;;;55372:29;;-1:-1:-1;;;;;55372:21:0;;;:29;;;;;;;;;;;;:21;:29;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;55372:29:0;55318:160;;;55430:48;55443:12;55457;55471:6;55430:12;:48::i;:::-;55533:82;55557:12;55571;55585:7;55594;55603:6;55611:3;55533:23;:82::i;:::-;55662:46;55681:12;55695;55662:18;:46::i;:::-;-1:-1:-1;55728:6:0;;54100:1642;-1:-1:-1;;;;;;;54100:1642:0:o;19306:174::-;18241:38;;;;;;;;;;;;;;;;-1:-1:-1;;;;;19412:59:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;19412:59:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;19412:59:0;;;179:29:-1;;;;160:49;;;19396:76:0;;19404:6;;19396:7;:76::i;:::-;19306:174;;;:::o;64823:1136::-;64962:7;65072:14;65216:9;65754:20;65089:30;65103:15;65089:13;:30::i;:::-;65072:47;;65228:1;65216:13;;65211:715;65235:14;:21;65231:1;:25;65211:715;;;65282:17;;-1:-1:-1;;;;;;;;;;;24789:42:0;65282:14;;65297:1;;65282:17;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65282:40:0;;65278:199;;65404:73;65421:14;65436:1;65421:17;;;;;;;;;;;;;;;;;;65440:10;65452:4;65458:15;65474:1;65458:18;;;;;;;;;;;;;;;;;;65404:16;:73::i;:::-;65532:15;65548:1;65532:18;;;;;;;;;;;;;;;;;;65494:8;:27;65503:14;65518:1;65503:17;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65494:27:0;;;;;;;;;;;-1:-1:-1;65494:27:0;:56;65599:17;;;;65614:1;;65599:17;;;;;;;;;;;;;;;65618:18;;-1:-1:-1;;;;;65572:93:0;;;;65587:10;;65572:93;;65618:15;;65634:1;;65618:18;;;;;;;;;;;;;;65638:15;65654:1;65638:18;;;;;;;;;;;;;;;;;;;;65572:93;;;;;;;;;;;;;;;;;;;;;;;;;65777:8;:27;65786:14;65801:1;65786:17;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65777:27:0;;;;;;;;;;;-1:-1:-1;65777:27:0;-1:-1:-1;65777:34:0;;65861:17;;65777:34;;;;;-1:-1:-1;65826:88:0;;65853:6;;65861:17;;65876:1;;65861:17;;;;;;;;;;;;;;65880:15;65896:1;65880:18;;;;;;;;;;;;;;;;;;65900:13;65826:26;:88::i;:::-;65258:3;;;;;65211:715;;;-1:-1:-1;65945:6:0;;64823:1136;-1:-1:-1;;;;64823:1136:0:o;66241:1998::-;66405:7;66567:22;66644:14;66739:26;66810:9;66872:24;66931:18;66997:21;67696:25;68023:20;66430:21;:19;:21::i;:::-;-1:-1:-1;;;;;;;;;;;66502:29:0;;:8;:29;;-1:-1:-1;;;;;;;;;;;66502:37:0;:52;;66544:9;66502:52;:41;:52;:::i;:::-;-1:-1:-1;;;;;;;;;;;66462:29:0;;:8;:29;;-1:-1:-1;;;;;;;;;;;66462:92:0;66607:25;-1:-1:-1;;;;;;;;;;;66607:9:0;:25::i;:::-;66567:66;;66661:67;66673:7;66682:12;66696:14;66712:15;66661:11;:67::i;:::-;66644:84;-1:-1:-1;66768:24:0;:12;66644:84;66768:24;:16;:24;:::i;:::-;66739:53;;66822:1;66810:13;;66805:1401;66829:14;:21;66825:1;:25;66805:1401;;;66899:14;66914:1;66899:17;;;;;;;;;;;;;;;;;;66872:44;;66952:8;:22;66961:12;-1:-1:-1;;;;;66952:22:0;-1:-1:-1;;;;;66952:22:0;;;;;;;;;;;;:30;;;66931:51;;67021:7;-1:-1:-1;;;;;67021:16:0;;67038:12;67052:10;67064:12;;;;;;;;;;;67078:6;67021:64;;;;;-1:-1:-1;;;67021:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67021:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67021:64:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;67021:64:0;;-1:-1:-1;67124:1:0;67108:17;;67100:52;;;;;-1:-1:-1;;;;;67100:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;67191:15;67207:1;67191:18;;;;;;;;;;;;;;;;;;;67174:35;;;67167:43;;;;-1:-1:-1;;;;;;;;67314:35:0;;;-1:-1:-1;;;;;;;;;67314:35:0;67310:369;;67431:63;67448:12;67462:10;67474:4;67480:13;67431:16;:63::i;:::-;67310:369;;;67539:13;67518:15;67534:1;67518:18;;;;;;;;;;;;;;;;;;:34;67514:165;;;67644:18;;67624:10;;:55;;67665:13;;67644:15;;67660:1;;67644:18;;;;;;;;;;;;;;:34;67624:55;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67624:55:0;67514:165;67724:29;:10;67739:13;67724:29;:14;:29;:::i;:::-;-1:-1:-1;;;;;67768:22:0;;;;;;:8;:22;;;;;;;;;:50;;;67840:94;;;;;;;;;;;;;;;;;;;67768:50;;-1:-1:-1;67768:22:0;;67855:10;;67840:94;;;;;;;;;;68046:8;:27;68055:14;68070:1;68055:17;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68046:27:0;;;;;;;;;;;-1:-1:-1;68046:27:0;-1:-1:-1;68046:34:0;;68142:17;;68046:34;;;;;-1:-1:-1;68095:99:0;;68122:18;;68142:17;;68157:1;;68142:17;;;;;;;;;;;;;;68161;68180:13;68095:26;:99::i;:::-;66852:3;;;;;66805:1401;;;-1:-1:-1;68225:6:0;;66241:1998;-1:-1:-1;;;;;;;;;;;66241:1998:0:o;17321:250::-;17381:7;;17434;;17430:34;;;17463:1;17456:8;;;;17430:34;-1:-1:-1;17489:7:0;;;17494:2;17489;:7;17515:6;;;;;;;;:12;17507:37;;;;;-1:-1:-1;;;;;17507:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;17799:174;17859:7;;17887:6;;;17879:37;;;;;-1:-1:-1;;;;;17879:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;17944:2;17939;:7;;;;;;;;;17799:174;-1:-1:-1;;;;17799:174:0:o;20441:793::-;20517:21;;:::i;:::-;:36;;;;;;;;;20550:1;20517:36;;;;;21034:2;20984:3;20888:5;20882:12;20790:2;20783:5;20779:14;20734:1;20678:6;20628:3;20605:476;21105:7;21098:15;21095:2;;;21143:1;21140;21133:12;21095:2;-1:-1:-1;21191:6:0;;:11;;21183:43;;;;;-1:-1:-1;;;;;21183:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;42882:758;43516:8;43503:21;;43496:29;;;;43541:91;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;43541:91:0;;;;;;;;;;;;;;;;;;;;;42882:758;;;;;;:::o;72439:1278::-;72576:6;;;72564:33;;;-1:-1:-1;;;;;72564:33:0;;;;72538:23;;;;;;;;;;;;;;-1:-1:-1;;;;;72576:6:0;;;;72564:31;;:33;;;;;;;;;;;;;72538:23;72576:6;72564:33;;;5:2:-1;;;;30:1;27;20:12;5:2;72564:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72564:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72564:33:0;;-1:-1:-1;72639:28:0;72654:12;72639:14;:28::i;:::-;72608:59;;72709:28;72724:12;72709:14;:28::i;:::-;-1:-1:-1;;;;;72777:22:0;;;;;;;:8;:22;;;;;;-1:-1:-1;72777:29:0;;;;72846:22;;;;;;;:29;;72678:59;;-1:-1:-1;72777:29:0;;;;;-1:-1:-1;72846:29:0;;;;-1:-1:-1;72949:45:0;;72678:59;;72777:29;;72949:24;:45;:::i;:::-;72933:61;-1:-1:-1;73021:45:0;:20;:45;;;;;:24;:45;:::i;:::-;73082:57;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;73082:57:0;;;;;;;;;;;;;;;;73220:100;73247:15;73264:12;73278:20;73300:19;73220:26;:100::i;:::-;73331;73358:15;73375:12;73389:20;73411:19;73331:26;:100::i;:::-;73515:89;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;73515:89:0;;;;;;;;;;;;;73620;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;73620:89:0;;;;;;;;;;;;;72439:1278;;;;;;;;;:::o;70167:608::-;70327:7;;70395:1;70378:249;70402:14;:21;70398:1;:25;70378:249;;;70518:66;70548:8;:27;70557:14;70572:1;70557:17;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70548:27:0;;;;;;;;;;;-1:-1:-1;70548:27:0;:35;70518:25;;;;70534:8;;70518:25;;;;;;;;;;;;;;;;:66;:29;:66;:::i;:::-;70449;70472:8;:34;70481:14;70496:8;70481:24;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70472:34:0;;;;;;;;;;;-1:-1:-1;70472:34:0;:42;70449:18;;;;70465:1;;70449:18;;;;;:66;:135;70445:170;;;70614:1;70603:12;;70445:170;70425:3;;70378:249;;;70644:7;-1:-1:-1;;;;;70644:24:0;;70669:12;70683:8;:34;70692:14;70707:8;70692:24;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70683:34:0;;;;;;;;;;;-1:-1:-1;70683:34:0;:42;70727:12;;70741:25;;70727:12;;;;;70741:25;;70757:8;;70741:25;;;;;;;;;;;;;;70644:123;;;;;-1:-1:-1;;;70644:123:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70644:123:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70644:123:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70644:123:0;;70167:608;-1:-1:-1;;;;;;;70167:608:0:o;50358:24032::-;;;;;;;;;-1:-1:-1;50358:24032:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;50358:24032:0;;;-1:-1:-1;;50358:24032:0:o
Swarm Source
bzzr://8ac6a9739e89dc82908965c8f0959f549da7cb06de5a581cb9b21b2afd9ede1d
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.