Address Details
contract

0xdF0130857a6fa8b00B211E6f5B89FaA71bdEb6d4

Contract Name
GasPriceMinimum
Creator
0x0cc59e–f1502d at 0x16779c–7fa7d5
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
1093
Contract name:
GasPriceMinimum




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




Verified at
2020-08-11T19:12:28.059365Z

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

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

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

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 GasPriceMinimum is Ownable, Initializable, UsingRegistry, CalledByVm {
  using FixidityLib for FixidityLib.Fraction;
  using SafeMath for uint256;

  event TargetDensitySet(uint256 targetDensity);
  event GasPriceMinimumFloorSet(uint256 gasPriceMinimumFloor);
  event AdjustmentSpeedSet(uint256 adjustmentSpeed);
  event GasPriceMinimumUpdated(uint256 gasPriceMinimum);

  uint256 public gasPriceMinimum;
  uint256 public gasPriceMinimumFloor;

  
  FixidityLib.Fraction public targetDensity;

  
  FixidityLib.Fraction public adjustmentSpeed;

  
  function initialize(
    address _registryAddress,
    uint256 _gasPriceMinimumFloor,
    uint256 _targetDensity,
    uint256 _adjustmentSpeed
  ) external initializer {
    _transferOwnership(msg.sender);
    setRegistry(_registryAddress);
    gasPriceMinimum = _gasPriceMinimumFloor;
    setGasPriceMinimumFloor(_gasPriceMinimumFloor);
    setTargetDensity(_targetDensity);
    setAdjustmentSpeed(_adjustmentSpeed);
  }

  
  function setAdjustmentSpeed(uint256 _adjustmentSpeed) public onlyOwner {
    adjustmentSpeed = FixidityLib.wrap(_adjustmentSpeed);
    require(adjustmentSpeed.lt(FixidityLib.fixed1()), "adjustment speed must be smaller than 1");
    emit AdjustmentSpeedSet(_adjustmentSpeed);
  }

  
  function setTargetDensity(uint256 _targetDensity) public onlyOwner {
    targetDensity = FixidityLib.wrap(_targetDensity);
    require(targetDensity.lt(FixidityLib.fixed1()), "target density must be smaller than 1");
    emit TargetDensitySet(_targetDensity);
  }

  
  function setGasPriceMinimumFloor(uint256 _gasPriceMinimumFloor) public onlyOwner {
    require(_gasPriceMinimumFloor > 0, "gas price minimum floor must be greater than zero");
    gasPriceMinimumFloor = _gasPriceMinimumFloor;
    emit GasPriceMinimumFloorSet(_gasPriceMinimumFloor);
  }

  
  function getGasPriceMinimum(address tokenAddress) external view returns (uint256) {
    if (
      tokenAddress == address(0) ||
      tokenAddress == registry.getAddressForOrDie(GOLD_TOKEN_REGISTRY_ID)
    ) {
      return gasPriceMinimum;
    } else {
      ISortedOracles sortedOracles = ISortedOracles(
        registry.getAddressForOrDie(SORTED_ORACLES_REGISTRY_ID)
      );
      uint256 rateNumerator;
      uint256 rateDenominator;
      (rateNumerator, rateDenominator) = sortedOracles.medianRate(tokenAddress);
      return (gasPriceMinimum.mul(rateNumerator).div(rateDenominator));
    }
  }

  
  function updateGasPriceMinimum(uint256 blockGasTotal, uint256 blockGasLimit)
    external
    onlyVm
    returns (uint256)
  {
    gasPriceMinimum = getUpdatedGasPriceMinimum(blockGasTotal, blockGasLimit);
    emit GasPriceMinimumUpdated(gasPriceMinimum);
    return gasPriceMinimum;
  }

  
  function getUpdatedGasPriceMinimum(uint256 blockGasTotal, uint256 blockGasLimit)
    public
    view
    returns (uint256)
  {
    FixidityLib.Fraction memory blockDensity = FixidityLib.newFixedFraction(
      blockGasTotal,
      blockGasLimit
    );
    bool densityGreaterThanTarget = blockDensity.gt(targetDensity);
    FixidityLib.Fraction memory densityDelta = densityGreaterThanTarget
      ? blockDensity.subtract(targetDensity)
      : targetDensity.subtract(blockDensity);
    FixidityLib.Fraction memory adjustment = densityGreaterThanTarget
      ? FixidityLib.fixed1().add(adjustmentSpeed.multiply(densityDelta))
      : FixidityLib.fixed1().subtract(adjustmentSpeed.multiply(densityDelta));

    uint256 newGasPriceMinimum = adjustment
      .multiply(FixidityLib.newFixed(gasPriceMinimum))
      .add(FixidityLib.fixed1())
      .fromFixed();

    return newGasPriceMinimum >= gasPriceMinimumFloor ? newGasPriceMinimum : gasPriceMinimumFloor;
  }
}
        

