Address Details
contract

0x976B5c1ebF9feCC0010E3BF9eB307Ec70e1D8E55

Contract Name
StableToken
Creator
0x0cc59e–f1502d at 0x79e8c9–766436
Balance
0 CELO
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
2159423
Contract name:
StableToken




Optimization enabled
false
Compiler version
v0.5.8+commit.23d335f2




Verified at
2020-08-11T19:20:54.401572Z

Contract source code

pragma solidity ^0.5.3;


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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

    
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        
        require(b > 0, errorMessage);
        uint256 c = a / b;
        

        return c;
    }

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

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

contract Context {
    
    
    constructor () internal { }
    

    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
        this; 
        return msg.data;
    }
}

contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    
    function isOwner() public view returns (bool) {
        return _msgSender() == _owner;
    }

    
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

interface IERC20 {
    
    function totalSupply() external view returns (uint256);

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

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

    
    function allowance(address owner, address spender) external view returns (uint256);

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

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

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

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

interface IStableToken {
  function mint(address, uint256) external returns (bool);
  function burn(uint256) external returns (bool);
  function setInflationParameters(uint256, uint256) external;
  function valueToUnits(uint256) external view returns (uint256);
  function unitsToValue(uint256) external view returns (uint256);
  function getInflationParameters() external view returns (uint256, uint256, uint256, uint256);

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

interface ICeloToken {
  function transferWithComment(address, uint256, string calldata) external returns (bool);
  function name() external view returns (string memory);
  function symbol() external view returns (string memory);
  function decimals() external view returns (uint8);
}

contract CalledByVm {
  modifier onlyVm() {
    require(msg.sender == address(0), "Only VM can call");
    _;
  }
}

contract Initializable {
  bool public initialized;

  modifier initializer() {
    require(!initialized, "contract already initialized");
    initialized = true;
    _;
  }
}

library FixidityLib {
  struct Fraction {
    uint256 value;
  }

  
  function digits() internal pure returns (uint8) {
    return 24;
  }

  uint256 private constant FIXED1_UINT = 1000000000000000000000000;

  
  function fixed1() internal pure returns (Fraction memory) {
    return Fraction(FIXED1_UINT);
  }

  
  function wrap(uint256 x) internal pure returns (Fraction memory) {
    return Fraction(x);
  }

  
  function unwrap(Fraction memory x) internal pure returns (uint256) {
    return x.value;
  }

  
  function mulPrecision() internal pure returns (uint256) {
    return 1000000000000;
  }

  
  function maxNewFixed() internal pure returns (uint256) {
    return 115792089237316195423570985008687907853269984665640564;
  }

  
  function newFixed(uint256 x) internal pure returns (Fraction memory) {
    require(x <= maxNewFixed(), "can't create fixidity number larger than maxNewFixed()");
    return Fraction(x * FIXED1_UINT);
  }

  
  function fromFixed(Fraction memory x) internal pure returns (uint256) {
    return x.value / FIXED1_UINT;
  }

  
  function newFixedFraction(uint256 numerator, uint256 denominator)
    internal
    pure
    returns (Fraction memory)
  {
    Fraction memory convertedNumerator = newFixed(numerator);
    Fraction memory convertedDenominator = newFixed(denominator);
    return divide(convertedNumerator, convertedDenominator);
  }

  
  function integer(Fraction memory x) internal pure returns (Fraction memory) {
    return Fraction((x.value / FIXED1_UINT) * FIXED1_UINT); 
  }

  
  function fractional(Fraction memory x) internal pure returns (Fraction memory) {
    return Fraction(x.value - (x.value / FIXED1_UINT) * FIXED1_UINT); 
  }

  
  function add(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) {
    uint256 z = x.value + y.value;
    require(z >= x.value, "add overflow detected");
    return Fraction(z);
  }

  
  function subtract(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) {
    require(x.value >= y.value, "substraction underflow detected");
    return Fraction(x.value - y.value);
  }

  
  function multiply(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) {
    if (x.value == 0 || y.value == 0) return Fraction(0);
    if (y.value == FIXED1_UINT) return x;
    if (x.value == FIXED1_UINT) return y;

    
    
    uint256 x1 = integer(x).value / FIXED1_UINT;
    uint256 x2 = fractional(x).value;
    uint256 y1 = integer(y).value / FIXED1_UINT;
    uint256 y2 = fractional(y).value;

    
    uint256 x1y1 = x1 * y1;
    if (x1 != 0) require(x1y1 / x1 == y1, "overflow x1y1 detected");

    
    
    uint256 fixed_x1y1 = x1y1 * FIXED1_UINT;
    if (x1y1 != 0) require(fixed_x1y1 / x1y1 == FIXED1_UINT, "overflow x1y1 * fixed1 detected");
    x1y1 = fixed_x1y1;

    uint256 x2y1 = x2 * y1;
    if (x2 != 0) require(x2y1 / x2 == y1, "overflow x2y1 detected");

    uint256 x1y2 = x1 * y2;
    if (x1 != 0) require(x1y2 / x1 == y2, "overflow x1y2 detected");

    x2 = x2 / mulPrecision();
    y2 = y2 / mulPrecision();
    uint256 x2y2 = x2 * y2;
    if (x2 != 0) require(x2y2 / x2 == y2, "overflow x2y2 detected");

    
    Fraction memory result = Fraction(x1y1);
    result = add(result, Fraction(x2y1)); 
    result = add(result, Fraction(x1y2)); 
    result = add(result, Fraction(x2y2)); 
    return result;
  }

  
  function reciprocal(Fraction memory x) internal pure returns (Fraction memory) {
    require(x.value != 0, "can't call reciprocal(0)");
    return Fraction((FIXED1_UINT * FIXED1_UINT) / x.value); 
  }

  
  function divide(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) {
    require(y.value != 0, "can't divide by 0");
    uint256 X = x.value * FIXED1_UINT;
    require(X / FIXED1_UINT == x.value, "overflow at divide");
    return Fraction(X / y.value);
  }

  
  function gt(Fraction memory x, Fraction memory y) internal pure returns (bool) {
    return x.value > y.value;
  }

  
  function gte(Fraction memory x, Fraction memory y) internal pure returns (bool) {
    return x.value >= y.value;
  }

  
  function lt(Fraction memory x, Fraction memory y) internal pure returns (bool) {
    return x.value < y.value;
  }

  
  function lte(Fraction memory x, Fraction memory y) internal pure returns (bool) {
    return x.value <= y.value;
  }

  
  function equals(Fraction memory x, Fraction memory y) internal pure returns (bool) {
    return x.value == y.value;
  }

  
  function isProperFraction(Fraction memory x) internal pure returns (bool) {
    return lte(x, fixed1());
  }
}

interface IAccounts {
  function isAccount(address) external view returns (bool);
  function voteSignerToAccount(address) external view returns (address);
  function validatorSignerToAccount(address) external view returns (address);
  function attestationSignerToAccount(address) external view returns (address);
  function signerToAccount(address) external view returns (address);
  function getAttestationSigner(address) external view returns (address);
  function getValidatorSigner(address) external view returns (address);
  function getVoteSigner(address) external view returns (address);
  function hasAuthorizedVoteSigner(address) external view returns (bool);
  function hasAuthorizedValidatorSigner(address) external view returns (bool);
  function hasAuthorizedAttestationSigner(address) external view returns (bool);

  function setAccountDataEncryptionKey(bytes calldata) external;
  function setMetadataURL(string calldata) external;
  function setName(string calldata) external;
  function setWalletAddress(address, uint8, bytes32, bytes32) external;
  function setAccount(string calldata, bytes calldata, address, uint8, bytes32, bytes32) external;

  function getDataEncryptionKey(address) external view returns (bytes memory);
  function getWalletAddress(address) external view returns (address);
  function getMetadataURL(address) external view returns (string memory);
  function batchGetMetadataURL(address[] calldata)
    external
    view
    returns (uint256[] memory, bytes memory);
  function getName(address) external view returns (string memory);

  function authorizeVoteSigner(address, uint8, bytes32, bytes32) external;
  function authorizeValidatorSigner(address, uint8, bytes32, bytes32) external;
  function authorizeValidatorSignerWithPublicKey(address, uint8, bytes32, bytes32, bytes calldata)
    external;
  function authorizeValidatorSignerWithKeys(
    address,
    uint8,
    bytes32,
    bytes32,
    bytes calldata,
    bytes calldata,
    bytes calldata
  ) external;
  function authorizeAttestationSigner(address, uint8, bytes32, bytes32) external;
  function createAccount() external returns (bool);
}

interface IFeeCurrencyWhitelist {
  function addToken(address) external;
  function getWhitelist() external view returns (address[] memory);
}

interface IFreezer {
  function isFrozen(address) external view returns (bool);
}

interface IRegistry {
  function setAddressFor(string calldata, address) external;
  function getAddressForOrDie(bytes32) external view returns (address);
  function getAddressFor(bytes32) external view returns (address);
  function isOneOf(bytes32[] calldata, address) external view returns (bool);
}

interface IElection {
  function getTotalVotes() external view returns (uint256);
  function getActiveVotes() external view returns (uint256);
  function getTotalVotesByAccount(address) external view returns (uint256);
  function markGroupIneligible(address) external;
  function markGroupEligible(address, address, address) external;
  function electValidatorSigners() external view returns (address[] memory);
  function vote(address, uint256, address, address) external returns (bool);
  function activate(address) external returns (bool);
  function revokeActive(address, uint256, address, address, uint256) external returns (bool);
  function revokeAllActive(address, address, address, uint256) external returns (bool);
  function revokePending(address, uint256, address, address, uint256) external returns (bool);
  function forceDecrementVotes(
    address,
    uint256,
    address[] calldata,
    address[] calldata,
    uint256[] calldata
  ) external returns (uint256);
}

interface IGovernance {
  function isVoting(address) external view returns (bool);
}

interface ILockedGold {
  function incrementNonvotingAccountBalance(address, uint256) external;
  function decrementNonvotingAccountBalance(address, uint256) external;
  function getAccountTotalLockedGold(address) external view returns (uint256);
  function getTotalLockedGold() external view returns (uint256);
  function getPendingWithdrawals(address)
    external
    view
    returns (uint256[] memory, uint256[] memory);
  function getTotalPendingWithdrawals(address) external view returns (uint256);
  function lock() external payable;
  function unlock(uint256) external;
  function relock(uint256, uint256) external;
  function withdraw(uint256) external;
  function slash(
    address account,
    uint256 penalty,
    address reporter,
    uint256 reward,
    address[] calldata lessers,
    address[] calldata greaters,
    uint256[] calldata indices
  ) external;
  function isSlasher(address) external view returns (bool);
}

interface IValidators {
  function getAccountLockedGoldRequirement(address) external view returns (uint256);
  function meetsAccountLockedGoldRequirements(address) external view returns (bool);
  function getGroupNumMembers(address) external view returns (uint256);
  function getGroupsNumMembers(address[] calldata) external view returns (uint256[] memory);
  function getNumRegisteredValidators() external view returns (uint256);
  function getTopGroupValidators(address, uint256) external view returns (address[] memory);
  function updateEcdsaPublicKey(address, address, bytes calldata) external returns (bool);
  function updatePublicKeys(address, address, bytes calldata, bytes calldata, bytes calldata)
    external
    returns (bool);
  function isValidator(address) external view returns (bool);
  function isValidatorGroup(address) external view returns (bool);
  function calculateGroupEpochScore(uint256[] calldata uptimes) external view returns (uint256);
  function groupMembershipInEpoch(address account, uint256 epochNumber, uint256 index)
    external
    view
    returns (address);
  function halveSlashingMultiplier(address group) external;
  function forceDeaffiliateIfValidator(address validator) external;
  function getValidatorGroupSlashingMultiplier(address) external view returns (uint256);
  function affiliate(address group) external returns (bool);
}

interface IRandom {
  function revealAndCommit(bytes32, bytes32, address) external;
  function randomnessBlockRetentionWindow() external view returns (uint256);
  function random() external view returns (bytes32);
  function getBlockRandomness(uint256) external view returns (bytes32);
}

interface IAttestations {
  function setAttestationRequestFee(address, uint256) external;
  function request(bytes32, uint256, address) external;
  function selectIssuers(bytes32) external;
  function complete(bytes32, uint8, bytes32, bytes32) external;
  function revoke(bytes32, uint256) external;
  function withdraw(address) external;