Contract ABI

[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"initialized","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setAdjustmentSpeed","inputs":[{"type":"uint256","name":"_adjustmentSpeed"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"gasPriceMinimum","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"value"}],"name":"targetDensity","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_registryAddress"},{"type":"uint256","name":"_gasPriceMinimumFloor"},{"type":"uint256","name":"_targetDensity"},{"type":"uint256","name":"_adjustmentSpeed"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"renounceOwnership","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"registry","inputs":[],"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":"nonpayable","payable":false,"outputs":[],"name":"setTargetDensity","inputs":[{"type":"uint256","name":"_targetDensity"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getGasPriceMinimum","inputs":[{"type":"address","name":"tokenAddress"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"value"}],"name":"adjustmentSpeed","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setRegistry","inputs":[{"type":"address","name":"registryAddress"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setGasPriceMinimumFloor","inputs":[{"type":"uint256","name":"_gasPriceMinimumFloor"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"updateGasPriceMinimum","inputs":[{"type":"uint256","name":"blockGasTotal"},{"type":"uint256","name":"blockGasLimit"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"gasPriceMinimumFloor","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getUpdatedGasPriceMinimum","inputs":[{"type":"uint256","name":"blockGasTotal"},{"type":"uint256","name":"blockGasLimit"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner"}],"constant":false},{"type":"event","name":"TargetDensitySet","inputs":[{"type":"uint256","name":"targetDensity","indexed":false}],"anonymous":false},{"type":"event","name":"GasPriceMinimumFloorSet","inputs":[{"type":"uint256","name":"gasPriceMinimumFloor","indexed":false}],"anonymous":false},{"type":"event","name":"AdjustmentSpeedSet","inputs":[{"type":"uint256","name":"adjustmentSpeed","indexed":false}],"anonymous":false},{"type":"event","name":"GasPriceMinimumUpdated","inputs":[{"type":"uint256","name":"gasPriceMinimum","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

0x608060405260006100146100b760201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506100bf565b600033905090565b6120b8806100ce6000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c806393ca6fc4116100a2578063b830f4a411610071578063b830f4a4146103b1578063c12398b4146103df578063ceff0bd61461042b578063ef712c5b14610449578063f2fde38b1461049557610116565b806393ca6fc4146102c9578063a54b7fc0146102f7578063a68f548e1461034f578063a91ee0dc1461036d57610116565b80634ec81af1116100e95780634ec81af1146101a7578063715018a6146102095780637b103999146102135780638da5cb5b1461025d5780638f32d59b146102a757610116565b8063158ef93e1461011b57806330f726b91461013d57806336945c2d1461016b5780634a3d5fe214610189575b600080fd5b6101236104d9565b604051808215151515815260200191505060405180910390f35b6101696004803603602081101561015357600080fd5b81019080803590602001909291905050506104ec565b005b61017361063d565b6040518082815260200191505060405180910390f35b610191610643565b6040518082815260200191505060405180910390f35b610207600480360360808110156101bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061064f565b005b610211610727565b005b61021b610860565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610265610886565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102af6108af565b604051808215151515815260200191505060405180910390f35b6102f5600480360360208110156102df57600080fd5b810190808035906020019092919050505061090d565b005b6103396004803603602081101561030d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a5e565b6040518082815260200191505060405180910390f35b610357610dbd565b6040518082815260200191505060405180910390f35b6103af6004803603602081101561038357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610dc9565b005b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610f6d565b005b610415600480360360408110156103f557600080fd5b810190808035906020019092919080359060200190929190505050611081565b6040518082815260200191505060405180910390f35b610433611178565b6040518082815260200191505060405180910390f35b61047f6004803603604081101561045f57600080fd5b81019080803590602001909291908035906020019092919050505061117e565b6040518082815260200191505060405180910390f35b6104d7600480360360208110156104ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611324565b005b600060149054906101000a900460ff1681565b6104f46108af565b610566576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61056f816113aa565b6005600082015181600001559050506105ae6105896113c8565b60056040518060200160405290816000820154815250506113ee90919063ffffffff16565b610603576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180611f936027913960400191505060405180910390fd5b7fd2e71cd7012df1df07d4908ff75ae4b2bfbb6c49d39144404661f1fd47253283816040518082815260200191505060405180910390a150565b60025481565b60048060000154905081565b600060149054906101000a900460ff16156106d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f636f6e747261637420616c726561647920696e697469616c697a65640000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff0219169083151502179055506106f633611403565b6106ff84610dc9565b8260028190555061070f83610f6d565b6107188261090d565b610721816104ec565b50505050565b61072f6108af565b6107a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108f1611547565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b6109156108af565b610987576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610990816113aa565b6004600082015181600001559050506109cf6109aa6113c8565b60046040518060200160405290816000820154815250506113ee90919063ffffffff16565b610a24576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806120686025913960400191505060405180910390fd5b7f2a109bad06121312708ed2a3e9b3556ea85ef8eadd4d10d8181f50d114eb4fab816040518082815260200191505060405180910390a150565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480610bb85750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed60405160200180807f476f6c64546f6b656e00000000000000000000000000000000000000000000008152506009019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610b4e57600080fd5b505afa158015610b62573d6000803e3d6000fd5b505050506040513d6020811015610b7857600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15610bc7576002549050610db8565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed60405160200180807f536f727465644f7261636c657300000000000000000000000000000000000000815250600d019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610c8257600080fd5b505afa158015610c96573d6000803e3d6000fd5b505050506040513d6020811015610cac57600080fd5b810190808051906020019092919050505090506000808273ffffffffffffffffffffffffffffffffffffffff1663ef90e1b0866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604080518083038186803b158015610d3e57600080fd5b505afa158015610d52573d6000803e3d6000fd5b505050506040513d6040811015610d6857600080fd5b8101908080519060200190929190805190602001909291905050508092508193505050610db281610da48460025461154f90919063ffffffff16565b6115d590919063ffffffff16565b93505050505b919050565b60058060000154905081565b610dd16108af565b610e43576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ee6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616e6e6f7420726567697374657220746865206e756c6c206164647265737381525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b60405160405180910390a250565b610f756108af565b610fe7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008111611040576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806120166031913960400191505060405180910390fd5b806003819055507f5548a13ccc1d9e4e2860461edda5ad49ba8a4fda485f67d954f9d7da8d2aff27816040518082815260200191505060405180910390a150565b60008073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611124576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4f6e6c7920564d2063616e2063616c6c0000000000000000000000000000000081525060200191505060405180910390fd5b61112e838361117e565b6002819055507f6e53b2f8b69496c2a175588ad1326dbabe2f66df4d82f817aeca52e3474807fb6002546040518082815260200191505060405180910390a1600254905092915050565b60035481565b6000611188611f7f565b611192848461161f565b905060006111bf60046040518060200160405290816000820154815250508361166190919063ffffffff16565b90506111c9611f7f565b816111fc576111f783600460405180602001604052908160008201548152505061167690919063ffffffff16565b611226565b61122560046040518060200160405290816000820154815250508461167690919063ffffffff16565b5b9050611230611f7f565b8261127c5761127761126183600560405180602001604052908160008201548152505061171d90919063ffffffff16565b6112696113c8565b61167690919063ffffffff16565b6112bf565b6112be6112a883600560405180602001604052908160008201548152505061171d90919063ffffffff16565b6112b06113c8565b611b7c90919063ffffffff16565b5b905060006113016112fc6112d16113c8565b6112ee6112df600254611c25565b8661171d90919063ffffffff16565b611b7c90919063ffffffff16565b611caf565b905060035481101561131557600354611317565b805b9550505050505092915050565b61132c6108af565b61139e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6113a781611403565b50565b6113b2611f7f565b6040518060200160405280838152509050919050565b6113d0611f7f565b604051806020016040528069d3c21bcecceda1000000815250905090565b60008160000151836000015110905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611489576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180611fba6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600033905090565b60008083141561156257600090506115cf565b600082840290508284828161157357fe5b04146115ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806120476021913960400191505060405180910390fd5b809150505b92915050565b600061161783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611cd0565b905092915050565b611627611f7f565b61162f611f7f565b61163884611c25565b9050611642611f7f565b61164b84611c25565b90506116578282611d96565b9250505092915050565b60008160000151836000015111905092915050565b61167e611f7f565b8160000151836000015110156116fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f737562737472616374696f6e20756e646572666c6f772064657465637465640081525060200191505060405180910390fd5b60405180602001604052808360000151856000015103815250905092915050565b611725611f7f565b60008360000151148061173c575060008260000151145b1561175857604051806020016040528060008152509050611b76565b69d3c21bcecceda10000008260000151141561177657829050611b76565b69d3c21bcecceda10000008360000151141561179457819050611b76565b600069d3c21bcecceda10000006117aa85611edf565b60000151816117b557fe5b04905060006117c385611f16565b600001519050600069d3c21bcecceda10000006117df86611edf565b60000151816117ea57fe5b04905060006117f886611f16565b600001519050600082850290506000851461188c578285828161181757fe5b041461188b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783179312064657465637465640000000000000000000081525060200191505060405180910390fd5b5b600069d3c21bcecceda1000000820290506000821461192e5769d3c21bcecceda10000008282816118b957fe5b041461192d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f6f766572666c6f772078317931202a206669786564312064657465637465640081525060200191505060405180910390fd5b5b80915060008486029050600086146119bf578486828161194a57fe5b04146119be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783279312064657465637465640000000000000000000081525060200191505060405180910390fd5b5b6000848802905060008814611a4d57848882816119d857fe5b0414611a4c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783179322064657465637465640000000000000000000081525060200191505060405180910390fd5b5b611a55611f53565b8781611a5d57fe5b049650611a68611f53565b8581611a7057fe5b0494506000858802905060008814611b015785888281611a8c57fe5b0414611b00576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783279322064657465637465640000000000000000000081525060200191505060405180910390fd5b5b611b09611f7f565b6040518060200160405280878152509050611b3281604051806020016040528087815250611b7c565b9050611b4c81604051806020016040528086815250611b7c565b9050611b6681604051806020016040528085815250611b7c565b9050809a50505050505050505050505b92915050565b611b84611f7f565b6000826000015184600001510190508360000151811015611c0d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f616464206f766572666c6f77206465746563746564000000000000000000000081525060200191505060405180910390fd5b60405180602001604052808281525091505092915050565b611c2d611f7f565b611c35611f60565b821115611c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180611fe06036913960400191505060405180910390fd5b604051806020016040528069d3c21bcecceda100000084028152509050919050565b600069d3c21bcecceda1000000826000015181611cc857fe5b049050919050565b60008083118290611d7c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611d41578082015181840152602081019050611d26565b50505050905090810190601f168015611d6e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581611d8857fe5b049050809150509392505050565b611d9e611f7f565b600082600001511415611e19576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f63616e277420646976696465206279203000000000000000000000000000000081525060200191505060405180910390fd5b600069d3c21bcecceda10000008460000151029050836000015169d3c21bcecceda10000008281611e4657fe5b0414611eba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f766572666c6f7720617420646976696465000000000000000000000000000081525060200191505060405180910390fd5b604051806020016040528084600001518381611ed257fe5b0481525091505092915050565b611ee7611f7f565b604051806020016040528069d3c21bcecceda100000080856000015181611f0a57fe5b04028152509050919050565b611f1e611f7f565b604051806020016040528069d3c21bcecceda100000080856000015181611f4157fe5b04028460000151038152509050919050565b600064e8d4a51000905090565b60007601357c299a88ea76a58924d52ce4f26a85af186c2b9e74905090565b604051806020016040528060008152509056fe61646a7573746d656e74207370656564206d75737420626520736d616c6c6572207468616e20314f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737363616e277420637265617465206669786964697479206e756d626572206c6172676572207468616e206d61784e657746697865642829676173207072696365206d696e696d756d20666c6f6f72206d7573742062652067726561746572207468616e207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777461726765742064656e73697479206d75737420626520736d616c6c6572207468616e2031a165627a7a72305820ef4fc6f6097cd11011dc5d9e7bbc00e95cb38c66733490cdb4909a32086e09b30029

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101165760003560e01c806393ca6fc4116100a2578063b830f4a411610071578063b830f4a4146103b1578063c12398b4146103df578063ceff0bd61461042b578063ef712c5b14610449578063f2fde38b1461049557610116565b806393ca6fc4146102c9578063a54b7fc0146102f7578063a68f548e1461034f578063a91ee0dc1461036d57610116565b80634ec81af1116100e95780634ec81af1146101a7578063715018a6146102095780637b103999146102135780638da5cb5b1461025d5780638f32d59b146102a757610116565b8063158ef93e1461011b57806330f726b91461013d57806336945c2d1461016b5780634a3d5fe214610189575b600080fd5b6101236104d9565b604051808215151515815260200191505060405180910390f35b6101696004803603602081101561015357600080fd5b81019080803590602001909291905050506104ec565b005b61017361063d565b6040518082815260200191505060405180910390f35b610191610643565b6040518082815260200191505060405180910390f35b610207600480360360808110156101bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061064f565b005b610211610727565b005b61021b610860565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610265610886565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102af6108af565b604051808215151515815260200191505060405180910390f35b6102f5600480360360208110156102df57600080fd5b810190808035906020019092919050505061090d565b005b6103396004803603602081101561030d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a5e565b6040518082815260200191505060405180910390f35b610357610dbd565b6040518082815260200191505060405180910390f35b6103af6004803603602081101561038357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610dc9565b005b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610f6d565b005b610415600480360360408110156103f557600080fd5b810190808035906020019092919080359060200190929190505050611081565b6040518082815260200191505060405180910390f35b610433611178565b6040518082815260200191505060405180910390f35b61047f6004803603604081101561045f57600080fd5b81019080803590602001909291908035906020019092919050505061117e565b6040518082815260200191505060405180910390f35b6104d7600480360360208110156104ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611324565b005b600060149054906101000a900460ff1681565b6104f46108af565b610566576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61056f816113aa565b6005600082015181600001559050506105ae6105896113c8565b60056040518060200160405290816000820154815250506113ee90919063ffffffff16565b610603576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180611f936027913960400191505060405180910390fd5b7fd2e71cd7012df1df07d4908ff75ae4b2bfbb6c49d39144404661f1fd47253283816040518082815260200191505060405180910390a150565b60025481565b60048060000154905081565b600060149054906101000a900460ff16156106d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f636f6e747261637420616c726561647920696e697469616c697a65640000000081525060200191505060405180910390fd5b6001600060146101000a81548160ff0219169083151502179055506106f633611403565b6106ff84610dc9565b8260028190555061070f83610f6d565b6107188261090d565b610721816104ec565b50505050565b61072f6108af565b6107a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108f1611547565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b6109156108af565b610987576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610990816113aa565b6004600082015181600001559050506109cf6109aa6113c8565b60046040518060200160405290816000820154815250506113ee90919063ffffffff16565b610a24576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806120686025913960400191505060405180910390fd5b7f2a109bad06121312708ed2a3e9b3556ea85ef8eadd4d10d8181f50d114eb4fab816040518082815260200191505060405180910390a150565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480610bb85750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed60405160200180807f476f6c64546f6b656e00000000000000000000000000000000000000000000008152506009019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610b4e57600080fd5b505afa158015610b62573d6000803e3d6000fd5b505050506040513d6020811015610b7857600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15610bc7576002549050610db8565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed60405160200180807f536f727465644f7261636c657300000000000000000000000000000000000000815250600d019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610c8257600080fd5b505afa158015610c96573d6000803e3d6000fd5b505050506040513d6020811015610cac57600080fd5b810190808051906020019092919050505090506000808273ffffffffffffffffffffffffffffffffffffffff1663ef90e1b0866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604080518083038186803b158015610d3e57600080fd5b505afa158015610d52573d6000803e3d6000fd5b505050506040513d6040811015610d6857600080fd5b8101908080519060200190929190805190602001909291905050508092508193505050610db281610da48460025461154f90919063ffffffff16565b6115d590919063ffffffff16565b93505050505b919050565b60058060000154905081565b610dd16108af565b610e43576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ee6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616e6e6f7420726567697374657220746865206e756c6c206164647265737381525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b60405160405180910390a250565b610f756108af565b610fe7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008111611040576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806120166031913960400191505060405180910390fd5b806003819055507f5548a13ccc1d9e4e2860461edda5ad49ba8a4fda485f67d954f9d7da8d2aff27816040518082815260200191505060405180910390a150565b60008073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611124576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4f6e6c7920564d2063616e2063616c6c0000000000000000000000000000000081525060200191505060405180910390fd5b61112e838361117e565b6002819055507f6e53b2f8b69496c2a175588ad1326dbabe2f66df4d82f817aeca52e3474807fb6002546040518082815260200191505060405180910390a1600254905092915050565b60035481565b6000611188611f7f565b611192848461161f565b905060006111bf60046040518060200160405290816000820154815250508361166190919063ffffffff16565b90506111c9611f7f565b816111fc576111f783600460405180602001604052908160008201548152505061167690919063ffffffff16565b611226565b61122560046040518060200160405290816000820154815250508461167690919063ffffffff16565b5b9050611230611f7f565b8261127c5761127761126183600560405180602001604052908160008201548152505061171d90919063ffffffff16565b6112696113c8565b61167690919063ffffffff16565b6112bf565b6112be6112a883600560405180602001604052908160008201548152505061171d90919063ffffffff16565b6112b06113c8565b611b7c90919063ffffffff16565b5b905060006113016112fc6112d16113c8565b6112ee6112df600254611c25565b8661171d90919063ffffffff16565b611b7c90919063ffffffff16565b611caf565b905060035481101561131557600354611317565b805b9550505050505092915050565b61132c6108af565b61139e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6113a781611403565b50565b6113b2611f7f565b6040518060200160405280838152509050919050565b6113d0611f7f565b604051806020016040528069d3c21bcecceda1000000815250905090565b60008160000151836000015110905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611489576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180611fba6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600033905090565b60008083141561156257600090506115cf565b600082840290508284828161157357fe5b04146115ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806120476021913960400191505060405180910390fd5b809150505b92915050565b600061161783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611cd0565b905092915050565b611627611f7f565b61162f611f7f565b61163884611c25565b9050611642611f7f565b61164b84611c25565b90506116578282611d96565b9250505092915050565b60008160000151836000015111905092915050565b61167e611f7f565b8160000151836000015110156116fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f737562737472616374696f6e20756e646572666c6f772064657465637465640081525060200191505060405180910390fd5b60405180602001604052808360000151856000015103815250905092915050565b611725611f7f565b60008360000151148061173c575060008260000151145b1561175857604051806020016040528060008152509050611b76565b69d3c21bcecceda10000008260000151141561177657829050611b76565b69d3c21bcecceda10000008360000151141561179457819050611b76565b600069d3c21bcecceda10000006117aa85611edf565b60000151816117b557fe5b04905060006117c385611f16565b600001519050600069d3c21bcecceda10000006117df86611edf565b60000151816117ea57fe5b04905060006117f886611f16565b600001519050600082850290506000851461188c578285828161181757fe5b041461188b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783179312064657465637465640000000000000000000081525060200191505060405180910390fd5b5b600069d3c21bcecceda1000000820290506000821461192e5769d3c21bcecceda10000008282816118b957fe5b041461192d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f6f766572666c6f772078317931202a206669786564312064657465637465640081525060200191505060405180910390fd5b5b80915060008486029050600086146119bf578486828161194a57fe5b04146119be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783279312064657465637465640000000000000000000081525060200191505060405180910390fd5b5b6000848802905060008814611a4d57848882816119d857fe5b0414611a4c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783179322064657465637465640000000000000000000081525060200191505060405180910390fd5b5b611a55611f53565b8781611a5d57fe5b049650611a68611f53565b8581611a7057fe5b0494506000858802905060008814611b015785888281611a8c57fe5b0414611b00576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f766572666c6f7720783279322064657465637465640000000000000000000081525060200191505060405180910390fd5b5b611b09611f7f565b6040518060200160405280878152509050611b3281604051806020016040528087815250611b7c565b9050611b4c81604051806020016040528086815250611b7c565b9050611b6681604051806020016040528085815250611b7c565b9050809a50505050505050505050505b92915050565b611b84611f7f565b6000826000015184600001510190508360000151811015611c0d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f616464206f766572666c6f77206465746563746564000000000000000000000081525060200191505060405180910390fd5b60405180602001604052808281525091505092915050565b611c2d611f7f565b611c35611f60565b821115611c8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180611fe06036913960400191505060405180910390fd5b604051806020016040528069d3c21bcecceda100000084028152509050919050565b600069d3c21bcecceda1000000826000015181611cc857fe5b049050919050565b60008083118290611d7c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611d41578082015181840152602081019050611d26565b50505050905090810190601f168015611d6e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581611d8857fe5b049050809150509392505050565b611d9e611f7f565b600082600001511415611e19576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f63616e277420646976696465206279203000000000000000000000000000000081525060200191505060405180910390fd5b600069d3c21bcecceda10000008460000151029050836000015169d3c21bcecceda10000008281611e4657fe5b0414611eba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f766572666c6f7720617420646976696465000000000000000000000000000081525060200191505060405180910390fd5b604051806020016040528084600001518381611ed257fe5b0481525091505092915050565b611ee7611f7f565b604051806020016040528069d3c21bcecceda100000080856000015181611f0a57fe5b04028152509050919050565b611f1e611f7f565b604051806020016040528069d3c21bcecceda100000080856000015181611f4157fe5b04028460000151038152509050919050565b600064e8d4a51000905090565b60007601357c299a88ea76a58924d52ce4f26a85af186c2b9e74905090565b604051806020016040528060008152509056fe61646a7573746d656e74207370656564206d75737420626520736d616c6c6572207468616e20314f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737363616e277420637265617465206669786964697479206e756d626572206c6172676572207468616e206d61784e657746697865642829676173207072696365206d696e696d756d20666c6f6f72206d7573742062652067726561746572207468616e207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777461726765742064656e73697479206d75737420626520736d616c6c6572207468616e2031a165627a7a72305820ef4fc6f6097cd11011dc5d9e7bbc00e95cb38c66733490cdb4909a32086e09b30029