  function setAttestationExpiryBlocks(uint256) external;

  function getMaxAttestations() external view returns (uint256);

  function getUnselectedRequest(bytes32, address) external view returns (uint32, uint32, address);
  function getAttestationRequestFee(address) external view returns (uint256);

  function lookupAccountsForIdentifier(bytes32) external view returns (address[] memory);

  function getAttestationStats(bytes32, address) external view returns (uint32, uint32);

  function getAttestationState(bytes32, address, address)
    external
    view
    returns (uint8, uint32, address);
  function getCompletableAttestations(bytes32, address)
    external
    view
    returns (uint32[] memory, address[] memory, uint256[] memory, bytes memory);
}

interface IExchange {
  function exchange(uint256, uint256, bool) external returns (uint256);
  function setUpdateFrequency(uint256) external;
  function getBuyTokenAmount(uint256, bool) external view returns (uint256);
  function getSellTokenAmount(uint256, bool) external view returns (uint256);
  function getBuyAndSellBuckets(bool) external view returns (uint256, uint256);
}

interface IReserve {
  function setTobinTaxStalenessThreshold(uint256) external;
  function addToken(address) external returns (bool);
  function removeToken(address, uint256) external returns (bool);
  function transferGold(address payable, uint256) external returns (bool);
  function transferExchangeGold(address payable, uint256) external returns (bool);
  function getReserveGoldBalance() external view returns (uint256);
  function getUnfrozenReserveGoldBalance() external view returns (uint256);
  function getOrComputeTobinTax() external returns (uint256, uint256);
  function getTokens() external view returns (address[] memory);
  function getReserveRatio() external view returns (uint256);
}

interface ISortedOracles {
  function addOracle(address, address) external;
  function removeOracle(address, address, uint256) external;
  function report(address, uint256, address, address) external;
  function removeExpiredReports(address, uint256) external;
  function isOldestReportExpired(address token) external view returns (bool, address);
  function numRates(address) external view returns (uint256);
  function medianRate(address) external view returns (uint256, uint256);
  function numTimestamps(address) external view returns (uint256);
  function medianTimestamp(address) external view returns (uint256);
}

contract UsingRegistry is Ownable {
  event RegistrySet(address indexed registryAddress);

  
  bytes32 constant ACCOUNTS_REGISTRY_ID = keccak256(abi.encodePacked("Accounts"));
  bytes32 constant ATTESTATIONS_REGISTRY_ID = keccak256(abi.encodePacked("Attestations"));
  bytes32 constant DOWNTIME_SLASHER_REGISTRY_ID = keccak256(abi.encodePacked("DowntimeSlasher"));
  bytes32 constant DOUBLE_SIGNING_SLASHER_REGISTRY_ID = keccak256(
    abi.encodePacked("DoubleSigningSlasher")
  );
  bytes32 constant ELECTION_REGISTRY_ID = keccak256(abi.encodePacked("Election"));
  bytes32 constant EXCHANGE_REGISTRY_ID = keccak256(abi.encodePacked("Exchange"));
  bytes32 constant FEE_CURRENCY_WHITELIST_REGISTRY_ID = keccak256(
    abi.encodePacked("FeeCurrencyWhitelist")
  );
  bytes32 constant FREEZER_REGISTRY_ID = keccak256(abi.encodePacked("Freezer"));
  bytes32 constant GOLD_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("GoldToken"));
  bytes32 constant GOVERNANCE_REGISTRY_ID = keccak256(abi.encodePacked("Governance"));
  bytes32 constant GOVERNANCE_SLASHER_REGISTRY_ID = keccak256(
    abi.encodePacked("GovernanceSlasher")
  );
  bytes32 constant LOCKED_GOLD_REGISTRY_ID = keccak256(abi.encodePacked("LockedGold"));
  bytes32 constant RESERVE_REGISTRY_ID = keccak256(abi.encodePacked("Reserve"));
  bytes32 constant RANDOM_REGISTRY_ID = keccak256(abi.encodePacked("Random"));
  bytes32 constant SORTED_ORACLES_REGISTRY_ID = keccak256(abi.encodePacked("SortedOracles"));
  bytes32 constant STABLE_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("StableToken"));
  bytes32 constant VALIDATORS_REGISTRY_ID = keccak256(abi.encodePacked("Validators"));
  

  IRegistry public registry;

  modifier onlyRegisteredContract(bytes32 identifierHash) {
    require(registry.getAddressForOrDie(identifierHash) == msg.sender, "only registered contract");
    _;
  }

  modifier onlyRegisteredContracts(bytes32[] memory identifierHashes) {
    require(registry.isOneOf(identifierHashes, msg.sender), "only registered contracts");
    _;
  }

  
  function setRegistry(address registryAddress) public onlyOwner {
    require(registryAddress != address(0), "Cannot register the null address");
    registry = IRegistry(registryAddress);
    emit RegistrySet(registryAddress);
  }

  function getAccounts() internal view returns (IAccounts) {
    return IAccounts(registry.getAddressForOrDie(ACCOUNTS_REGISTRY_ID));
  }

  function getAttestations() internal view returns (IAttestations) {
    return IAttestations(registry.getAddressForOrDie(ATTESTATIONS_REGISTRY_ID));
  }

  function getElection() internal view returns (IElection) {
    return IElection(registry.getAddressForOrDie(ELECTION_REGISTRY_ID));
  }

  function getExchange() internal view returns (IExchange) {
    return IExchange(registry.getAddressForOrDie(EXCHANGE_REGISTRY_ID));
  }

  function getFeeCurrencyWhitelistRegistry() internal view returns (IFeeCurrencyWhitelist) {
    return IFeeCurrencyWhitelist(registry.getAddressForOrDie(FEE_CURRENCY_WHITELIST_REGISTRY_ID));
  }

  function getFreezer() internal view returns (IFreezer) {
    return IFreezer(registry.getAddressForOrDie(FREEZER_REGISTRY_ID));
  }

  function getGoldToken() internal view returns (IERC20) {
    return IERC20(registry.getAddressForOrDie(GOLD_TOKEN_REGISTRY_ID));
  }

  function getGovernance() internal view returns (IGovernance) {
    return IGovernance(registry.getAddressForOrDie(GOVERNANCE_REGISTRY_ID));
  }

  function getLockedGold() internal view returns (ILockedGold) {
    return ILockedGold(registry.getAddressForOrDie(LOCKED_GOLD_REGISTRY_ID));
  }

  function getRandom() internal view returns (IRandom) {
    return IRandom(registry.getAddressForOrDie(RANDOM_REGISTRY_ID));
  }

  function getReserve() internal view returns (IReserve) {
    return IReserve(registry.getAddressForOrDie(RESERVE_REGISTRY_ID));
  }

  function getSortedOracles() internal view returns (ISortedOracles) {
    return ISortedOracles(registry.getAddressForOrDie(SORTED_ORACLES_REGISTRY_ID));
  }

  function getStableToken() internal view returns (IStableToken) {
    return IStableToken(registry.getAddressForOrDie(STABLE_TOKEN_REGISTRY_ID));
  }

  function getValidators() internal view returns (IValidators) {
    return IValidators(registry.getAddressForOrDie(VALIDATORS_REGISTRY_ID));
  }
}

contract Freezable is UsingRegistry {
  
  
  modifier onlyWhenNotFrozen() {
    require(!getFreezer().isFrozen(address(this)), "can't call when contract is frozen");
    _;
  }
}

contract UsingPrecompiles {
  using SafeMath for uint256;

  address constant TRANSFER = address(0xff - 2);
  address constant FRACTION_MUL = address(0xff - 3);
  address constant PROOF_OF_POSSESSION = address(0xff - 4);
  address constant GET_VALIDATOR = address(0xff - 5);
  address constant NUMBER_VALIDATORS = address(0xff - 6);
  address constant EPOCH_SIZE = address(0xff - 7);
  address constant BLOCK_NUMBER_FROM_HEADER = address(0xff - 8);
  address constant HASH_HEADER = address(0xff - 9);
  address constant GET_PARENT_SEAL_BITMAP = address(0xff - 10);
  address constant GET_VERIFIED_SEAL_BITMAP = address(0xff - 11);

  
  function fractionMulExp(
    uint256 aNumerator,
    uint256 aDenominator,
    uint256 bNumerator,
    uint256 bDenominator,
    uint256 exponent,
    uint256 _decimals
  ) public view returns (uint256, uint256) {
    require(aDenominator != 0 && bDenominator != 0, "a denominator is zero");
    uint256 returnNumerator;
    uint256 returnDenominator;
    bool success;
    bytes memory out;
    (success, out) = FRACTION_MUL.staticcall(
      abi.encodePacked(aNumerator, aDenominator, bNumerator, bDenominator, exponent, _decimals)
    );
    require(success, "error calling fractionMulExp precompile");
    returnNumerator = getUint256FromBytes(out, 0);
    returnDenominator = getUint256FromBytes(out, 32);
    return (returnNumerator, returnDenominator);
  }

  
  function getEpochSize() public view returns (uint256) {
    bytes memory out;
    bool success;
    (success, out) = EPOCH_SIZE.staticcall(abi.encodePacked());
    require(success, "error calling getEpochSize precompile");
    return getUint256FromBytes(out, 0);
  }

  
  function getEpochNumberOfBlock(uint256 blockNumber) public view returns (uint256) {
    return epochNumberOfBlock(blockNumber, getEpochSize());
  }

  
  function getEpochNumber() public view returns (uint256) {
    return getEpochNumberOfBlock(block.number);
  }

  
  function epochNumberOfBlock(uint256 blockNumber, uint256 epochSize)
    internal
    pure
    returns (uint256)
  {
    
    uint256 epochNumber = blockNumber / epochSize;
    if (blockNumber % epochSize == 0) {
      return epochNumber;
    } else {
      return epochNumber + 1;
    }
  }

  
  function validatorSignerAddressFromCurrentSet(uint256 index) public view returns (address) {
    bytes memory out;
    bool success;
    (success, out) = GET_VALIDATOR.staticcall(abi.encodePacked(index, uint256(block.number)));
    require(success, "error calling validatorSignerAddressFromCurrentSet precompile");
    return address(getUint256FromBytes(out, 0));
  }

  
  function validatorSignerAddressFromSet(uint256 index, uint256 blockNumber)
    public
    view
    returns (address)
  {
    bytes memory out;
    bool success;
    (success, out) = GET_VALIDATOR.staticcall(abi.encodePacked(index, blockNumber));
    require(success, "error calling validatorSignerAddressFromSet precompile");
    return address(getUint256FromBytes(out, 0));
  }

  
  function numberValidatorsInCurrentSet() public view returns (uint256) {
    bytes memory out;
    bool success;
    (success, out) = NUMBER_VALIDATORS.staticcall(abi.encodePacked(uint256(block.number)));
    require(success, "error calling numberValidatorsInCurrentSet precompile");
    return getUint256FromBytes(out, 0);
  }

  
  function numberValidatorsInSet(uint256 blockNumber) public view returns (uint256) {
    bytes memory out;
    bool success;
    (success, out) = NUMBER_VALIDATORS.staticcall(abi.encodePacked(blockNumber));
    require(success, "error calling numberValidatorsInSet precompile");
    return getUint256FromBytes(out, 0);
  }

  
  function checkProofOfPossession(address sender, bytes memory blsKey, bytes memory blsPop)
    public
    view
    returns (bool)
  {
    bool success;
    (success, ) = PROOF_OF_POSSESSION.staticcall(abi.encodePacked(sender, blsKey, blsPop));
    return success;
  }

  
  function getBlockNumberFromHeader(bytes memory header) public view returns (uint256) {
    bytes memory out;
    bool success;
    (success, out) = BLOCK_NUMBER_FROM_HEADER.staticcall(abi.encodePacked(header));
    require(success, "error calling getBlockNumberFromHeader precompile");
    return getUint256FromBytes(out, 0);
  }

  
  function hashHeader(bytes memory header) public view returns (bytes32) {
    bytes memory out;
    bool success;
    (success, out) = HASH_HEADER.staticcall(abi.encodePacked(header));
    require(success, "error calling hashHeader precompile");
    return getBytes32FromBytes(out, 0);
  }

  
  function getParentSealBitmap(uint256 blockNumber) public view returns (bytes32) {
    bytes memory out;
    bool success;
    (success, out) = GET_PARENT_SEAL_BITMAP.staticcall(abi.encodePacked(blockNumber));
    require(success, "error calling getParentSealBitmap precompile");
    return getBytes32FromBytes(out, 0);
  }

  
  function getVerifiedSealBitmapFromHeader(bytes memory header) public view returns (bytes32) {
    bytes memory out;
    bool success;
    (success, out) = GET_VERIFIED_SEAL_BITMAP.staticcall(abi.encodePacked(header));
    require(success, "error calling getVerifiedSealBitmapFromHeader precompile");
    return getBytes32FromBytes(out, 0);
  }

  
  function getUint256FromBytes(bytes memory bs, uint256 start) internal pure returns (uint256) {
    return uint256(getBytes32FromBytes(bs, start));
  }

  
  function getBytes32FromBytes(bytes memory bs, uint256 start) internal pure returns (bytes32) {
    require(bs.length >= start + 32, "slicing out of range");
    bytes32 x;
    assembly {
      x := mload(add(bs, add(start, 32)))
    }
    return x;
  }

  
  function minQuorumSize(uint256 blockNumber) public view returns (uint256) {
    return numberValidatorsInSet(blockNumber).mul(2).add(2).div(3);
  }

  
  function minQuorumSizeInCurrentSet() public view returns (uint256) {
    return minQuorumSize(block.number);
  }

}

contract StableToken is
  Ownable,
  Initializable,
  UsingRegistry,
  UsingPrecompiles,
  Freezable,
  CalledByVm,
  IStableToken,
  IERC20,
  ICeloToken
{
  using FixidityLib for FixidityLib.Fraction;
  using SafeMath for uint256;

  event InflationFactorUpdated(uint256 factor, uint256 lastUpdated);

  event InflationParametersUpdated(uint256 rate, uint256 updatePeriod, uint256 lastUpdated);

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

  event TransferComment(string comment);

  string internal name_;
  string internal symbol_;
  uint8 internal decimals_;

  
  mapping(address => uint256) internal balances;
  uint256 internal totalSupply_;

  
  mapping(address => mapping(address => uint256)) internal allowed;

  

  
  
  
  
  struct InflationState {
    FixidityLib.Fraction rate;
    FixidityLib.Fraction factor;
    uint256 updatePeriod;
    uint256 factorLastUpdated;
  }

  InflationState inflationState;

  
  modifier updateInflationFactor() {
    FixidityLib.Fraction memory updatedInflationFactor;
    uint256 lastUpdated;

    (updatedInflationFactor, lastUpdated) = getUpdatedInflationFactor();

    if (lastUpdated != inflationState.factorLastUpdated) {
      inflationState.factor = updatedInflationFactor;
      inflationState.factorLastUpdated = lastUpdated;
      emit InflationFactorUpdated(inflationState.factor.unwrap(), inflationState.factorLastUpdated);
    }
    _;
  }

  
  function initialize(
    string calldata _name,
    string calldata _symbol,
    uint8 _decimals,
    address registryAddress,
    uint256 inflationRate,
    uint256 inflationFactorUpdatePeriod,
    address[] calldata initialBalanceAddresses,
    uint256[] calldata initialBalanceValues
  ) external initializer {
    require(inflationRate != 0, "Must provide a non-zero inflation rate");
    require(inflationFactorUpdatePeriod > 0, "inflationFactorUpdatePeriod must be > 0");

    _transferOwnership(msg.sender);

    totalSupply_ = 0;
    name_ = _name;
    symbol_ = _symbol;
    decimals_ = _decimals;

    inflationState.rate = FixidityLib.wrap(inflationRate);
    inflationState.factor = FixidityLib.fixed1();
    inflationState.updatePeriod = inflationFactorUpdatePeriod;
    
    inflationState.factorLastUpdated = now;

    require(initialBalanceAddresses.length == initialBalanceValues.length, "Array length mismatch");
    for (uint256 i = 0; i < initialBalanceAddresses.length; i = i.add(1)) {
      _mint(initialBalanceAddresses[i], initialBalanceValues[i]);
    }
    setRegistry(registryAddress);
  }

  
  function setInflationParameters(uint256 rate, uint256 updatePeriod)
    external
    onlyOwner
    updateInflationFactor
  {
    require(rate != 0, "Must provide a non-zero inflation rate.");
    require(updatePeriod > 0, "updatePeriod must be > 0");
    inflationState.rate = FixidityLib.wrap(rate);
    inflationState.updatePeriod = updatePeriod;

    emit InflationParametersUpdated(
      rate,
      updatePeriod,
      
      now
    );
  }

  
  function increaseAllowance(address spender, uint256 value)
    external
    updateInflationFactor
    returns (bool)
  {
    require(spender != address(0), "reserved address 0x0 cannot have allowance");
    uint256 oldValue = allowed[msg.sender][spender];
    uint256 newValue = oldValue.add(value);
    allowed[msg.sender][spender] = newValue;
    emit Approval(msg.sender, spender, newValue);
    return true;
  }

  
  function decreaseAllowance(address spender, uint256 value)
    external
    updateInflationFactor
    returns (bool)
  {
    uint256 oldValue = allowed[msg.sender][spender];
    uint256 newValue = oldValue.sub(value);
    allowed[msg.sender][spender] = newValue;
    emit Approval(msg.sender, spender, newValue);
    return true;
  }

  
  function approve(address spender, uint256 value) external updateInflationFactor returns (bool) {
    require(spender != address(0), "reserved address 0x0 cannot have allowance");
    allowed[msg.sender][spender] = value;
    emit Approval(msg.sender, spender, value);
    return true;
  }

  
  function mint(address to, uint256 value) external updateInflationFactor returns (bool) {
    require(
      msg.sender == registry.getAddressFor(EXCHANGE_REGISTRY_ID) ||
        msg.sender == registry.getAddressFor(VALIDATORS_REGISTRY_ID),
      "Only the Exchange and Validators contracts are authorized to mint"
    );
    return _mint(to, value);
  }

  
  function _mint(address to, uint256 value) private returns (bool) {
    require(to != address(0), "0 is a reserved address");
    if (value == 0) {
      return true;
    }

    uint256 units = _valueToUnits(inflationState.factor, value);
    totalSupply_ = totalSupply_.add(units);
    balances[to] = balances[to].add(units);
    emit Transfer(address(0), to, value);
    return true;
  }

  
  function transferWithComment(address to, uint256 value, string calldata comment)
    external
    updateInflationFactor
    onlyWhenNotFrozen
    returns (bool)
  {
    bool succeeded = transfer(to, value);
    emit TransferComment(comment);
    return succeeded;
  }

  
  function burn(uint256 value)
    external
    onlyRegisteredContract(EXCHANGE_REGISTRY_ID)
    updateInflationFactor
    returns (bool)
  {
    uint256 units = _valueToUnits(inflationState.factor, value);
    require(units <= balances[msg.sender], "value exceeded balance of sender");
    totalSupply_ = totalSupply_.sub(units);
    balances[msg.sender] = balances[msg.sender].sub(units);
    emit Transfer(msg.sender, address(0), units);
    return true;
  }

  
  function transferFrom(address from, address to, uint256 value)
    external
    updateInflationFactor
    onlyWhenNotFrozen
    returns (bool)
  {
    uint256 units = _valueToUnits(inflationState.factor, value);
    require(to != address(0), "transfer attempted to reserved address 0x0");
    require(units <= balances[from], "transfer value exceeded balance of sender");
    require(
      value <= allowed[from][msg.sender],
      "transfer value exceeded sender's allowance for recipient"
    );

    balances[to] = balances[to].add(units);
    balances[from] = balances[from].sub(units);
    allowed[from][msg.sender] = allowed[from][msg.sender].sub(value);
    emit Transfer(from, to, value);
    return true;
  }

  
  function name() external view returns (string memory) {
    return name_;
  }

  
  function symbol() external view returns (string memory) {
    return symbol_;
  }

  
  function decimals() external view returns (uint8) {
    return decimals_;
  }

  
  function allowance(address accountOwner, address spender) external view returns (uint256) {
    return allowed[accountOwner][spender];
  }

  
  function balanceOf(address accountOwner) external view returns (uint256) {
    return unitsToValue(balances[accountOwner]);
  }

  
  function totalSupply() external view returns (uint256) {
    return unitsToValue(totalSupply_);
  }

  
  function getInflationParameters() external view returns (uint256, uint256, uint256, uint256) {
    return (
      inflationState.rate.unwrap(),
      inflationState.factor.unwrap(),
      inflationState.updatePeriod,
      inflationState.factorLastUpdated
    );
  }

  
  function valueToUnits(uint256 value) external view returns (uint256) {
    FixidityLib.Fraction memory updatedInflationFactor;

    (updatedInflationFactor, ) = getUpdatedInflationFactor();
    return _valueToUnits(updatedInflationFactor, value);
  }

  
  function unitsToValue(uint256 units) public view returns (uint256) {
    FixidityLib.Fraction memory updatedInflationFactor;

    (updatedInflationFactor, ) = getUpdatedInflationFactor();

    
    
    
    
    
    
    return FixidityLib.newFixed(units).divide(updatedInflationFactor).fromFixed();
  }

  
  function _valueToUnits(FixidityLib.Fraction memory inflationFactor, uint256 value)
    private
    pure
    returns (uint256)
  {
    return inflationFactor.multiply(FixidityLib.newFixed(value)).fromFixed();
  }

  
  function getUpdatedInflationFactor() private view returns (FixidityLib.Fraction memory, uint256) {
    
    if (now < inflationState.factorLastUpdated.add(inflationState.updatePeriod)) {
      return (inflationState.factor, inflationState.factorLastUpdated);
    }

    uint256 numerator;
    uint256 denominator;

    
    uint256 timesToApplyInflation = now.sub(inflationState.factorLastUpdated).div(
      inflationState.updatePeriod
    );

    (numerator, denominator) = fractionMulExp(
      inflationState.factor.unwrap(),
      FixidityLib.fixed1().unwrap(),
      inflationState.rate.unwrap(),
      FixidityLib.fixed1().unwrap(),
      timesToApplyInflation,
      decimals_
    );

    
    
    if (numerator == 0 || denominator == 0) {
      return (inflationState.factor, inflationState.factorLastUpdated);
    }

    FixidityLib.Fraction memory currentInflationFactor = FixidityLib.wrap(numerator).divide(
      FixidityLib.wrap(denominator)
    );
    uint256 lastUpdated = inflationState.factorLastUpdated.add(
      inflationState.updatePeriod.mul(timesToApplyInflation)
    );

    return (currentInflationFactor, lastUpdated);
    
  }

  
  
  function transfer(address to, uint256 value)
    public
    updateInflationFactor
    onlyWhenNotFrozen
    returns (bool)
  {
    return _transfer(to, value);
  }

  
  function _transfer(address to, uint256 value) internal returns (bool) {
    require(to != address(0), "transfer attempted to reserved address 0x0");
    uint256 units = _valueToUnits(inflationState.factor, value);
    require(balances[msg.sender] >= units, "transfer value exceeded balance of sender");
    balances[msg.sender] = balances[msg.sender].sub(units);
    balances[to] = balances[to].add(units);
    emit Transfer(msg.sender, to, value);
    return true;
  }

  
  function debitGasFees(address from, uint256 value)
    external
    onlyVm
    onlyWhenNotFrozen
    updateInflationFactor
  {
    uint256 units = _valueToUnits(inflationState.factor, value);
    balances[from] = balances[from].sub(units);
    totalSupply_ = totalSupply_.sub(units);
  }

  
  function creditGasFees(
    address from,
    address feeRecipient,
    address gatewayFeeRecipient,
    address communityFund,
    uint256 refund,
    uint256 tipTxFee,
    uint256 gatewayFee,
    uint256 baseTxFee
  ) external onlyVm onlyWhenNotFrozen {
    uint256 units = _valueToUnits(inflationState.factor, refund);
    balances[from] = balances[from].add(units);

    units = units.add(_creditGas(from, communityFund, baseTxFee));
    units = units.add(_creditGas(from, feeRecipient, tipTxFee));
    units = units.add(_creditGas(from, gatewayFeeRecipient, gatewayFee));
    totalSupply_ = totalSupply_.add(units);
  }

  function _creditGas(address from, address to, uint256 value) internal returns (uint256) {
    if (to == address(0)) {
      return 0;
    }
    uint256 units = _valueToUnits(inflationState.factor, value);
    balances[to] = balances[to].add(units);
    emit Transfer(from, to, value);
    return units;
  }

}
        

Contract ABI

[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":""}],"name":"name","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"approve","inputs":[{"type":"address","name":"spender"},{"type":"uint256","name":"value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"validatorSignerAddressFromCurrentSet","inputs":[{"type":"uint256","name":"index"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"valueToUnits","inputs":[{"type":"uint256","name":"value"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"initialized","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setInflationParameters","inputs":[{"type":"uint256","name":"rate"},{"type":"uint256","name":"updatePeriod"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"transferFrom","inputs":[{"type":"address","name":"from"},{"type":"address","name":"to"},{"type":"uint256","name":"value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"checkProofOfPossession","inputs":[{"type":"address","name":"sender"},{"type":"bytes","name":"blsKey"},{"type":"bytes","name":"blsPop"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":""}],"name":"decimals","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender"},{"type":"uint256","name":"value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getEpochNumberOfBlock","inputs":[{"type":"uint256","name":"blockNumber"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"mint","inputs":[{"type":"address","name":"to"},{"type":"uint256","name":"value"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"burn","inputs":[{"type":"uint256","name":"value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"getVerifiedSealBitmapFromHeader","inputs":[{"type":"bytes","name":"header"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"debitGasFees","inputs":[{"type":"address","name":"from"},{"type":"uint256","name":"value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"validatorSignerAddressFromSet","inputs":[{"type":"uint256","name":"index"},{"type":"uint256","name":"blockNumber"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"hashHeader","inputs":[{"type":"bytes","name":"header"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"creditGasFees","inputs":[{"type":"address","name":"from"},{"type":"address","name":"feeRecipient"},{"type":"address","name":"gatewayFeeRecipient"},{"type":"address","name":"communityFund"},{"type":"uint256","name":"refund"},{"type":"uint256","name":"tipTxFee"},{"type":"uint256","name":"gatewayFee"},{"type":"uint256","name":"baseTxFee"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"balanceOf","inputs":[{"type":"address","name":"accountOwner"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"renounceOwnership","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"minQuorumSizeInCurrentSet","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"registry","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"string","name":"_name"},{"type":"string","name":"_symbol"},{"type":"uint8","name":"_decimals"},{"type":"address","name":"registryAddress"},{"type":"uint256","name":"inflationRate"},{"type":"uint256","name":"inflationFactorUpdatePeriod"},{"type":"address[]","name":"initialBalanceAddresses"},{"type":"uint256[]","name":"initialBalanceValues"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"numberValidatorsInCurrentSet","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getBlockNumberFromHeader","inputs":[{"type":"bytes","name":"header"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isOwner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":""}],"name":"symbol","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getEpochNumber","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"numberValidatorsInSet","inputs":[{"type":"uint256","name":"blockNumber"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender"},{"type":"uint256","name":"value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""},{"type":"uint256","name":""},{"type":"uint256","name":""},{"type":"uint256","name":""}],"name":"getInflationParameters","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"transfer","inputs":[{"type":"address","name":"to"},{"type":"uint256","name":"value"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setRegistry","inputs":[{"type":"address","name":"registryAddress"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"unitsToValue","inputs":[{"type":"uint256","name":"units"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"allowance","inputs":[{"type":"address","name":"accountOwner"},{"type":"address","name":"spender"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getEpochSize","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"transferWithComment","inputs":[{"type":"address","name":"to"},{"type":"uint256","name":"value"},{"type":"string","name":"comment"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"minQuorumSize","inputs":[{"type":"uint256","name":"blockNumber"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""},{"type":"uint256","name":""}],"name":"fractionMulExp","inputs":[{"type":"uint256","name":"aNumerator"},{"type":"uint256","name":"aDenominator"},{"type":"uint256","name":"bNumerator"},{"type":"uint256","name":"bDenominator"},{"type":"uint256","name":"exponent"},{"type":"uint256","name":"_decimals"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"getParentSealBitmap","inputs":[{"type":"uint256","name":"blockNumber"}],"constant":true},{"type":"event","name":"InflationFactorUpdated","inputs":[{"type":"uint256","name":"factor","indexed":false},{"type":"uint256","name":"lastUpdated","indexed":false}],"anonymous":false},{"type":"event","name":"InflationParametersUpdated","inputs":[{"type":"uint256","name":"rate","indexed":false},{"type":"uint256","name":"updatePeriod","indexed":false},{"type":"uint256","name":"lastUpdated","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"TransferComment","inputs":[{"type":"string","name":"comment","indexed":false}],"anonymous":false},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","indexed":true},{"type":"address","name":"spender","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"RegistrySet","inputs":[{"type":"address","name":"registryAddress","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","indexed":true},{"type":"address","name":"newOwner","indexed":true}],"anonymous":false}]
              

Contract Creation Code

0x6080604052600062000016620000ba60201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620000c2565b600033905090565b616c2a80620000d26000396000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c80637385e5da11610151578063a67f8747116100c3578063df4da46111610087578063df4da461146111f5578063e1d6aceb14611213578063e50e652d146112ce578063ec68307214611310578063f2fde38b1461138b578063fae8db0a146113cf57610269565b8063a67f87471461105e578063a9059cbb14611091578063a91ee0dc146110f7578063af31f5871461113b578063dd62ed3e1461117d57610269565b80638da5cb5b116101155780638da5cb5b14610ea95780638f32d59b14610ef357806395d89b4114610f155780639a7b3be714610f985780639b2b592f14610fb6578063a457c2d714610ff857610269565b80637385e5da14610b9a5780637b10399914610bb857806382b9351614610c0257806387ee8a0f14610dbc5780638a88362614610dda57610269565b806339509351116101ea57806358cf9672116101ae57806358cf9672146108d65780635d180adb1461092457806367960e911461099c5780636a30b25314610a6b57806370a0823114610b38578063715018a614610b9057610269565b806339509351146106b35780633b1eb4bf1461071957806340c10f191461075b57806342966c68146107c15780634b2c2f441461080757610269565b806318160ddd1161023157806318160ddd14610429578063222836ad1461044757806323b872dd1461047f57806323f0ab6514610505578063313ce5671461068f57610269565b806306fdde031461026e578063095ea7b3146102f1578063123633ea1461035757806312c6c099146103c5578063158ef93e14610407575b600080fd5b610276611411565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102b657808201518184015260208101905061029b565b50505050905090810190601f1680156102e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61033d6004803603604081101561030757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114b3565b604051808215151515815260200191505060405180910390f35b6103836004803603602081101561036d57600080fd5b81019080803590602001909291905050506116d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103f1600480360360208110156103db57600080fd5b8101908080359060200190929190505050611827565b6040518082815260200191505060405180910390f35b61040f611850565b604051808215151515815260200191505060405180910390f35b610431611863565b6040518082815260200191505060405180910390f35b61047d6004803603604081101561045d57600080fd5b810190808035906020019092919080359060200190929190505050611875565b005b6104eb6004803603606081101561049557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611ada565b604051808215151515815260200191505060405180910390f35b6106756004803603606081101561051b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561055857600080fd5b82018360208201111561056a57600080fd5b8035906020019184600183028401116401000000008311171561058c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156105ef57600080fd5b82018360208201111561060157600080fd5b8035906020019184600183028401116401000000008311171561062357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612160565b604051808215151515815260200191505060405180910390f35b610697612319565b604051808260ff1660ff16815260200191505060405180910390f35b6106ff600480360360408110156106c957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612330565b604051808215151515815260200191505060405180910390f35b6107456004803603602081101561072f57600080fd5b81019080803590602001909291905050506125ed565b6040518082815260200191505060405180910390f35b6107a76004803603604081101561077157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612607565b604051808215151515815260200191505060405180910390f35b6107ed600480360360208110156107d757600080fd5b8101908080359060200190929190505050612966565b604051808215151515815260200191505060405180910390f35b6108c06004803603602081101561081d57600080fd5b810190808035906020019064010000000081111561083a57600080fd5b82018360208201111561084c57600080fd5b8035906020019184600183028401116401000000008311171561086e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612da5565b6040518082815260200191505060405180910390f35b610922600480360360408110156108ec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612f39565b005b61095a6004803603604081101561093a57600080fd5b810190808035906020019092919080359060200190929190505050613277565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610a55600480360360208110156109b257600080fd5b81019080803590602001906401000000008111156109cf57600080fd5b8201836020820111156109e157600080fd5b80359060200191846001830284011164010000000083111715610a0357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506133c9565b6040518082815260200191505060405180910390f35b610b366004803603610100811015610a8257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919050505061355d565b005b610b7a60048036036020811015610b4e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613853565b6040518082815260200191505060405180910390f35b610b986138a4565b005b610ba26139dd565b6040518082815260200191505060405180910390f35b610bc06139ed565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610dba6004803603610100811015610c1957600080fd5b8101908080359060200190640100000000811115610c3657600080fd5b820183602082011115610c4857600080fd5b80359060200191846001830284011164010000000083111715610c6a57600080fd5b909192939192939080359060200190640100000000811115610c8b57600080fd5b820183602082011115610c9d57600080fd5b80359060200191846001830284011164010000000083111715610cbf57600080fd5b9091929391929390803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190640100000000811115610d2157600080fd5b820183602082011115610d3357600080fd5b80359060200191846020830284011164010000000083111715610d5557600080fd5b909192939192939080359060200190640100000000811115610d7657600080fd5b820183602082011115610d8857600080fd5b80359060200191846020830284011164010000000083111715610daa57600080fd5b9091929391929390505050613a13565b005b610dc4613d01565b6040518082815260200191505060405180910390f35b610e9360048036036020811015610df057600080fd5b8101908080359060200190640100000000811115610e0d57600080fd5b820183602082011115610e1f57600080fd5b80359060200191846001830284011164010000000083111715610e4157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613e48565b6040518082815260200191505060405180910390f35b610eb1613fdc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610efb614005565b604051808215151515815260200191505060405180910390f35b610f1d614063565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610f5d578082015181840152602081019050610f42565b50505050905090810190601f168015610f8a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610fa0614105565b6040518082815260200191505060405180910390f35b610fe260048036036020811015610fcc57600080fd5b8101908080359060200190929190505050614115565b6040518082815260200191505060405180910390f35b6110446004803603604081101561100e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061425e565b604051808215151515815260200191505060405180910390f35b611066614495565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b6110dd600480360360408110156110a757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506144f9565b604051808215151515815260200191505060405180910390f35b6111396004803603602081101561110d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506146cd565b005b6111676004803603602081101561115157600080fd5b8101908080359060200190929190505050614871565b6040518082815260200191505060405180910390f35b6111df6004803603604081101561119357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506148b3565b6040518082815260200191505060405180910390f35b6111fd61493a565b6040518082815260200191505060405180910390f35b6112b46004803603606081101561122957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561127057600080fd5b82018360208201111561128257600080fd5b803590602001918460018302840111640100000000831117156112a457600080fd5b9091929391929390505050614a76565b604051808215151515815260200191505060405180910390f35b6112fa600480360360208110156112e457600080fd5b8101908080359060200190929190505050614cb5565b6040518082815260200191505060405180910390f35b61136e600480360360c081101561132657600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190505050614d00565b604051808381526020018281526020019250505060405180910390f35b6113cd600480360360208110156113a157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614f14565b005b6113fb600480360360208110156113e557600080fd5b8101908080359060200190929190505050614f9a565b6040518082815260200191505060405180910390f35b606060028054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114a95780601f1061147e576101008083540402835291602001916114a9565b820191906000526020600020905b81548152906001019060200180831161148c57829003601f168201915b5050505050905090565b60006114bd616763565b60006114c76150e3565b8092508193505050600860030154811461155e5781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761153b60086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156115e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180616a5d602a913960400191505060405180910390fd5b83600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925866040518082815260200191505060405180910390a360019250505092915050565b60006060600060fa73ffffffffffffffffffffffffffffffffffffffff16844360405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061174f578051825260208201915060208101905060208303925061172c565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146117af576040519150601f19603f3d011682016040523d82523d6000602084013e6117b4565b606091505b50809350819250505080611813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001806169b5603d913960400191505060405180910390fd5b61181e8260006152bc565b92505050919050565b6000611831616763565b6118396150e3565b508091505061184881846152d3565b915050919050565b600060149054906101000a900460ff1681565b6000611870600654614871565b905090565b61187d614005565b6118ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6118f7616763565b60006119016150e3565b809250819350505060086003015481146119985781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761197560086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b60008414156119f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806168fe6027913960400191505060405180910390fd5b60008311611a68576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f757064617465506572696f64206d757374206265203e2030000000000000000081525060200191505060405180910390fd5b611a7184615300565b600860000160008201518160000155905050826008600201819055507fa0035d6667ffb7d387c86c7228141c4a877e8ed831b267ac928a2f5b651c155d84844260405180848152602001838152602001828152602001935050505060405180910390a150505050565b6000611ae4616763565b6000611aee6150e3565b80925081935050506008600301548114611b855781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a97611b6260086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b611b8d61531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611c0957600080fd5b505afa158015611c1d573d6000803e3d6000fd5b505050506040513d6020811015611c3357600080fd5b810190808051906020019092919050505015611c9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b6000611cbf6008600101604051806020016040529081600082015481525050866152d3565b9050600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415611d47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180616bb2602a913960400191505060405180910390fd5b600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054811115611ddf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180616aa86029913960400191505060405180910390fd5b600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054851115611eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180616ad16038913960400191505060405180910390fd5b611f0681600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611f9b81600560008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061206d85600760008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600760008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040518082815260200191505060405180910390a3600193505050509392505050565b60008060fb73ffffffffffffffffffffffffffffffffffffffff16858585604051602001808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140183805190602001908083835b602083106121e957805182526020820191506020810190506020830392506121c6565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061223a5780518252602082019150602081019050602083039250612217565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b602083106122a35780518252602082019150602081019050602083039250612280565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114612303576040519150601f19603f3d011682016040523d82523d6000602084013e612308565b606091505b505080915050809150509392505050565b6000600460009054906101000a900460ff16905090565b600061233a616763565b60006123446150e3565b809250819350505060086003015481146123db5781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a976123b860086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415612461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180616a5d602a913960400191505060405180910390fd5b6000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006124f7868361541990919063ffffffff16565b905080600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3600194505050505092915050565b6000612600826125fb61493a565b6154eb565b9050919050565b6000612611616763565b600061261b6150e3565b809250819350505060086003015481146126b25781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761268f60086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd92723360405160200180807f45786368616e67650000000000000000000000000000000000000000000000008152506008019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561276b57600080fd5b505afa15801561277f573d6000803e3d6000fd5b505050506040513d602081101561279557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806128fd5750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd92723360405160200180807f56616c696461746f727300000000000000000000000000000000000000000000815250600a019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561289357600080fd5b505afa1580156128a7573d6000803e3d6000fd5b505050506040513d60208110156128bd57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612952576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260418152602001806168bd6041913960600191505060405180910390fd5b61295c8585615523565b9250505092915050565b600060405160200180807f45786368616e67650000000000000000000000000000000000000000000000008152506008019050604051602081830303815290604052805190602001203373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612a3957600080fd5b505afa158015612a4d573d6000803e3d6000fd5b505050506040513d6020811015612a6357600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614612afd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f6f6e6c79207265676973746572656420636f6e7472616374000000000000000081525060200191505060405180910390fd5b612b05616763565b6000612b0f6150e3565b80925081935050506008600301548114612ba65781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a97612b8360086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b6000612bcb6008600101604051806020016040529081600082015481525050876152d3565b9050600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054811115612c82576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f76616c75652065786365656465642062616c616e6365206f662073656e64657281525060200191505060405180910390fd5b612c97816006546154a190919063ffffffff16565b600681905550612cef81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a36001945050505050919050565b60006060600060f473ffffffffffffffffffffffffffffffffffffffff16846040516020018082805190602001908083835b60208310612dfa5780518252602082019150602081019050602083039250612dd7565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310612e615780518252602082019150602081019050602083039250612e3e565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114612ec1576040519150601f19603f3d011682016040523d82523d6000602084013e612ec6565b606091505b50809350819250505080612f25576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806169256038913960400191505060405180910390fd5b612f30826000615722565b92505050919050565b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612fdb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4f6e6c7920564d2063616e2063616c6c0000000000000000000000000000000081525060200191505060405180910390fd5b612fe361531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561305f57600080fd5b505afa158015613073573d6000803e3d6000fd5b505050506040513d602081101561308957600080fd5b8101908080519060200190929190505050156130f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b6130f8616763565b60006131026150e3565b809250819350505060086003015481146131995781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761317660086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b60006131be6008600101604051806020016040529081600082015481525050856152d3565b905061321281600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061326a816006546154a190919063ffffffff16565b6006819055505050505050565b60006060600060fa73ffffffffffffffffffffffffffffffffffffffff16858560405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b602083106132f057805182526020820191506020810190506020830392506132cd565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114613350576040519150601f19603f3d011682016040523d82523d6000602084013e613355565b606091505b508093508192505050806133b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180616a276036913960400191505060405180910390fd5b6133bf8260006152bc565b9250505092915050565b60006060600060f673ffffffffffffffffffffffffffffffffffffffff16846040516020018082805190602001908083835b6020831061341e57805182526020820191506020810190506020830392506133fb565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b602083106134855780518252602082019150602081019050602083039250613462565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146134e5576040519150601f19603f3d011682016040523d82523d6000602084013e6134ea565b606091505b50809350819250505080613549576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180616bdc6023913960400191505060405180910390fd5b613554826000615722565b92505050919050565b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146135ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4f6e6c7920564d2063616e2063616c6c0000000000000000000000000000000081525060200191505060405180910390fd5b61360761531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561368357600080fd5b505afa158015613697573d6000803e3d6000fd5b505050506040513d60208110156136ad57600080fd5b810190808051906020019092919050505015613714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b60006137396008600101604051806020016040529081600082015481525050866152d3565b905061378d81600560008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506137ed6137de8a88856157b3565b8261541990919063ffffffff16565b905061380c6137fd8a8a876157b3565b8261541990919063ffffffff16565b905061382b61381c8a89866157b3565b8261541990919063ffffffff16565b90506138428160065461541990919063ffffffff16565b600681905550505050505050505050565b600061389d600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054614871565b9050919050565b6138ac614005565b61391e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60006139e843614cb5565b905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff1615613a96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f636f6e747261637420616c726561647920696e697469616c697a65640000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff0219169083151502179055506000861415613b0b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806168976026913960400191505060405180910390fd5b60008511613b64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061684a6027913960400191505060405180910390fd5b613b6d3361591f565b60006006819055508b8b60029190613b86929190616776565b50898960039190613b98929190616776565b5087600460006101000a81548160ff021916908360ff160217905550613bbd86615300565b600860000160008201518160000155905050613bd7615a63565b6008600101600082015181600001559050508460086002018190555042600860030181905550818190508484905014613c78576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4172726179206c656e677468206d69736d61746368000000000000000000000081525060200191505060405180910390fd5b60008090505b84849050811015613ce957613ccd858583818110613c9857fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16848484818110613cc157fe5b90506020020135615523565b50613ce260018261541990919063ffffffff16565b9050613c7e565b50613cf3876146cd565b505050505050505050505050565b60006060600060f973ffffffffffffffffffffffffffffffffffffffff1643604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b60208310613d725780518252602082019150602081019050602083039250613d4f565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b50809350819250505080613e36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001806169f26035913960400191505060405180910390fd5b613e418260006152bc565b9250505090565b60006060600060f773ffffffffffffffffffffffffffffffffffffffff16846040516020018082805190602001908083835b60208310613e9d5780518252602082019150602081019050602083039250613e7a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310613f045780518252602082019150602081019050602083039250613ee1565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114613f64576040519150601f19603f3d011682016040523d82523d6000602084013e613f69565b606091505b50809350819250505080613fc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180616b816031913960400191505060405180910390fd5b613fd38260006152bc565b92505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16614047615a89565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b606060038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156140fb5780601f106140d0576101008083540402835291602001916140fb565b820191906000526020600020905b8154815290600101906020018083116140de57829003601f168201915b5050505050905090565b6000614110436125ed565b905090565b60006060600060f973ffffffffffffffffffffffffffffffffffffffff1684604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b602083106141865780518252602082019150602081019050602083039250614163565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146141e6576040519150601f19603f3d011682016040523d82523d6000602084013e6141eb565b606091505b5080935081925050508061424a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018061681c602e913960400191505060405180910390fd5b6142558260006152bc565b92505050919050565b6000614268616763565b60006142726150e3565b809250819350505060086003015481146143095781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a976142e660086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b6000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061439f86836154a190919063ffffffff16565b905080600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3600194505050505092915050565b6000806000806144bd60086000016040518060200160405290816000820154815250506152ae565b6144df60086001016040518060200160405290816000820154815250506152ae565b600860020154600860030154935093509350935090919293565b6000614503616763565b600061450d6150e3565b809250819350505060086003015481146145a45781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761458160086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b6145ac61531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561462857600080fd5b505afa15801561463c573d6000803e3d6000fd5b505050506040513d602081101561465257600080fd5b8101908080519060200190929190505050156146b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b6146c38585615a91565b9250505092915050565b6146d5614005565b614747576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156147ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616e6e6f7420726567697374657220746865206e756c6c206164647265737381525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b60405160405180910390a250565b600061487b616763565b6148836150e3565b50809150506148ab6148a68261489886615d71565b615dfb90919063ffffffff16565b615f44565b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60006060600060f873ffffffffffffffffffffffffffffffffffffffff166040516020016040516020818303038152906040526040518082805190602001908083835b602083106149a0578051825260208201915060208101905060208303925061497d565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114614a00576040519150601f19603f3d011682016040523d82523d6000602084013e614a05565b606091505b50809350819250505080614a64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180616b306025913960400191505060405180910390fd5b614a6f8260006152bc565b9250505090565b6000614a80616763565b6000614a8a6150e3565b80925081935050506008600301548114614b215781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a97614afe60086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b614b2961531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015614ba557600080fd5b505afa158015614bb9573d6000803e3d6000fd5b505050506040513d6020811015614bcf57600080fd5b810190808051906020019092919050505015614c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b6000614c4288886144f9565b90507fe5d4e30fb8364e57bc4d662a07d0cf36f4c34552004c4c3624620a2c1d1c03dc868660405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a1809350505050949350505050565b6000614cf96003614ceb6002614cdd6002614ccf88614115565b615f6590919063ffffffff16565b61541990919063ffffffff16565b615feb90919063ffffffff16565b9050919050565b60008060008714158015614d15575060008514155b614d87576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f612064656e6f6d696e61746f72206973207a65726f000000000000000000000081525060200191505060405180910390fd5b6000806000606060fc73ffffffffffffffffffffffffffffffffffffffff168c8c8c8c8c8c6040516020018087815260200186815260200185815260200184815260200183815260200182815260200196505050505050506040516020818303038152906040526040518082805190602001908083835b60208310614e215780518252602082019150602081019050602083039250614dfe565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114614e81576040519150601f19603f3d011682016040523d82523d6000602084013e614e86565b606091505b50809250819350505081614ee5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180616b096027913960400191505060405180910390fd5b614ef08160006152bc565b9350614efd8160206152bc565b925083839550955050505050965096945050505050565b614f1c614005565b614f8e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b614f978161591f565b50565b60006060600060f573ffffffffffffffffffffffffffffffffffffffff1684604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061500b5780518252602082019150602081019050602083039250614fe8565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b508093508192505050806150cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180616b55602c913960400191505060405180910390fd5b6150da826000615722565b92505050919050565b6150eb616763565b600061510a60086002015460086003015461541990919063ffffffff16565b42101561513d576008600101600860030154816040518060200160405290816000820154815250509150915091506152aa565b6000806000615171600860020154615163600860030154426154a190919063ffffffff16565b615feb90919063ffffffff16565b90506151f361519860086001016040518060200160405290816000820154815250506152ae565b6151a86151a3615a63565b6152ae565b6151ca60086000016040518060200160405290816000820154815250506152ae565b6151da6151d5615a63565b6152ae565b85600460009054906101000a900460ff1660ff16614d00565b8093508194505050600083148061520a5750600082145b1561523e576008600101600860030154816040518060200160405290816000820154815250509150945094505050506152aa565b615246616763565b61526961525284615300565b61525b86615300565b615dfb90919063ffffffff16565b9050600061529c61528884600860020154615f6590919063ffffffff16565b60086003015461541990919063ffffffff16565b905081819650965050505050505b9091565b600081600001519050919050565b60006152c88383615722565b60001c905092915050565b60006152f86152f36152e484615d71565b8561603590919063ffffffff16565b615f44565b905092915050565b615308616763565b6040518060200160405280838152509050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed60405160200180807f467265657a6572000000000000000000000000000000000000000000000000008152506007019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156153d957600080fd5b505afa1580156153ed573d6000803e3d6000fd5b505050506040513d602081101561540357600080fd5b8101908080519060200190929190505050905090565b600080828401905083811015615497576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60006154e383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250616494565b905092915050565b6000808284816154f757fe5b049050600083858161550557fe5b061415615515578091505061551d565b600181019150505b92915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156155c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f302069732061207265736572766564206164647265737300000000000000000081525060200191505060405180910390fd5b60008214156155d9576001905061571c565b60006155fe6008600101604051806020016040529081600082015481525050846152d3565b90506156158160065461541990919063ffffffff16565b60068190555061566d81600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150505b92915050565b6000602082018351101561579e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f736c6963696e67206f7574206f662072616e676500000000000000000000000081525060200191505060405180910390fd5b60006020830184015190508091505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156157f25760009050615918565b60006158176008600101604051806020016040529081600082015481525050846152d3565b905061586b81600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3809150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156159a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806168716026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b615a6b616763565b604051806020016040528069d3c21bcecceda1000000815250905090565b600033905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415615b18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180616bb2602a913960400191505060405180910390fd5b6000615b3d6008600101604051806020016040529081600082015481525050846152d3565b905080600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015615bd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180616aa86029913960400191505060405180910390fd5b615c2981600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550615cbe81600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191505092915050565b615d79616763565b615d81616554565b821115615dd9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061697f6036913960400191505060405180910390fd5b604051806020016040528069d3c21bcecceda100000084028152509050919050565b615e03616763565b600082600001511415615e7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f63616e277420646976696465206279203000000000000000000000000000000081525060200191505060405180910390fd5b600069d3c21bcecceda10000008460000151029050836000015169d3c21bcecceda10000008281615eab57fe5b0414615f1f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f766572666c6f7720617420646976696465000000000000000000000000000081525060200191505060405180910390fd5b604051806020016040528084600001518381615f3757fe5b0481525091505092915050565b600069d3c21bcecceda1000000826000015181615f5d57fe5b049050919050565b600080831415615f785760009050615fe5565b6000828402905082848281615f8957fe5b0414615fe0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180616a876021913960400191505060405180910390fd5b809150505b92915050565b600061602d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250616573565b905092915050565b61603d616763565b600083600001511480616054575060008260000151145b156160705760405180602001604052806000815250905061648e565b69d3c21bcecceda10000008260000151141561608e5782905061648e565b69d3c21bcecceda1000000836000015114156160ac5781905061648e565b600069d3c21bcecceda10000006160c285616639565b60000151816160cd57fe5b04905060006160db85616670565b600001519050600069d3c21bcecceda10000006160f786616639565b600001518161610257fe5b049050600061611086616670565b60000151905060008285029050600085146161a4578285828161612f57fe5b04146161a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783179312064657465637465640000000000000000000081525060200191505060405180910390fd5b5b600069d3c21bcecceda100000082029050600082146162465769d3c21bcecceda10000008282816161d157fe5b0414616245576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f6f766572666c6f772078317931202a206669786564312064657465637465640081525060200191505060405180910390fd5b5b80915060008486029050600086146162d7578486828161626257fe5b04146162d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783279312064657465637465640000000000000000000081525060200191505060405180910390fd5b5b600084880290506000881461636557848882816162f057fe5b0414616364576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783179322064657465637465640000000000000000000081525060200191505060405180910390fd5b5b61636d6166ad565b878161637557fe5b0496506163806166ad565b858161638857fe5b049450600085880290506000881461641957858882816163a457fe5b0414616418576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783279322064657465637465640000000000000000000081525060200191505060405180910390fd5b5b616421616763565b604051806020016040528087815250905061644a816040518060200160405280878152506166ba565b9050616464816040518060200160405280868152506166ba565b905061647e816040518060200160405280858152506166ba565b9050809a50505050505050505050505b92915050565b6000838311158290616541576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156165065780820151818401526020810190506164eb565b50505050905090810190601f1680156165335780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60007601357c299a88ea76a58924d52ce4f26a85af186c2b9e74905090565b6000808311829061661f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156165e45780820151818401526020810190506165c9565b50505050905090810190601f1680156166115780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161662b57fe5b049050809150509392505050565b616641616763565b604051806020016040528069d3c21bcecceda10000008085600001518161666457fe5b04028152509050919050565b616678616763565b604051806020016040528069d3c21bcecceda10000008085600001518161669b57fe5b04028460000151038152509050919050565b600064e8d4a51000905090565b6166c2616763565b600082600001518460000151019050836000015181101561674b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f616464206f766572666c6f77206465746563746564000000000000000000000081525060200191505060405180910390fd5b60405180602001604052808281525091505092915050565b6040518060200160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106167b757803560ff19168380011785556167e5565b828001600101855582156167e5579182015b828111156167e45782358255916020019190600101906167c9565b5b5090506167f291906167f6565b5090565b61681891905b808211156168145760008160009055506001016167fc565b5090565b9056fe6572726f722063616c6c696e67206e756d62657256616c696461746f7273496e53657420707265636f6d70696c65696e666c6174696f6e466163746f72557064617465506572696f64206d757374206265203e20304f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734d7573742070726f766964652061206e6f6e2d7a65726f20696e666c6174696f6e20726174654f6e6c79207468652045786368616e676520616e642056616c696461746f727320636f6e7472616374732061726520617574686f72697a656420746f206d696e744d7573742070726f766964652061206e6f6e2d7a65726f20696e666c6174696f6e20726174652e6572726f722063616c6c696e672067657456657269666965645365616c4269746d617046726f6d48656164657220707265636f6d70696c6563616e27742063616c6c207768656e20636f6e74726163742069732066726f7a656e63616e277420637265617465206669786964697479206e756d626572206c6172676572207468616e206d61784e6577466978656428296572726f722063616c6c696e672076616c696461746f725369676e65724164647265737346726f6d43757272656e7453657420707265636f6d70696c656572726f722063616c6c696e67206e756d62657256616c696461746f7273496e43757272656e7453657420707265636f6d70696c656572726f722063616c6c696e672076616c696461746f725369676e65724164647265737346726f6d53657420707265636f6d70696c6572657365727665642061646472657373203078302063616e6e6f74206861766520616c6c6f77616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777472616e736665722076616c75652065786365656465642062616c616e6365206f662073656e6465727472616e736665722076616c75652065786365656465642073656e646572277320616c6c6f77616e636520666f7220726563697069656e746572726f722063616c6c696e67206672616374696f6e4d756c45787020707265636f6d70696c656572726f722063616c6c696e672067657445706f636853697a6520707265636f6d70696c656572726f722063616c6c696e6720676574506172656e745365616c4269746d617020707265636f6d70696c656572726f722063616c6c696e6720676574426c6f636b4e756d62657246726f6d48656164657220707265636f6d70696c657472616e7366657220617474656d7074656420746f2072657365727665642061646472657373203078306572726f722063616c6c696e67206861736848656164657220707265636f6d70696c65a165627a7a72305820a0ebf270b001d32209f9c4af9aa3bba7e912d230ee3ba33df412600994be0f210029

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106102695760003560e01c80637385e5da11610151578063a67f8747116100c3578063df4da46111610087578063df4da461146111f5578063e1d6aceb14611213578063e50e652d146112ce578063ec68307214611310578063f2fde38b1461138b578063fae8db0a146113cf57610269565b8063a67f87471461105e578063a9059cbb14611091578063a91ee0dc146110f7578063af31f5871461113b578063dd62ed3e1461117d57610269565b80638da5cb5b116101155780638da5cb5b14610ea95780638f32d59b14610ef357806395d89b4114610f155780639a7b3be714610f985780639b2b592f14610fb6578063a457c2d714610ff857610269565b80637385e5da14610b9a5780637b10399914610bb857806382b9351614610c0257806387ee8a0f14610dbc5780638a88362614610dda57610269565b806339509351116101ea57806358cf9672116101ae57806358cf9672146108d65780635d180adb1461092457806367960e911461099c5780636a30b25314610a6b57806370a0823114610b38578063715018a614610b9057610269565b806339509351146106b35780633b1eb4bf1461071957806340c10f191461075b57806342966c68146107c15780634b2c2f441461080757610269565b806318160ddd1161023157806318160ddd14610429578063222836ad1461044757806323b872dd1461047f57806323f0ab6514610505578063313ce5671461068f57610269565b806306fdde031461026e578063095ea7b3146102f1578063123633ea1461035757806312c6c099146103c5578063158ef93e14610407575b600080fd5b610276611411565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102b657808201518184015260208101905061029b565b50505050905090810190601f1680156102e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61033d6004803603604081101561030757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114b3565b604051808215151515815260200191505060405180910390f35b6103836004803603602081101561036d57600080fd5b81019080803590602001909291905050506116d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103f1600480360360208110156103db57600080fd5b8101908080359060200190929190505050611827565b6040518082815260200191505060405180910390f35b61040f611850565b604051808215151515815260200191505060405180910390f35b610431611863565b6040518082815260200191505060405180910390f35b61047d6004803603604081101561045d57600080fd5b810190808035906020019092919080359060200190929190505050611875565b005b6104eb6004803603606081101561049557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611ada565b604051808215151515815260200191505060405180910390f35b6106756004803603606081101561051b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561055857600080fd5b82018360208201111561056a57600080fd5b8035906020019184600183028401116401000000008311171561058c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156105ef57600080fd5b82018360208201111561060157600080fd5b8035906020019184600183028401116401000000008311171561062357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612160565b604051808215151515815260200191505060405180910390f35b610697612319565b604051808260ff1660ff16815260200191505060405180910390f35b6106ff600480360360408110156106c957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612330565b604051808215151515815260200191505060405180910390f35b6107456004803603602081101561072f57600080fd5b81019080803590602001909291905050506125ed565b6040518082815260200191505060405180910390f35b6107a76004803603604081101561077157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612607565b604051808215151515815260200191505060405180910390f35b6107ed600480360360208110156107d757600080fd5b8101908080359060200190929190505050612966565b604051808215151515815260200191505060405180910390f35b6108c06004803603602081101561081d57600080fd5b810190808035906020019064010000000081111561083a57600080fd5b82018360208201111561084c57600080fd5b8035906020019184600183028401116401000000008311171561086e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612da5565b6040518082815260200191505060405180910390f35b610922600480360360408110156108ec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612f39565b005b61095a6004803603604081101561093a57600080fd5b810190808035906020019092919080359060200190929190505050613277565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610a55600480360360208110156109b257600080fd5b81019080803590602001906401000000008111156109cf57600080fd5b8201836020820111156109e157600080fd5b80359060200191846001830284011164010000000083111715610a0357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506133c9565b6040518082815260200191505060405180910390f35b610b366004803603610100811015610a8257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919050505061355d565b005b610b7a60048036036020811015610b4e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613853565b6040518082815260200191505060405180910390f35b610b986138a4565b005b610ba26139dd565b6040518082815260200191505060405180910390f35b610bc06139ed565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610dba6004803603610100811015610c1957600080fd5b8101908080359060200190640100000000811115610c3657600080fd5b820183602082011115610c4857600080fd5b80359060200191846001830284011164010000000083111715610c6a57600080fd5b909192939192939080359060200190640100000000811115610c8b57600080fd5b820183602082011115610c9d57600080fd5b80359060200191846001830284011164010000000083111715610cbf57600080fd5b9091929391929390803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190640100000000811115610d2157600080fd5b820183602082011115610d3357600080fd5b80359060200191846020830284011164010000000083111715610d5557600080fd5b909192939192939080359060200190640100000000811115610d7657600080fd5b820183602082011115610d8857600080fd5b80359060200191846020830284011164010000000083111715610daa57600080fd5b9091929391929390505050613a13565b005b610dc4613d01565b6040518082815260200191505060405180910390f35b610e9360048036036020811015610df057600080fd5b8101908080359060200190640100000000811115610e0d57600080fd5b820183602082011115610e1f57600080fd5b80359060200191846001830284011164010000000083111715610e4157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613e48565b6040518082815260200191505060405180910390f35b610eb1613fdc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610efb614005565b604051808215151515815260200191505060405180910390f35b610f1d614063565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610f5d578082015181840152602081019050610f42565b50505050905090810190601f168015610f8a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610fa0614105565b6040518082815260200191505060405180910390f35b610fe260048036036020811015610fcc57600080fd5b8101908080359060200190929190505050614115565b6040518082815260200191505060405180910390f35b6110446004803603604081101561100e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061425e565b604051808215151515815260200191505060405180910390f35b611066614495565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b6110dd600480360360408110156110a757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506144f9565b604051808215151515815260200191505060405180910390f35b6111396004803603602081101561110d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506146cd565b005b6111676004803603602081101561115157600080fd5b8101908080359060200190929190505050614871565b6040518082815260200191505060405180910390f35b6111df6004803603604081101561119357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506148b3565b6040518082815260200191505060405180910390f35b6111fd61493a565b6040518082815260200191505060405180910390f35b6112b46004803603606081101561122957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561127057600080fd5b82018360208201111561128257600080fd5b803590602001918460018302840111640100000000831117156112a457600080fd5b9091929391929390505050614a76565b604051808215151515815260200191505060405180910390f35b6112fa600480360360208110156112e457600080fd5b8101908080359060200190929190505050614cb5565b6040518082815260200191505060405180910390f35b61136e600480360360c081101561132657600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190505050614d00565b604051808381526020018281526020019250505060405180910390f35b6113cd600480360360208110156113a157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614f14565b005b6113fb600480360360208110156113e557600080fd5b8101908080359060200190929190505050614f9a565b6040518082815260200191505060405180910390f35b606060028054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114a95780601f1061147e576101008083540402835291602001916114a9565b820191906000526020600020905b81548152906001019060200180831161148c57829003601f168201915b5050505050905090565b60006114bd616763565b60006114c76150e3565b8092508193505050600860030154811461155e5781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761153b60086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156115e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180616a5d602a913960400191505060405180910390fd5b83600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925866040518082815260200191505060405180910390a360019250505092915050565b60006060600060fa73ffffffffffffffffffffffffffffffffffffffff16844360405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061174f578051825260208201915060208101905060208303925061172c565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146117af576040519150601f19603f3d011682016040523d82523d6000602084013e6117b4565b606091505b50809350819250505080611813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001806169b5603d913960400191505060405180910390fd5b61181e8260006152bc565b92505050919050565b6000611831616763565b6118396150e3565b508091505061184881846152d3565b915050919050565b600060149054906101000a900460ff1681565b6000611870600654614871565b905090565b61187d614005565b6118ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6118f7616763565b60006119016150e3565b809250819350505060086003015481146119985781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761197560086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b60008414156119f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806168fe6027913960400191505060405180910390fd5b60008311611a68576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f757064617465506572696f64206d757374206265203e2030000000000000000081525060200191505060405180910390fd5b611a7184615300565b600860000160008201518160000155905050826008600201819055507fa0035d6667ffb7d387c86c7228141c4a877e8ed831b267ac928a2f5b651c155d84844260405180848152602001838152602001828152602001935050505060405180910390a150505050565b6000611ae4616763565b6000611aee6150e3565b80925081935050506008600301548114611b855781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a97611b6260086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b611b8d61531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611c0957600080fd5b505afa158015611c1d573d6000803e3d6000fd5b505050506040513d6020811015611c3357600080fd5b810190808051906020019092919050505015611c9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b6000611cbf6008600101604051806020016040529081600082015481525050866152d3565b9050600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415611d47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180616bb2602a913960400191505060405180910390fd5b600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054811115611ddf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180616aa86029913960400191505060405180910390fd5b600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054851115611eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180616ad16038913960400191505060405180910390fd5b611f0681600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611f9b81600560008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061206d85600760008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600760008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040518082815260200191505060405180910390a3600193505050509392505050565b60008060fb73ffffffffffffffffffffffffffffffffffffffff16858585604051602001808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660601b815260140183805190602001908083835b602083106121e957805182526020820191506020810190506020830392506121c6565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061223a5780518252602082019150602081019050602083039250612217565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b602083106122a35780518252602082019150602081019050602083039250612280565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114612303576040519150601f19603f3d011682016040523d82523d6000602084013e612308565b606091505b505080915050809150509392505050565b6000600460009054906101000a900460ff16905090565b600061233a616763565b60006123446150e3565b809250819350505060086003015481146123db5781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a976123b860086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415612461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180616a5d602a913960400191505060405180910390fd5b6000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006124f7868361541990919063ffffffff16565b905080600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3600194505050505092915050565b6000612600826125fb61493a565b6154eb565b9050919050565b6000612611616763565b600061261b6150e3565b809250819350505060086003015481146126b25781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761268f60086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd92723360405160200180807f45786368616e67650000000000000000000000000000000000000000000000008152506008019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561276b57600080fd5b505afa15801561277f573d6000803e3d6000fd5b505050506040513d602081101561279557600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806128fd5750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd92723360405160200180807f56616c696461746f727300000000000000000000000000000000000000000000815250600a019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561289357600080fd5b505afa1580156128a7573d6000803e3d6000fd5b505050506040513d60208110156128bd57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612952576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260418152602001806168bd6041913960600191505060405180910390fd5b61295c8585615523565b9250505092915050565b600060405160200180807f45786368616e67650000000000000000000000000000000000000000000000008152506008019050604051602081830303815290604052805190602001203373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612a3957600080fd5b505afa158015612a4d573d6000803e3d6000fd5b505050506040513d6020811015612a6357600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614612afd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f6f6e6c79207265676973746572656420636f6e7472616374000000000000000081525060200191505060405180910390fd5b612b05616763565b6000612b0f6150e3565b80925081935050506008600301548114612ba65781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a97612b8360086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b6000612bcb6008600101604051806020016040529081600082015481525050876152d3565b9050600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054811115612c82576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f76616c75652065786365656465642062616c616e6365206f662073656e64657281525060200191505060405180910390fd5b612c97816006546154a190919063ffffffff16565b600681905550612cef81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a36001945050505050919050565b60006060600060f473ffffffffffffffffffffffffffffffffffffffff16846040516020018082805190602001908083835b60208310612dfa5780518252602082019150602081019050602083039250612dd7565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310612e615780518252602082019150602081019050602083039250612e3e565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114612ec1576040519150601f19603f3d011682016040523d82523d6000602084013e612ec6565b606091505b50809350819250505080612f25576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260388152602001806169256038913960400191505060405180910390fd5b612f30826000615722565b92505050919050565b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612fdb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4f6e6c7920564d2063616e2063616c6c0000000000000000000000000000000081525060200191505060405180910390fd5b612fe361531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561305f57600080fd5b505afa158015613073573d6000803e3d6000fd5b505050506040513d602081101561308957600080fd5b8101908080519060200190929190505050156130f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b6130f8616763565b60006131026150e3565b809250819350505060086003015481146131995781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761317660086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b60006131be6008600101604051806020016040529081600082015481525050856152d3565b905061321281600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061326a816006546154a190919063ffffffff16565b6006819055505050505050565b60006060600060fa73ffffffffffffffffffffffffffffffffffffffff16858560405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b602083106132f057805182526020820191506020810190506020830392506132cd565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114613350576040519150601f19603f3d011682016040523d82523d6000602084013e613355565b606091505b508093508192505050806133b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180616a276036913960400191505060405180910390fd5b6133bf8260006152bc565b9250505092915050565b60006060600060f673ffffffffffffffffffffffffffffffffffffffff16846040516020018082805190602001908083835b6020831061341e57805182526020820191506020810190506020830392506133fb565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b602083106134855780518252602082019150602081019050602083039250613462565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146134e5576040519150601f19603f3d011682016040523d82523d6000602084013e6134ea565b606091505b50809350819250505080613549576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180616bdc6023913960400191505060405180910390fd5b613554826000615722565b92505050919050565b600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146135ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4f6e6c7920564d2063616e2063616c6c0000000000000000000000000000000081525060200191505060405180910390fd5b61360761531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561368357600080fd5b505afa158015613697573d6000803e3d6000fd5b505050506040513d60208110156136ad57600080fd5b810190808051906020019092919050505015613714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b60006137396008600101604051806020016040529081600082015481525050866152d3565b905061378d81600560008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506137ed6137de8a88856157b3565b8261541990919063ffffffff16565b905061380c6137fd8a8a876157b3565b8261541990919063ffffffff16565b905061382b61381c8a89866157b3565b8261541990919063ffffffff16565b90506138428160065461541990919063ffffffff16565b600681905550505050505050505050565b600061389d600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054614871565b9050919050565b6138ac614005565b61391e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60006139e843614cb5565b905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060149054906101000a900460ff1615613a96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f636f6e747261637420616c726561647920696e697469616c697a65640000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff0219169083151502179055506000861415613b0b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806168976026913960400191505060405180910390fd5b60008511613b64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061684a6027913960400191505060405180910390fd5b613b6d3361591f565b60006006819055508b8b60029190613b86929190616776565b50898960039190613b98929190616776565b5087600460006101000a81548160ff021916908360ff160217905550613bbd86615300565b600860000160008201518160000155905050613bd7615a63565b6008600101600082015181600001559050508460086002018190555042600860030181905550818190508484905014613c78576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f4172726179206c656e677468206d69736d61746368000000000000000000000081525060200191505060405180910390fd5b60008090505b84849050811015613ce957613ccd858583818110613c9857fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16848484818110613cc157fe5b90506020020135615523565b50613ce260018261541990919063ffffffff16565b9050613c7e565b50613cf3876146cd565b505050505050505050505050565b60006060600060f973ffffffffffffffffffffffffffffffffffffffff1643604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b60208310613d725780518252602082019150602081019050602083039250613d4f565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114613dd2576040519150601f19603f3d011682016040523d82523d6000602084013e613dd7565b606091505b50809350819250505080613e36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001806169f26035913960400191505060405180910390fd5b613e418260006152bc565b9250505090565b60006060600060f773ffffffffffffffffffffffffffffffffffffffff16846040516020018082805190602001908083835b60208310613e9d5780518252602082019150602081019050602083039250613e7a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310613f045780518252602082019150602081019050602083039250613ee1565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114613f64576040519150601f19603f3d011682016040523d82523d6000602084013e613f69565b606091505b50809350819250505080613fc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180616b816031913960400191505060405180910390fd5b613fd38260006152bc565b92505050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16614047615a89565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b606060038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156140fb5780601f106140d0576101008083540402835291602001916140fb565b820191906000526020600020905b8154815290600101906020018083116140de57829003601f168201915b5050505050905090565b6000614110436125ed565b905090565b60006060600060f973ffffffffffffffffffffffffffffffffffffffff1684604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b602083106141865780518252602082019150602081019050602083039250614163565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146141e6576040519150601f19603f3d011682016040523d82523d6000602084013e6141eb565b606091505b5080935081925050508061424a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018061681c602e913960400191505060405180910390fd5b6142558260006152bc565b92505050919050565b6000614268616763565b60006142726150e3565b809250819350505060086003015481146143095781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a976142e660086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b6000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061439f86836154a190919063ffffffff16565b905080600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3600194505050505092915050565b6000806000806144bd60086000016040518060200160405290816000820154815250506152ae565b6144df60086001016040518060200160405290816000820154815250506152ae565b600860020154600860030154935093509350935090919293565b6000614503616763565b600061450d6150e3565b809250819350505060086003015481146145a45781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a9761458160086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b6145ac61531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561462857600080fd5b505afa15801561463c573d6000803e3d6000fd5b505050506040513d602081101561465257600080fd5b8101908080519060200190929190505050156146b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b6146c38585615a91565b9250505092915050565b6146d5614005565b614747576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156147ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616e6e6f7420726567697374657220746865206e756c6c206164647265737381525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b60405160405180910390a250565b600061487b616763565b6148836150e3565b50809150506148ab6148a68261489886615d71565b615dfb90919063ffffffff16565b615f44565b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60006060600060f873ffffffffffffffffffffffffffffffffffffffff166040516020016040516020818303038152906040526040518082805190602001908083835b602083106149a0578051825260208201915060208101905060208303925061497d565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114614a00576040519150601f19603f3d011682016040523d82523d6000602084013e614a05565b606091505b50809350819250505080614a64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180616b306025913960400191505060405180910390fd5b614a6f8260006152bc565b9250505090565b6000614a80616763565b6000614a8a6150e3565b80925081935050506008600301548114614b215781600860010160008201518160000155905050806008600301819055507f08f3ed03ec9e579d1f6ab2f9e0d3dc661704696deabe37a6b6df7014f1b30a97614afe60086001016040518060200160405290816000820154815250506152ae565b600860030154604051808381526020018281526020019250505060405180910390a15b614b2961531e565b73ffffffffffffffffffffffffffffffffffffffff1663e5839836306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015614ba557600080fd5b505afa158015614bb9573d6000803e3d6000fd5b505050506040513d6020811015614bcf57600080fd5b810190808051906020019092919050505015614c36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061695d6022913960400191505060405180910390fd5b6000614c4288886144f9565b90507fe5d4e30fb8364e57bc4d662a07d0cf36f4c34552004c4c3624620a2c1d1c03dc868660405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a1809350505050949350505050565b6000614cf96003614ceb6002614cdd6002614ccf88614115565b615f6590919063ffffffff16565b61541990919063ffffffff16565b615feb90919063ffffffff16565b9050919050565b60008060008714158015614d15575060008514155b614d87576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f612064656e6f6d696e61746f72206973207a65726f000000000000000000000081525060200191505060405180910390fd5b6000806000606060fc73ffffffffffffffffffffffffffffffffffffffff168c8c8c8c8c8c6040516020018087815260200186815260200185815260200184815260200183815260200182815260200196505050505050506040516020818303038152906040526040518082805190602001908083835b60208310614e215780518252602082019150602081019050602083039250614dfe565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114614e81576040519150601f19603f3d011682016040523d82523d6000602084013e614e86565b606091505b50809250819350505081614ee5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180616b096027913960400191505060405180910390fd5b614ef08160006152bc565b9350614efd8160206152bc565b925083839550955050505050965096945050505050565b614f1c614005565b614f8e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b614f978161591f565b50565b60006060600060f573ffffffffffffffffffffffffffffffffffffffff1684604051602001808281526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061500b5780518252602082019150602081019050602083039250614fe8565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d806000811461506b576040519150601f19603f3d011682016040523d82523d6000602084013e615070565b606091505b508093508192505050806150cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180616b55602c913960400191505060405180910390fd5b6150da826000615722565b92505050919050565b6150eb616763565b600061510a60086002015460086003015461541990919063ffffffff16565b42101561513d576008600101600860030154816040518060200160405290816000820154815250509150915091506152aa565b6000806000615171600860020154615163600860030154426154a190919063ffffffff16565b615feb90919063ffffffff16565b90506151f361519860086001016040518060200160405290816000820154815250506152ae565b6151a86151a3615a63565b6152ae565b6151ca60086000016040518060200160405290816000820154815250506152ae565b6151da6151d5615a63565b6152ae565b85600460009054906101000a900460ff1660ff16614d00565b8093508194505050600083148061520a5750600082145b1561523e576008600101600860030154816040518060200160405290816000820154815250509150945094505050506152aa565b615246616763565b61526961525284615300565b61525b86615300565b615dfb90919063ffffffff16565b9050600061529c61528884600860020154615f6590919063ffffffff16565b60086003015461541990919063ffffffff16565b905081819650965050505050505b9091565b600081600001519050919050565b60006152c88383615722565b60001c905092915050565b60006152f86152f36152e484615d71565b8561603590919063ffffffff16565b615f44565b905092915050565b615308616763565b6040518060200160405280838152509050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed60405160200180807f467265657a6572000000000000000000000000000000000000000000000000008152506007019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156153d957600080fd5b505afa1580156153ed573d6000803e3d6000fd5b505050506040513d602081101561540357600080fd5b8101908080519060200190929190505050905090565b600080828401905083811015615497576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60006154e383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250616494565b905092915050565b6000808284816154f757fe5b049050600083858161550557fe5b061415615515578091505061551d565b600181019150505b92915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156155c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f302069732061207265736572766564206164647265737300000000000000000081525060200191505060405180910390fd5b60008214156155d9576001905061571c565b60006155fe6008600101604051806020016040529081600082015481525050846152d3565b90506156158160065461541990919063ffffffff16565b60068190555061566d81600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150505b92915050565b6000602082018351101561579e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f736c6963696e67206f7574206f662072616e676500000000000000000000000081525060200191505060405180910390fd5b60006020830184015190508091505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156157f25760009050615918565b60006158176008600101604051806020016040529081600082015481525050846152d3565b905061586b81600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3809150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156159a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806168716026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b615a6b616763565b604051806020016040528069d3c21bcecceda1000000815250905090565b600033905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415615b18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180616bb2602a913960400191505060405180910390fd5b6000615b3d6008600101604051806020016040529081600082015481525050846152d3565b905080600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015615bd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180616aa86029913960400191505060405180910390fd5b615c2981600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546154a190919063ffffffff16565b600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550615cbe81600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461541990919063ffffffff16565b600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191505092915050565b615d79616763565b615d81616554565b821115615dd9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061697f6036913960400191505060405180910390fd5b604051806020016040528069d3c21bcecceda100000084028152509050919050565b615e03616763565b600082600001511415615e7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f63616e277420646976696465206279203000000000000000000000000000000081525060200191505060405180910390fd5b600069d3c21bcecceda10000008460000151029050836000015169d3c21bcecceda10000008281615eab57fe5b0414615f1f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f766572666c6f7720617420646976696465000000000000000000000000000081525060200191505060405180910390fd5b604051806020016040528084600001518381615f3757fe5b0481525091505092915050565b600069d3c21bcecceda1000000826000015181615f5d57fe5b049050919050565b600080831415615f785760009050615fe5565b6000828402905082848281615f8957fe5b0414615fe0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180616a876021913960400191505060405180910390fd5b809150505b92915050565b600061602d83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250616573565b905092915050565b61603d616763565b600083600001511480616054575060008260000151145b156160705760405180602001604052806000815250905061648e565b69d3c21bcecceda10000008260000151141561608e5782905061648e565b69d3c21bcecceda1000000836000015114156160ac5781905061648e565b600069d3c21bcecceda10000006160c285616639565b60000151816160cd57fe5b04905060006160db85616670565b600001519050600069d3c21bcecceda10000006160f786616639565b600001518161610257fe5b049050600061611086616670565b60000151905060008285029050600085146161a4578285828161612f57fe5b04146161a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783179312064657465637465640000000000000000000081525060200191505060405180910390fd5b5b600069d3c21bcecceda100000082029050600082146162465769d3c21bcecceda10000008282816161d157fe5b0414616245576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f6f766572666c6f772078317931202a206669786564312064657465637465640081525060200191505060405180910390fd5b5b80915060008486029050600086146162d7578486828161626257fe5b04146162d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783279312064657465637465640000000000000000000081525060200191505060405180910390fd5b5b600084880290506000881461636557848882816162f057fe5b0414616364576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783179322064657465637465640000000000000000000081525060200191505060405180910390fd5b5b61636d6166ad565b878161637557fe5b0496506163806166ad565b858161638857fe5b049450600085880290506000881461641957858882816163a457fe5b0414616418576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783279322064657465637465640000000000000000000081525060200191505060405180910390fd5b5b616421616763565b604051806020016040528087815250905061644a816040518060200160405280878152506166ba565b9050616464816040518060200160405280868152506166ba565b905061647e816040518060200160405280858152506166ba565b9050809a50505050505050505050505b92915050565b6000838311158290616541576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156165065780820151818401526020810190506164eb565b50505050905090810190601f1680156165335780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60007601357c299a88ea76a58924d52ce4f26a85af186c2b9e74905090565b6000808311829061661f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156165e45780820151818401526020810190506165c9565b50505050905090810190601f1680156166115780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161662b57fe5b049050809150509392505050565b616641616763565b604051806020016040528069d3c21bcecceda10000008085600001518161666457fe5b04028152509050919050565b616678616763565b604051806020016040528069d3c21bcecceda10000008085600001518161669b57fe5b04028460000151038152509050919050565b600064e8d4a51000905090565b6166c2616763565b600082600001518460000151019050836000015181101561674b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f616464206f766572666c6f77206465746563746564000000000000000000000081525060200191505060405180910390fd5b60405180602001604052808281525091505092915050565b6040518060200160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106167b757803560ff19168380011785556167e5565b828001600101855582156167e5579182015b828111156167e45782358255916020019190600101906167c9565b5b5090506167f291906167f6565b5090565b61681891905b808211156168145760008160009055506001016167fc565b5090565b9056fe6572726f722063616c6c696e67206e756d62657256616c696461746f7273496e53657420707265636f6d70696c65696e666c6174696f6e466163746f72557064617465506572696f64206d757374206265203e20304f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734d7573742070726f766964652061206e6f6e2d7a65726f20696e666c6174696f6e20726174654f6e6c79207468652045786368616e676520616e642056616c696461746f727320636f6e7472616374732061726520617574686f72697a656420746f206d696e744d7573742070726f766964652061206e6f6e2d7a65726f20696e666c6174696f6e20726174652e6572726f722063616c6c696e672067657456657269666965645365616c4269746d617046726f6d48656164657220707265636f6d70696c6563616e27742063616c6c207768656e20636f6e74726163742069732066726f7a656e63616e277420637265617465206669786964697479206e756d626572206c6172676572207468616e206d61784e6577466978656428296572726f722063616c6c696e672076616c696461746f725369676e65724164647265737346726f6d43757272656e7453657420707265636f6d70696c656572726f722063616c6c696e67206e756d62657256616c696461746f7273496e43757272656e7453657420707265636f6d70696c656572726f722063616c6c696e672076616c696461746f725369676e65724164647265737346726f6d53657420707265636f6d70696c6572657365727665642061646472657373203078302063616e6e6f74206861766520616c6c6f77616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777472616e736665722076616c75652065786365656465642062616c616e6365206f662073656e6465727472616e736665722076616c75652065786365656465642073656e646572277320616c6c6f77616e636520666f7220726563697069656e746572726f722063616c6c696e67206672616374696f6e4d756c45787020707265636f6d70696c656572726f722063616c6c696e672067657445706f636853697a6520707265636f6d70696c656572726f722063616c6c696e6720676574506172656e745365616c4269746d617020707265636f6d70696c656572726f722063616c6c696e6720676574426c6f636b4e756d62657246726f6d48656164657220707265636f6d70696c657472616e7366657220617474656d7074656420746f2072657365727665642061646472657373203078306572726f722063616c6c696e67206861736848656164657220707265636f6d70696c65a165627a7a72305820a0ebf270b001d32209f9c4af9aa3bba7e912d230ee3ba33df412600994be0f210029