ETH Price: $3,344.02 (-0.68%)
Gas: 5 Gwei

Contract

0x0564AeCEa06A74CaA67a4C4c37087851eEf56C29
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
123780932021-05-06 2:38:301181 days ago1620268710  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PRawPerSecondCalculator

Compiler Version
v0.6.7+commit.b8d736ae

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-05-06
*/

pragma solidity 0.6.7;

contract GebMath {
    uint256 public constant RAY = 10 ** 27;
    uint256 public constant WAD = 10 ** 18;

    function ray(uint x) public pure returns (uint z) {
        z = multiply(x, 10 ** 9);
    }
    function rad(uint x) public pure returns (uint z) {
        z = multiply(x, 10 ** 27);
    }
    function minimum(uint x, uint y) public pure returns (uint z) {
        z = (x <= y) ? x : y;
    }
    function addition(uint x, uint y) public pure returns (uint z) {
        z = x + y;
        require(z >= x, "uint-uint-add-overflow");
    }
    function subtract(uint x, uint y) public pure returns (uint z) {
        z = x - y;
        require(z <= x, "uint-uint-sub-underflow");
    }
    function multiply(uint x, uint y) public pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x, "uint-uint-mul-overflow");
    }
    function rmultiply(uint x, uint y) public pure returns (uint z) {
        z = multiply(x, y) / RAY;
    }
    function rdivide(uint x, uint y) public pure returns (uint z) {
        z = multiply(x, RAY) / y;
    }
    function wdivide(uint x, uint y) public pure returns (uint z) {
        z = multiply(x, WAD) / y;
    }
    function wmultiply(uint x, uint y) public pure returns (uint z) {
        z = multiply(x, y) / WAD;
    }
    function rpower(uint x, uint n, uint base) public pure returns (uint z) {
        assembly {
            switch x case 0 {switch n case 0 {z := base} default {z := 0}}
            default {
                switch mod(n, 2) case 0 { z := base } default { z := x }
                let half := div(base, 2)  // for rounding.
                for { n := div(n, 2) } n { n := div(n,2) } {
                    let xx := mul(x, x)
                    if iszero(eq(div(xx, x), x)) { revert(0,0) }
                    let xxRound := add(xx, half)
                    if lt(xxRound, xx) { revert(0,0) }
                    x := div(xxRound, base)
                    if mod(n,2) {
                        let zx := mul(z, x)
                        if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
                        let zxRound := add(zx, half)
                        if lt(zxRound, zx) { revert(0,0) }
                        z := div(zxRound, base)
                    }
                }
            }
        }
    }
}

abstract contract OracleLike {
    function getResultWithValidity() virtual external view returns (uint256, bool);
}

abstract contract PIDCalculator {
    function computeRate(uint256, uint256, uint256) virtual external returns (uint256);
    function rt(uint256, uint256, uint256) virtual external view returns (uint256);
    function pscl() virtual external view returns (uint256);
    function tlv() virtual external view returns (uint256);
}

contract PIRateSetter is GebMath {
    // --- Auth ---
    mapping (address => uint) public authorizedAccounts;
    /**
     * @notice Add auth to an account
     * @param account Account to add auth to
     */
    function addAuthorization(address account) external isAuthorized {
        authorizedAccounts[account] = 1;
        emit AddAuthorization(account);
    }
    /**
     * @notice Remove auth from an account
     * @param account Account to remove auth from
     */
    function removeAuthorization(address account) external isAuthorized {
        authorizedAccounts[account] = 0;
        emit RemoveAuthorization(account);
    }
    /**
    * @notice Checks whether msg.sender can call an authed function
    **/
    modifier isAuthorized {
        require(authorizedAccounts[msg.sender] == 1, "PIRateSetter/account-not-authorized");
        _;
    }

    // --- Variables ---
    // When the price feed was last updated
    uint256 public lastUpdateTime;                  // [timestamp]
    // Enforced gap between calls
    uint256 public updateRateDelay;                 // [seconds]
    // Whether the leak is set to zero by default
    uint256 public defaultLeak;                     // [0 or 1]

    // --- System Dependencies ---
    // OSM or medianizer for the system coin
    OracleLike                public orcl;
    // OracleRelayer where the redemption price is stored
    OracleRelayerLike         public oracleRelayer;
    // The contract that will pass the new redemption rate to the oracle relayer
    SetterRelayer             public setterRelayer;
    // Calculator for the redemption rate
    PIDCalculator             public pidCalculator;

    // --- Events ---
    event AddAuthorization(address account);
    event RemoveAuthorization(address account);
    event ModifyParameters(
      bytes32 parameter,
      address addr
    );
    event ModifyParameters(
      bytes32 parameter,
      uint256 val
    );
    event UpdateRedemptionRate(
        uint marketPrice,
        uint redemptionPrice,
        uint redemptionRate
    );
    event FailUpdateRedemptionRate(
        uint marketPrice,
        uint redemptionPrice,
        uint redemptionRate,
        bytes reason
    );

    constructor(
      address oracleRelayer_,
      address setterRelayer_,
      address orcl_,
      address pidCalculator_,
      uint256 updateRateDelay_
    ) public {
        require(oracleRelayer_ != address(0), "PIRateSetter/null-oracle-relayer");
        require(setterRelayer_ != address(0), "PIRateSetter/null-setter-relayer");
        require(orcl_ != address(0), "PIRateSetter/null-orcl");
        require(pidCalculator_ != address(0), "PIRateSetter/null-calculator");

        authorizedAccounts[msg.sender] = 1;
        defaultLeak                    = 1;

        oracleRelayer    = OracleRelayerLike(oracleRelayer_);
        setterRelayer    = SetterRelayer(setterRelayer_);
        orcl             = OracleLike(orcl_);
        pidCalculator    = PIDCalculator(pidCalculator_);

        updateRateDelay  = updateRateDelay_;

        emit AddAuthorization(msg.sender);
        emit ModifyParameters("orcl", orcl_);
        emit ModifyParameters("oracleRelayer", oracleRelayer_);
        emit ModifyParameters("setterRelayer", setterRelayer_);
        emit ModifyParameters("pidCalculator", pidCalculator_);
        emit ModifyParameters("updateRateDelay", updateRateDelay_);
    }

    // --- Boolean Logic ---
    function either(bool x, bool y) internal pure returns (bool z) {
        assembly{ z := or(x, y)}
    }

    // --- Management ---
    /*
    * @notify Modify the address of a contract that the setter is connected to
    * @param parameter Contract name
    * @param addr The new contract address
    */
    function modifyParameters(bytes32 parameter, address addr) external isAuthorized {
        require(addr != address(0), "PIRateSetter/null-addr");
        if (parameter == "orcl") orcl = OracleLike(addr);
        else if (parameter == "oracleRelayer") oracleRelayer = OracleRelayerLike(addr);
        else if (parameter == "setterRelayer") setterRelayer = SetterRelayer(addr);
        else if (parameter == "pidCalculator") {
          pidCalculator = PIDCalculator(addr);
        }
        else revert("PIRateSetter/modify-unrecognized-param");
        emit ModifyParameters(
          parameter,
          addr
        );
    }
    /*
    * @notify Modify a uint256 parameter
    * @param parameter The parameter name
    * @param val The new parameter value
    */
    function modifyParameters(bytes32 parameter, uint256 val) external isAuthorized {
        if (parameter == "updateRateDelay") {
          require(val > 0, "PIRateSetter/null-update-delay");
          updateRateDelay = val;
        }
        else if (parameter == "defaultLeak") {
          require(val <= 1, "PIRateSetter/invalid-default-leak");
          defaultLeak = val;
        }
        else revert("PIRateSetter/modify-unrecognized-param");
        emit ModifyParameters(
          parameter,
          val
        );
    }

    // --- Feedback Mechanism ---
    /**
    * @notice Compute and set a new redemption rate
    * @param feeReceiver The proposed address that should receive the reward for calling this function
    *        (unless it's address(0) in which case msg.sender will get it)
    **/
    function updateRate(address feeReceiver) external {
        // The fee receiver must not be null
        require(feeReceiver != address(0), "PIRateSetter/null-fee-receiver");
        // Check delay between calls
        require(either(subtract(now, lastUpdateTime) >= updateRateDelay, lastUpdateTime == 0), "PIRateSetter/wait-more");
        // Get price feed updates
        (uint256 marketPrice, bool hasValidValue) = orcl.getResultWithValidity();
        // If the oracle has a value
        require(hasValidValue, "PIRateSetter/invalid-oracle-value");
        // If the price is non-zero
        require(marketPrice > 0, "PIRateSetter/null-price");
        // Get the latest redemption price
        uint redemptionPrice = oracleRelayer.redemptionPrice();
        // Calculate the rate
        uint256 iapcr      = (defaultLeak == 1) ? RAY : rpower(pidCalculator.pscl(), pidCalculator.tlv(), RAY);
        uint256 calculated = pidCalculator.computeRate(
            marketPrice,
            redemptionPrice,
            iapcr
        );
        // Store the timestamp of the update
        lastUpdateTime = now;
        // Update the rate using the setter relayer
        try setterRelayer.relayRate(calculated, feeReceiver) {
          // Emit success event
          emit UpdateRedemptionRate(
            ray(marketPrice),
            redemptionPrice,
            calculated
          );
        }
        catch(bytes memory revertReason) {
          emit FailUpdateRedemptionRate(
            ray(marketPrice),
            redemptionPrice,
            calculated,
            revertReason
          );
        }
    }

    // --- Getters ---
    /**
    * @notice Get the market price from the system coin oracle
    **/
    function getMarketPrice() external view returns (uint256) {
        (uint256 marketPrice, ) = orcl.getResultWithValidity();
        return marketPrice;
    }
    /**
    * @notice Get the redemption and the market prices for the system coin
    **/
    function getRedemptionAndMarketPrices() external returns (uint256 marketPrice, uint256 redemptionPrice) {
        (marketPrice, ) = orcl.getResultWithValidity();
        redemptionPrice = oracleRelayer.redemptionPrice();
    }
}


abstract contract StabilityFeeTreasuryLike {
    function getAllowance(address) virtual external view returns (uint, uint);
    function systemCoin() virtual external view returns (address);
    function pullFunds(address, address, uint) virtual external;
    function setTotalAllowance(address, uint256) external virtual;
    function setPerBlockAllowance(address, uint256) external virtual;
}

contract IncreasingTreasuryReimbursement is GebMath {
    // --- Auth ---
    mapping (address => uint) public authorizedAccounts;
    /**
     * @notice Add auth to an account
     * @param account Account to add auth to
     */
    function addAuthorization(address account) virtual external isAuthorized {
        authorizedAccounts[account] = 1;
        emit AddAuthorization(account);
    }
    /**
     * @notice Remove auth from an account
     * @param account Account to remove auth from
     */
    function removeAuthorization(address account) virtual external isAuthorized {
        authorizedAccounts[account] = 0;
        emit RemoveAuthorization(account);
    }
    /**
    * @notice Checks whether msg.sender can call an authed function
    **/
    modifier isAuthorized {
        require(authorizedAccounts[msg.sender] == 1, "IncreasingTreasuryReimbursement/account-not-authorized");
        _;
    }

    // --- Variables ---
    // Starting reward for the fee receiver/keeper
    uint256 public baseUpdateCallerReward;          // [wad]
    // Max possible reward for the fee receiver/keeper
    uint256 public maxUpdateCallerReward;           // [wad]
    // Max delay taken into consideration when calculating the adjusted reward
    uint256 public maxRewardIncreaseDelay;          // [seconds]
    // Rate applied to baseUpdateCallerReward every extra second passed beyond a certain point (e.g next time when a specific function needs to be called)
    uint256 public perSecondCallerRewardIncrease;   // [ray]

    // SF treasury
    StabilityFeeTreasuryLike  public treasury;

    // --- Events ---
    event AddAuthorization(address account);
    event RemoveAuthorization(address account);
    event ModifyParameters(
      bytes32 parameter,
      address addr
    );
    event ModifyParameters(
      bytes32 parameter,
      uint256 val
    );
    event FailRewardCaller(bytes revertReason, address feeReceiver, uint256 amount);

    constructor(
      address treasury_,
      uint256 baseUpdateCallerReward_,
      uint256 maxUpdateCallerReward_,
      uint256 perSecondCallerRewardIncrease_
    ) public {
        if (address(treasury_) != address(0)) {
          require(StabilityFeeTreasuryLike(treasury_).systemCoin() != address(0), "IncreasingTreasuryReimbursement/treasury-coin-not-set");
        }
        require(maxUpdateCallerReward_ >= baseUpdateCallerReward_, "IncreasingTreasuryReimbursement/invalid-max-caller-reward");
        require(perSecondCallerRewardIncrease_ >= RAY, "IncreasingTreasuryReimbursement/invalid-per-second-reward-increase");
        authorizedAccounts[msg.sender] = 1;

        treasury                        = StabilityFeeTreasuryLike(treasury_);
        baseUpdateCallerReward          = baseUpdateCallerReward_;
        maxUpdateCallerReward           = maxUpdateCallerReward_;
        perSecondCallerRewardIncrease   = perSecondCallerRewardIncrease_;
        maxRewardIncreaseDelay          = uint(-1);

        emit AddAuthorization(msg.sender);
        emit ModifyParameters("treasury", treasury_);
        emit ModifyParameters("baseUpdateCallerReward", baseUpdateCallerReward);
        emit ModifyParameters("maxUpdateCallerReward", maxUpdateCallerReward);
        emit ModifyParameters("perSecondCallerRewardIncrease", perSecondCallerRewardIncrease);
    }

    // --- Boolean Logic ---
    function either(bool x, bool y) internal pure returns (bool z) {
        assembly{ z := or(x, y)}
    }

    // --- Treasury ---
    /**
    * @notice This returns the stability fee treasury allowance for this contract by taking the minimum between the per block and the total allowances
    **/
    function treasuryAllowance() public view returns (uint256) {
        (uint total, uint perBlock) = treasury.getAllowance(address(this));
        return minimum(total, perBlock);
    }
    /*
    * @notice Get the SF reward that can be sent to a function caller right now
    * @param timeOfLastUpdate The last time when the function that the treasury pays for has been updated
    * @param defaultDelayBetweenCalls Enforced delay between calls to the function for which the treasury reimburses callers
    */
    function getCallerReward(uint256 timeOfLastUpdate, uint256 defaultDelayBetweenCalls) public view returns (uint256) {
        // If the rewards are null or if the time of the last update is in the future or present, return 0
        bool nullRewards = (baseUpdateCallerReward == 0 && maxUpdateCallerReward == 0);
        if (either(timeOfLastUpdate >= now, nullRewards)) return 0;

        // If the time elapsed is smaller than defaultDelayBetweenCalls or if the base reward is zero, return 0
        uint256 timeElapsed = (timeOfLastUpdate == 0) ? defaultDelayBetweenCalls : subtract(now, timeOfLastUpdate);
        if (either(timeElapsed < defaultDelayBetweenCalls, baseUpdateCallerReward == 0)) {
            return 0;
        }

        // If too much time elapsed, return the max reward
        uint256 adjustedTime      = subtract(timeElapsed, defaultDelayBetweenCalls);
        uint256 maxPossibleReward = minimum(maxUpdateCallerReward, treasuryAllowance() / RAY);
        if (adjustedTime > maxRewardIncreaseDelay) {
            return maxPossibleReward;
        }

        // Calculate the reward
        uint256 calculatedReward = baseUpdateCallerReward;
        if (adjustedTime > 0) {
            calculatedReward = rmultiply(rpower(perSecondCallerRewardIncrease, adjustedTime, RAY), calculatedReward);
        }

        // If the reward is higher than max, set it to max
        if (calculatedReward > maxPossibleReward) {
            calculatedReward = maxPossibleReward;
        }
        return calculatedReward;
    }
    /**
    * @notice Send a stability fee reward to an address
    * @param proposedFeeReceiver The SF receiver
    * @param reward The system coin amount to send
    **/
    function rewardCaller(address proposedFeeReceiver, uint256 reward) internal {
        // If the receiver is the treasury itself or if the treasury is null or if the reward is zero, return
        if (address(treasury) == proposedFeeReceiver) return;
        if (either(address(treasury) == address(0), reward == 0)) return;

        // Determine the actual receiver and send funds
        address finalFeeReceiver = (proposedFeeReceiver == address(0)) ? msg.sender : proposedFeeReceiver;
        try treasury.pullFunds(finalFeeReceiver, treasury.systemCoin(), reward) {}
        catch(bytes memory revertReason) {
            emit FailRewardCaller(revertReason, finalFeeReceiver, reward);
        }
    }
}

abstract contract OracleRelayerLike {
    function redemptionPrice() virtual external returns (uint256);
    function modifyParameters(bytes32,uint256) virtual external;
}

contract SetterRelayer is IncreasingTreasuryReimbursement {
    // --- Events ---
    event RelayRate(address setter, uint256 redemptionRate);

    // --- Variables ---
    // When the rate has last been relayed
    uint256           public lastUpdateTime;                      // [timestamp]
    // Enforced gap between relays
    uint256           public relayDelay;                          // [seconds]
    // The address that's allowed to pass new redemption rates
    address           public setter;
    // The oracle relayer contract
    OracleRelayerLike public oracleRelayer;

    constructor(
      address oracleRelayer_,
      address treasury_,
      uint256 baseUpdateCallerReward_,
      uint256 maxUpdateCallerReward_,
      uint256 perSecondCallerRewardIncrease_,
      uint256 relayDelay_
    ) public IncreasingTreasuryReimbursement(treasury_, baseUpdateCallerReward_, maxUpdateCallerReward_, perSecondCallerRewardIncrease_) {
        relayDelay    = relayDelay_;
        oracleRelayer = OracleRelayerLike(oracleRelayer_);

        emit ModifyParameters("relayDelay", relayDelay_);
    }

    // --- Administration ---
    /*
    * @notice Change the addresses of contracts that this relayer is connected to
    * @param parameter The contract whose address is changed
    * @param addr The new contract address
    */
    function modifyParameters(bytes32 parameter, address addr) external isAuthorized {
        require(addr != address(0), "SetterRelayer/null-addr");
        if (parameter == "setter") {
          setter = addr;
        }
        else if (parameter == "treasury") {
          require(StabilityFeeTreasuryLike(addr).systemCoin() != address(0), "SetterRelayer/treasury-coin-not-set");
          treasury = StabilityFeeTreasuryLike(addr);
        }
        else revert("SetterRelayer/modify-unrecognized-param");
        emit ModifyParameters(
          parameter,
          addr
        );
    }
    /*
    * @notify Modify a uint256 parameter
    * @param parameter The parameter name
    * @param val The new parameter value
    */
    function modifyParameters(bytes32 parameter, uint256 val) external isAuthorized {
        if (parameter == "baseUpdateCallerReward") {
          require(val <= maxUpdateCallerReward, "SetterRelayer/invalid-base-caller-reward");
          baseUpdateCallerReward = val;
        }
        else if (parameter == "maxUpdateCallerReward") {
          require(val >= baseUpdateCallerReward, "SetterRelayer/invalid-max-caller-reward");
          maxUpdateCallerReward = val;
        }
        else if (parameter == "perSecondCallerRewardIncrease") {
          require(val >= RAY, "SetterRelayer/invalid-caller-reward-increase");
          perSecondCallerRewardIncrease = val;
        }
        else if (parameter == "maxRewardIncreaseDelay") {
          require(val > 0, "SetterRelayer/invalid-max-increase-delay");
          maxRewardIncreaseDelay = val;
        }
        else if (parameter == "relayDelay") {
          relayDelay = val;
        }
        else revert("SetterRelayer/modify-unrecognized-param");
        emit ModifyParameters(
          parameter,
          val
        );
    }

    // --- Core Logic ---
    /*
    * @notice Relay a new redemption rate to the OracleRelayer
    * @param redemptionRate The new redemption rate to relay
    */
    function relayRate(uint256 redemptionRate, address feeReceiver) external {
        // Perform checks
        require(setter == msg.sender, "SetterRelayer/invalid-caller");
        require(feeReceiver != address(0), "SetterRelayer/null-fee-receiver");
        require(feeReceiver != setter, "SetterRelayer/setter-cannot-receive-fees");
        // Check delay between calls
        require(either(subtract(now, lastUpdateTime) >= relayDelay, lastUpdateTime == 0), "SetterRelayer/wait-more");
        // Get the caller's reward
        uint256 callerReward = getCallerReward(lastUpdateTime, relayDelay);
        // Store the timestamp of the update
        lastUpdateTime = now;
        // Update the redemption price and then set the rate
        oracleRelayer.redemptionPrice();
        oracleRelayer.modifyParameters("redemptionRate", redemptionRate);
        // Emit an event
        emit RelayRate(setter, redemptionRate);
        // Pay the caller for relaying the rate
        rewardCaller(feeReceiver, callerReward);
    }
}


/**
 * @title SignedSafeMath
 * @dev Signed math operations with safety checks that revert on error.
 */
contract SignedSafeMath {
    int256 constant private _INT256_MIN = -2**255;

    /**
     * @dev Returns the multiplication of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function multiply(int256 a, int256 b) internal pure returns (int256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");

        int256 c = a * b;
        require(c / a == b, "SignedSafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two signed integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function divide(int256 a, int256 b) internal pure returns (int256) {
        require(b != 0, "SignedSafeMath: division by zero");
        require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");

        int256 c = a / b;

        return c;
    }

    /**
     * @dev Returns the subtraction of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function subtract(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");

        return c;
    }

    /**
     * @dev Returns the addition of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function addition(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");

        return c;
    }
}


/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
contract SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function addition(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function subtract(uint256 a, uint256 b) internal pure returns (uint256) {
        return subtract(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function subtract(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function multiply(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

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

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function divide(uint256 a, uint256 b) internal pure returns (uint256) {
        return divide(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function divide(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }
}

/**
Reflexer PI Controller License 1.0
Definitions
Primary License: This license agreement
Secondary License: GNU General Public License v2.0 or later
Effective Date of Secondary License: May 5, 2023
Licensed Software:
Software License Grant: Subject to and dependent upon your adherence to the terms and conditions of this Primary License, and subject to explicit approval by Reflexer, Inc., Reflexer, Inc., hereby grants you the right to copy, modify or otherwise create derivative works, redistribute, and use the Licensed Software solely for internal testing and development, and solely until the Effective Date of the Secondary License.  You may not, and you agree you will not, use the Licensed Software outside the scope of the limited license grant in this Primary License.
You agree you will not (i) use the Licensed Software for any commercial purpose, and (ii) deploy the Licensed Software to a blockchain system other than as a noncommercial deployment to a testnet in which tokens or transactions could not reasonably be expected to have or develop commercial value.You agree to be bound by the terms and conditions of this Primary License until the Effective Date of the Secondary License, at which time the Primary License will expire and be replaced by the Secondary License. You Agree that as of the Effective Date of the Secondary License, you will be bound by the terms and conditions of the Secondary License.
You understand and agree that any violation of the terms and conditions of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Software.
You understand and agree that any use of the Licensed Software outside the boundaries of the limited licensed granted in this Primary License renders the license granted in this Primary License null and void as of the date you first used the Licensed Software in any way (void ab initio).You understand and agree that you may purchase a commercial license to use a version of the Licensed Software under the terms and conditions set by Reflexer, Inc.  You understand and agree that you will display an unmodified copy of this Primary License with each Licensed Software, and any derivative work of the Licensed Software.
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED SOFTWARE IS PROVIDED ON AN "AS IS" BASIS. REFLEXER, INC HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
You understand and agree that all copies of the Licensed Software, and all derivative works thereof, are each subject to the terms and conditions of this License. Notwithstanding the foregoing, You hereby grant to Reflexer, Inc. a fully paid-up, worldwide, fully sublicensable license to use,for any lawful purpose, any such derivative work made by or for You, now or in the future. You agree that you will, at the request of Reflexer, Inc., provide Reflexer, Inc. with the complete source code to such derivative work.
Copyright © 2021 Reflexer Inc. All Rights Reserved
**/
contract PRawPerSecondCalculator is SafeMath, SignedSafeMath {
    // --- Authorities ---
    mapping (address => uint) public authorities;
    function addAuthority(address account) external isAuthority { authorities[account] = 1; }
    function removeAuthority(address account) external isAuthority { authorities[account] = 0; }
    modifier isAuthority {
        require(authorities[msg.sender] == 1, "PRawPerSecondCalculator/not-an-authority");
        _;
    }

    // --- Readers ---
    mapping (address => uint) public readers;
    function addReader(address account) external isAuthority { readers[account] = 1; }
    function removeReader(address account) external isAuthority { readers[account] = 0; }
    modifier isReader {
        require(either(allReaderToggle == 1, readers[msg.sender] == 1), "PRawPerSecondCalculator/not-a-reader");
        _;
    }

    // -- Static & Default Variables ---
    // The Kp used in this calculator
    int256  public Kp;                               // [EIGHTEEN_DECIMAL_NUMBER]

    // Flag that can allow anyone to read variables
    uint256 public   allReaderToggle;
    // The minimum percentage deviation from the redemption price that allows the contract to calculate a non null redemption rate
    uint256 internal noiseBarrier;                   // [EIGHTEEN_DECIMAL_NUMBER]
    // The default redemption rate to calculate in case P + I is smaller than noiseBarrier
    uint256 internal defaultRedemptionRate;          // [TWENTY_SEVEN_DECIMAL_NUMBER]
    // The maximum value allowed for the redemption rate
    uint256 internal feedbackOutputUpperBound;       // [TWENTY_SEVEN_DECIMAL_NUMBER]
    // The minimum value allowed for the redemption rate
    int256  internal feedbackOutputLowerBound;       // [TWENTY_SEVEN_DECIMAL_NUMBER]
    // The minimum delay between two computeRate calls
    uint256 internal periodSize;                     // [seconds]

    // --- Fluctuating/Dynamic Variables ---
    // Timestamp of the last update
    uint256 internal lastUpdateTime;                       // [timestamp]
    // Flag indicating that the rate computed is per second
    uint256 constant internal defaultGlobalTimeline = 1;

    // The address allowed to call calculateRate
    address public seedProposer;

    uint256 internal constant NEGATIVE_RATE_LIMIT         = TWENTY_SEVEN_DECIMAL_NUMBER - 1;
    uint256 internal constant TWENTY_SEVEN_DECIMAL_NUMBER = 10 ** 27;
    uint256 internal constant EIGHTEEN_DECIMAL_NUMBER     = 10 ** 18;

    constructor(
        int256 Kp_,
        uint256 periodSize_,
        uint256 noiseBarrier_,
        uint256 feedbackOutputUpperBound_,
        int256  feedbackOutputLowerBound_
    ) public {
        defaultRedemptionRate      = TWENTY_SEVEN_DECIMAL_NUMBER;

        require(both(feedbackOutputUpperBound_ < subtract(subtract(uint(-1), defaultRedemptionRate), 1), feedbackOutputUpperBound_ > 0), "PRawPerSecondCalculator/invalid-foub");
        require(both(feedbackOutputLowerBound_ < 0, feedbackOutputLowerBound_ >= -int(NEGATIVE_RATE_LIMIT)), "PRawPerSecondCalculator/invalid-folb");
        require(periodSize_ > 0, "PRawPerSecondCalculator/invalid-ips");
        require(both(noiseBarrier_ > 0, noiseBarrier_ <= EIGHTEEN_DECIMAL_NUMBER), "PRawPerSecondCalculator/invalid-nb");
        require(both(Kp_ >= -int(EIGHTEEN_DECIMAL_NUMBER), Kp_ <= int(EIGHTEEN_DECIMAL_NUMBER)), "PRawPerSecondCalculator/invalid-sg");

        authorities[msg.sender]   = 1;
        readers[msg.sender]       = 1;

        feedbackOutputUpperBound  = feedbackOutputUpperBound_;
        feedbackOutputLowerBound  = feedbackOutputLowerBound_;
        periodSize                = periodSize_;
        Kp                        = Kp_;
        noiseBarrier              = noiseBarrier_;
    }

    // --- Boolean Logic ---
    function both(bool x, bool y) internal pure returns (bool z) {
        assembly{ z := and(x, y)}
    }
    function either(bool x, bool y) internal pure returns (bool z) {
        assembly{ z := or(x, y)}
    }

    // --- Administration ---
    /*
    * @notify Modify an address parameter
    * @param parameter The name of the address parameter to change
    * @param addr The new address for the parameter
    */
    function modifyParameters(bytes32 parameter, address addr) external isAuthority {
        if (parameter == "seedProposer") {
          readers[seedProposer] = 0;
          seedProposer = addr;
          readers[seedProposer] = 1;
        }
        else revert("PRawPerSecondCalculator/modify-unrecognized-param");
    }
    /*
    * @notify Modify an uint256 parameter
    * @param parameter The name of the parameter to change
    * @param val The new value for the parameter
    */
    function modifyParameters(bytes32 parameter, uint256 val) external isAuthority {
        if (parameter == "nb") {
          require(both(val > 0, val <= EIGHTEEN_DECIMAL_NUMBER), "PRawPerSecondCalculator/invalid-nb");
          noiseBarrier = val;
        }
        else if (parameter == "ps") {
          require(val > 0, "PRawPerSecondCalculator/null-ps");
          periodSize = val;
        }
        else if (parameter == "foub") {
          require(both(val < subtract(subtract(uint(-1), defaultRedemptionRate), 1), val > 0), "PRawPerSecondCalculator/invalid-foub");
          feedbackOutputUpperBound = val;
        }
        else if (parameter == "allReaderToggle") {
          allReaderToggle = val;
        }
        else revert("PRawPerSecondCalculator/modify-unrecognized-param");
    }
    /*
    * @notify Modify an int256 parameter
    * @param parameter The name of the parameter to change
    * @param val The new value for the parameter
    */
    function modifyParameters(bytes32 parameter, int256 val) external isAuthority {
        if (parameter == "folb") {
          require(both(val < 0, val >= -int(NEGATIVE_RATE_LIMIT)), "PRawPerSecondCalculator/invalid-folb");
          feedbackOutputLowerBound = val;
        }
        else if (parameter == "sg") {
          require(both(val >= -int(EIGHTEEN_DECIMAL_NUMBER), val <= int(EIGHTEEN_DECIMAL_NUMBER)), "PRawPerSecondCalculator/invalid-sg");
          Kp = val;
        }
        else revert("PRawPerSecondCalculator/modify-unrecognized-param");
    }

    // --- Controller Specific Math ---
    function absolute(int x) internal pure returns (uint z) {
        z = (x < 0) ? uint(-x) : uint(x);
    }

    // --- P Controller Utils ---
    /*
    * @notice Return a redemption rate bounded by feedbackOutputLowerBound and feedbackOutputUpperBound as well as the
              timeline over which that rate will take effect
    * @param pOutput The raw redemption rate computed from the proportional and integral terms
    */
    function getBoundedRedemptionRate(int pOutput) public isReader view returns (uint256, uint256) {
        int  boundedPOutput = pOutput;
        uint newRedemptionRate;

        if (pOutput < feedbackOutputLowerBound) {
          boundedPOutput = feedbackOutputLowerBound;
        } else if (pOutput > int(feedbackOutputUpperBound)) {
          boundedPOutput = int(feedbackOutputUpperBound);
        }

        // newRedemptionRate cannot be lower than 10^0 (1) because of the way rpower is designed
        bool negativeOutputExceedsHundred = (boundedPOutput < 0 && -boundedPOutput >= int(defaultRedemptionRate));

        // If it is smaller than 1, set it to the nagative rate limit
        if (negativeOutputExceedsHundred) {
          newRedemptionRate = NEGATIVE_RATE_LIMIT;
        } else {
          // If boundedPOutput is lower than -int(NEGATIVE_RATE_LIMIT) set newRedemptionRate to 1
          if (boundedPOutput < 0 && boundedPOutput <= -int(NEGATIVE_RATE_LIMIT)) {
            newRedemptionRate = uint(addition(int(defaultRedemptionRate), -int(NEGATIVE_RATE_LIMIT)));
          } else {
            // Otherwise add defaultRedemptionRate and boundedPOutput together
            newRedemptionRate = uint(addition(int(defaultRedemptionRate), boundedPOutput));
          }
        }

        return (newRedemptionRate, defaultGlobalTimeline);
    }
    /*
    * @notice Returns whether the proportional result exceeds the noise barrier
    * @param proportionalResult Represents the P term
    * @param redemptionPrice The system coin redemption price
    */
    function breaksNoiseBarrier(uint proportionalResult, uint redemptionPrice) public isReader view returns (bool) {
        uint deltaNoise = subtract(multiply(uint(2), EIGHTEEN_DECIMAL_NUMBER), noiseBarrier);
        return proportionalResult >= subtract(divide(multiply(redemptionPrice, deltaNoise), EIGHTEEN_DECIMAL_NUMBER), redemptionPrice);
    }

    // --- Rate Validation/Calculation ---
    /*
    * @notice Compute a new redemption rate
    * @param marketPrice The system coin market price
    * @param redemptionPrice The system coin redemption price
    */
    function computeRate(
      uint marketPrice,
      uint redemptionPrice,
      uint
    ) external returns (uint256) {
        // Only the seed proposer can call this
        require(seedProposer == msg.sender, "PRawPerSecondCalculator/invalid-msg-sender");
        // Ensure that at least periodSize seconds passed since the last update or that this is the first update
        require(subtract(now, lastUpdateTime) >= periodSize || lastUpdateTime == 0, "PRawPerSecondCalculator/wait-more");
        // The proportional term is just redemption - market. Market is read as having 18 decimals so we multiply by 10**9
        // in order to have 27 decimals like the redemption price
        int256 proportionalTerm = subtract(int(redemptionPrice), multiply(int(marketPrice), int(10**9)));
        // Set the last update time to now
        lastUpdateTime = now;
        // Multiply P by Kp
        proportionalTerm = multiply(proportionalTerm, int(Kp)) / int(EIGHTEEN_DECIMAL_NUMBER);
        // If the P * Kp output breaks the noise barrier, you can recompute a non null rate. Also make sure the output is not null
        if (
          breaksNoiseBarrier(absolute(proportionalTerm), redemptionPrice) &&
          proportionalTerm != 0
        ) {
          // Get the new redemption rate by taking into account the feedbackOutputUpperBound and feedbackOutputLowerBound
          (uint newRedemptionRate, ) = getBoundedRedemptionRate(proportionalTerm);
          return newRedemptionRate;
        } else {
          return TWENTY_SEVEN_DECIMAL_NUMBER;
        }
    }
    /*
    * @notice Compute and return the upcoming redemption rate
    * @param marketPrice The system coin market price
    * @param redemptionPrice The system coin redemption price
    */
    function getNextRedemptionRate(uint marketPrice, uint redemptionPrice, uint)
      public isReader view returns (uint256, int256, uint256) {
        // The proportional term is just redemption - market. Market is read as having 18 decimals so we multiply by 10**9
        // in order to have 27 decimals like the redemption price
        int256 rawProportionalTerm = subtract(int(redemptionPrice), multiply(int(marketPrice), int(10**9)));
        // Multiply P by Kp
        int256 gainProportionalTerm = multiply(rawProportionalTerm, int(Kp)) / int(EIGHTEEN_DECIMAL_NUMBER);
        // If the P * Kp output breaks the noise barrier, you can recompute a non null rate. Also make sure the output is not null
        if (
          breaksNoiseBarrier(absolute(gainProportionalTerm), redemptionPrice) &&
          gainProportionalTerm != 0
        ) {
          // Get the new redemption rate by taking into account the feedbackOutputUpperBound and feedbackOutputLowerBound
          (uint newRedemptionRate, uint rateTimeline) = getBoundedRedemptionRate(gainProportionalTerm);
          return (newRedemptionRate, rawProportionalTerm, rateTimeline);
        } else {
          return (TWENTY_SEVEN_DECIMAL_NUMBER, rawProportionalTerm, defaultGlobalTimeline);
        }
    }

    // --- Parameter Getters ---
    /*
    * @notice Get the timeline over which the computed redemption rate takes effect e.g rateTimeline = 3600 so the rate is
    *         computed over 1 hour
    */
    function rt(uint marketPrice, uint redemptionPrice, uint) external isReader view returns (uint256) {
        (, , uint rateTimeline) = getNextRedemptionRate(marketPrice, redemptionPrice, 0);
        return rateTimeline;
    }
    /*
    * @notice Return Kp
    */
    function sg() external isReader view returns (int256) {
        return Kp;
    }
    function nb() external isReader view returns (uint256) {
        return noiseBarrier;
    }
    function drr() external isReader view returns (uint256) {
        return defaultRedemptionRate;
    }
    function foub() external isReader view returns (uint256) {
        return feedbackOutputUpperBound;
    }
    function folb() external isReader view returns (int256) {
        return feedbackOutputLowerBound;
    }
    function ps() external isReader view returns (uint256) {
        return periodSize;
    }
    function pscl() external isReader view returns (uint256) {
        return TWENTY_SEVEN_DECIMAL_NUMBER;
    }
    function lut() external isReader view returns (uint256) {
        return lastUpdateTime;
    }
    function dgt() external isReader view returns (uint256) {
        return defaultGlobalTimeline;
    }
    /*
    * @notice Returns the time elapsed since the last calculateRate call minus periodSize
    */
    function adat() external isReader view returns (uint256) {
        uint elapsed = subtract(now, lastUpdateTime);
        if (elapsed < periodSize) {
          return 0;
        }
        return subtract(elapsed, periodSize);
    }
    /*
    * @notice Returns the time elapsed since the last calculateRate call
    */
    function tlv() external isReader view returns (uint256) {
        uint elapsed = (lastUpdateTime == 0) ? 0 : subtract(now, lastUpdateTime);
        return elapsed;
    }
}


abstract contract OldRateSetterLike is PIRateSetter {
    function treasury() public virtual returns (address);
}

abstract contract Setter {
    function addAuthorization(address) external virtual;
    function removeAuthorization(address) external virtual;
    function modifyParameters(bytes32,bytes32,address) external virtual;
}

// @dev This contract is meant for upgrading from an older version of the rate setter to a new one that supports both a P only and a PI calculator
// It also deploys a P only calculator and connects it to the rate setter.
// The very last steps are not performed in order to allow for testing in prod before commiting to an upgrade (steps commented in the execute function)
contract DeployPIRateSetter {
    uint constant RAY = 10 ** 27;

    function execute(address oldRateSetter) public returns (address, address, address) {
        OldRateSetterLike oldSetter       = OldRateSetterLike(oldRateSetter);
        StabilityFeeTreasuryLike treasury = StabilityFeeTreasuryLike(oldSetter.treasury());

        // deploy the P only calculator
        PRawPerSecondCalculator calculator = new PRawPerSecondCalculator(
            5 * 10**8,       // sg
            21600,           // periodSize
            10**18,          // noiseBarrier
            10**45,          // feedbackUpperBound
            -int((10**27)-1) // feedbackLowerBound
        );

        // deploy the setter wrapper
        SetterRelayer relayer = new SetterRelayer(
            address(oldSetter.oracleRelayer()),
            address(oldSetter.treasury()),
            0.0001 ether,  // baseUpdateCallerReward
            0.0001 ether,  // maxUpdateCallerReward
            1 * RAY,       // perSecondCallerRewardIncrease
            21600          // relayDelay
        );

        relayer.modifyParameters("maxRewardIncreaseDelay", 10800);

        // deploy new rate setter
        PIRateSetter rateSetter = new PIRateSetter(
            address(oldSetter.oracleRelayer()),
            address(relayer),
            address(oldSetter.orcl()),
            address(calculator),
            21600 // updateRateDelay
        );

        rateSetter.modifyParameters("defaultLeak", 1);

        // Setup treasury allowance
        treasury.setTotalAllowance(address(oldSetter), 0);
        treasury.setPerBlockAllowance(address(oldSetter), 0);

        treasury.setTotalAllowance(address(relayer), uint(-1));
        treasury.setPerBlockAllowance(address(relayer), 0.0001 ether * RAY);

        // auth
        calculator.modifyParameters("seedProposer", address(rateSetter));
        relayer.modifyParameters("setter", address(rateSetter));
        // Setter(address(oldSetter.oracleRelayer())).addAuthorization(address(relayer));
        // Setter(address(oldSetter.oracleRelayer())).removeAuthorization(address(oldSetter));

        return (address(calculator), address(rateSetter), address(relayer));
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"int256","name":"Kp_","type":"int256"},{"internalType":"uint256","name":"periodSize_","type":"uint256"},{"internalType":"uint256","name":"noiseBarrier_","type":"uint256"},{"internalType":"uint256","name":"feedbackOutputUpperBound_","type":"uint256"},{"internalType":"int256","name":"feedbackOutputLowerBound_","type":"int256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Kp","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adat","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addReader","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allReaderToggle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorities","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proportionalResult","type":"uint256"},{"internalType":"uint256","name":"redemptionPrice","type":"uint256"}],"name":"breaksNoiseBarrier","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketPrice","type":"uint256"},{"internalType":"uint256","name":"redemptionPrice","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"computeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dgt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"drr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"folb","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"foub","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"pOutput","type":"int256"}],"name":"getBoundedRedemptionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketPrice","type":"uint256"},{"internalType":"uint256","name":"redemptionPrice","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"getNextRedemptionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"int256","name":"val","type":"int256"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"address","name":"addr","type":"address"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"uint256","name":"val","type":"uint256"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nb","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pscl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"readers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeReader","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketPrice","type":"uint256"},{"internalType":"uint256","name":"redemptionPrice","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"seedProposer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sg","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tlv","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162001d8338038062001d83833981810160405260a08110156200003757600080fd5b5080516020820151604083015160608401516080909401516b033b2e3c9fd0803ce8000000600581905593949293919291620000af906200009b906200008a90600019906001600160e01b036200029616565b60016001600160e01b036200029616565b83108315156001600160e01b03620002e716565b620000ec5760405162461bcd60e51b815260040180806020018281038252602481526020018062001cf66024913960400191505060405180910390fd5b62000114600082126b033b2e3c9fd0803ce7fffffe198312156001600160e01b03620002e716565b620001515760405162461bcd60e51b815260040180806020018281038252602481526020018062001d1a6024913960400191505060405180910390fd5b60008411620001925760405162461bcd60e51b815260040180806020018281038252602381526020018062001d3e6023913960400191505060405180910390fd5b620001b4831515670de0b6b3a76400008511156001600160e01b03620002e716565b620001f15760405162461bcd60e51b815260040180806020018281038252602281526020018062001cd46022913960400191505060405180910390fd5b6200021d670de0b6b3a763ffff19861215670de0b6b3a76400008713156001600160e01b03620002e716565b6200025a5760405162461bcd60e51b815260040180806020018281038252602281526020018062001d616022913960400191505060405180910390fd5b33600090815260208181526040808320600190819055918290529091205560069190915560075560089190915560029190915560045562000386565b6000620002e083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250620002eb60201b60201c565b9392505050565b1690565b600081848411156200037e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156200034257818101518382015260200162000328565b50505050905090810190601f168015620003705780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b61193e80620003966000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806369cb9945116100f9578063afd8b1d111610097578063d2c00e2411610071578063d2c00e241461046c578063d41fb39c14610474578063d544e0101461047c578063fe4f5890146104a2576101c4565b8063afd8b1d114610407578063b8bf1a051461042d578063c1b8008314610435576101c4565b8063803c6ee6116100d3578063803c6ee6146103c9578063822c530e146103d15780638d8900bd146103d957806391223d69146103e1576101c4565b806369cb9945146103745780636e3126ef1461039857806371c7132e146103a0576101c4565b806341a54550116101665780635f1b0b98116101405780635f1b0b9814610315578063610a714a1461031d5780636531fe7b146103405780636614f01014610348576101c4565b806341a54550146102a05780634635a4f4146102a857806351e59ffb146102ef576101c4565b80632af8afca116101a25780632af8afca1461026257806330d1c5151461026a5780633523af481461027257806338d65d111461027a576101c4565b80631f5b3005146101c957806326defa73146101ff57806328f2d58914610227575b600080fd5b6101e6600480360360208110156101df57600080fd5b50356104c5565b6040805192835260208301919091528051918290030190f35b6102256004803603602081101561021557600080fd5b50356001600160a01b03166105e0565b005b6102506004803603606081101561023d57600080fd5b508035906020810135906040013561064b565b60408051918252519081900360200190f35b6102506106c6565b61025061072d565b610250610794565b6102256004803603602081101561029057600080fd5b50356001600160a01b031661082a565b610250610892565b6102d1600480360360608110156102be57600080fd5b50803590602081013590604001356108f9565b60408051938452602084019290925282820152519081900360600190f35b6102506004803603602081101561030557600080fd5b50356001600160a01b03166109f8565b610250610a0a565b6102256004803603604081101561033357600080fd5b5080359060200135610a7b565b610250610be8565b6102256004803603604081101561035e57600080fd5b50803590602001356001600160a01b0316610bee565b61037c610c9a565b604080516001600160a01b039092168252519081900360200190f35b610250610ca9565b610250600480360360608110156103b657600080fd5b5080359060208101359060400135610d2e565b610250610e5a565b610250610ec1565b610250610f28565b610250600480360360208110156103f757600080fd5b50356001600160a01b0316610f8f565b6102256004803603602081101561041d57600080fd5b50356001600160a01b0316610fa1565b61025061100c565b6104586004803603604081101561044b57600080fd5b5080359060200135611012565b604080519115158252519081900360200190f35b6102506110c5565b61025061112c565b6102256004803603602081101561049257600080fd5b50356001600160a01b0316611193565b610225600480360360408110156104b857600080fd5b50803590602001356111fb565b600354336000908152600160208190526040822054919283926104ec9291821491146113bd565b6105275760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b6007548390600090821215610540576007549150610550565b6006548513156105505760065491505b6000808312801561056657506005548360000312155b90508015610582576b033b2e3c9fd0803ce7ffffff91506105d4565b60008312801561059f57506b033b2e3c9fd0803ce7fffffe198313155b156105c5576005546105be906b033b2e3c9fd0803ce7fffffe196113c1565b91506105d4565b6105d1600554846113c1565b91505b50946001945092505050565b3360009081526020819052604090205460011461062e5760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b6001600160a01b0316600090815260208190526040902060019055565b60035433600090815260016020819052604082205491926106709290821491146113bd565b6106ab5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b60006106b9858560006108f9565b93505050505b9392505050565b60035433600090815260016020819052604082205491926106eb9290821491146113bd565b6107265760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060015b90565b60035433600090815260016020819052604082205491926107529290821491146113bd565b61078d5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060095490565b60035433600090815260016020819052604082205491926107b99290821491146113bd565b6107f45760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b600061080242600954611426565b905060085481101561081857600091505061072a565b61082481600854611426565b91505090565b336000908152602081905260409020546001146108785760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b6001600160a01b0316600090815260016020526040812055565b60035433600090815260016020819052604082205491926108b79290821491146113bd565b6108f25760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060085490565b60035433600090815260016020819052604082205491928392839261092192811491146113bd565b61095c5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b60006109758661097089633b9aca00611468565b611511565b90506000670de0b6b3a764000061098e83600254611468565b8161099557fe5b0590506109aa6109a482611576565b88611012565b80156109b557508015155b156109d8576000806109c6836104c5565b9097509395509293506109ef92505050565b506b033b2e3c9fd0803ce800000093509150600190505b93509350939050565b60016020526000908152604090205481565b6003543360009081526001602081905260408220549192610a2f9290821491146113bd565b610a6a5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b506b033b2e3c9fd0803ce800000090565b33600090815260208190526040902054600114610ac95760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b81633337b63160e11b1415610b3a57610af5600082126b033b2e3c9fd0803ce7fffffe1983121561158c565b610b305760405162461bcd60e51b81526004018080602001828103825260248152602001806118466024913960400191505060405180910390fd5b6007819055610be4565b8161736760f01b1415610bad57610b68670de0b6b3a763ffff19821215670de0b6b3a764000083131561158c565b610ba35760405162461bcd60e51b81526004018080602001828103825260228152602001806118bf6022913960400191505060405180910390fd5b6002819055610be4565b60405162461bcd60e51b815260040180806020018281038252603181526020018061186a6031913960400191505060405180910390fd5b5050565b60035481565b33600090815260208190526040902054600114610c3c5760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b816b39b2b2b2283937b837b9b2b960a11b1415610bad57600a80546001600160a01b03908116600090815260016020819052604080832083905584546001600160a01b03191686851617948590559390921681529190912055610be4565b600a546001600160a01b031681565b6003543360009081526001602081905260408220549192610cce9290821491146113bd565b610d095760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b6000600954600014610d2657610d2142600954611426565b610824565b600091505090565b600a546000906001600160a01b03163314610d7a5760405162461bcd60e51b815260040180806020018281038252602a81526020018061178f602a913960400191505060405180910390fd5b600854610d8942600954611426565b101580610d965750600954155b610dd15760405162461bcd60e51b81526004018080602001828103825260218152602001806117fe6021913960400191505060405180910390fd5b6000610de58461097087633b9aca00611468565b905042600981905550670de0b6b3a7640000610e0382600254611468565b81610e0a57fe5b059050610e1f610e1982611576565b85611012565b8015610e2a57508015155b15610e45576000610e3a826104c5565b5092506106bf915050565b6b033b2e3c9fd0803ce80000009150506106bf565b6003543360009081526001602081905260408220549192610e7f9290821491146113bd565b610eba5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060065490565b6003543360009081526001602081905260408220549192610ee69290821491146113bd565b610f215760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060075490565b6003543360009081526001602081905260408220549192610f4d9290821491146113bd565b610f885760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060025490565b60006020819052908152604090205481565b33600090815260208190526040902054600114610fef5760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b6001600160a01b0316600090815260016020819052604090912055565b60025481565b60035433600090815260016020819052604082205491926110379290821491146113bd565b6110725760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b600061109261108a6002670de0b6b3a7640000611590565b600454611426565b90506110b86110b26110a48584611590565b670de0b6b3a76400006115e9565b84611426565b8410159150505b92915050565b60035433600090815260016020819052604082205491926110ea9290821491146113bd565b6111255760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060045490565b60035433600090815260016020819052604082205491926111519290821491146113bd565b61118c5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060055490565b336000908152602081905260409020546001146111e15760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b6001600160a01b0316600090815260208190526040812055565b336000908152602081905260409020546001146112495760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b8161373160f11b14156112b35761126e60008211670de0b6b3a764000083111561158c565b6112a95760405162461bcd60e51b815260040180806020018281038252602281526020018061174c6022913960400191505060405180910390fd5b6004819055610be4565b8161707360f01b141561131f5760008111611315576040805162461bcd60e51b815260206004820152601f60248201527f505261775065725365636f6e6443616c63756c61746f722f6e756c6c2d707300604482015290519081900360640190fd5b6008819055610be4565b81633337bab160e11b141561139957611354611349611342600019600554611426565b6001611426565b82106000831161158c565b61138f5760405162461bcd60e51b81526004018080602001828103825260248152602001806117b96024913960400191505060405180910390fd5b6006819055610be4565b816e616c6c526561646572546f67676c6560881b1415610bad576003819055610be4565b1790565b60008282018183128015906113d65750838112155b806113eb57506000831280156113eb57508381125b6106bf5760405162461bcd60e51b815260040180806020018281038252602181526020018061176e6021913960400191505060405180910390fd5b60006106bf83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061162b565b600082611477575060006110bf565b8260001914801561148b5750600160ff1b82145b156114c75760405162461bcd60e51b815260040180806020018281038252602781526020018061181f6027913960400191505060405180910390fd5b828202828482816114d457fe5b05146106bf5760405162461bcd60e51b815260040180806020018281038252602781526020018061181f6027913960400191505060405180910390fd5b60008183038183128015906115265750838113155b8061153b575060008312801561153b57508381135b6106bf5760405162461bcd60e51b815260040180806020018281038252602481526020018061189b6024913960400191505060405180910390fd5b600080821261158557816110bf565b5060000390565b1690565b60008261159f575060006110bf565b828202828482816115ac57fe5b04146106bf5760405162461bcd60e51b81526004018080602001828103825260218152602001806117dd6021913960400191505060405180910390fd5b60006106bf83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506116c2565b600081848411156116ba5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561167f578181015183820152602001611667565b50505050905090810190601f1680156116ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836117115760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561167f578181015183820152602001611667565b50600083858161171d57fe5b049594505050505056fe505261775065725365636f6e6443616c63756c61746f722f6e6f742d612d726561646572505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d6e625369676e6564536166654d6174683a206164646974696f6e206f766572666c6f77505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d6d73672d73656e646572505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d666f7562536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77505261775065725365636f6e6443616c63756c61746f722f776169742d6d6f72655369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d666f6c62505261775065725365636f6e6443616c63756c61746f722f6d6f646966792d756e7265636f676e697a65642d706172616d5369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f77505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d7367505261775065725365636f6e6443616c63756c61746f722f6e6f742d616e2d617574686f72697479a26469706673582212209d68ad36136d508e915d6a012a90a167bfa4c5e1bc98001a82c178d306cf365c64736f6c63430006070033505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d6e62505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d666f7562505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d666f6c62505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d697073505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d7367000000000000000000000000000000000000000000000000000000001dcd650000000000000000000000000000000000000000000000000000000000000054600000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000002cd76fe086b93ce2f768a00b22a00000000000fffffffffffffffffffffffffffffffffffffffffcc4d1c3602f7fc318000001

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806369cb9945116100f9578063afd8b1d111610097578063d2c00e2411610071578063d2c00e241461046c578063d41fb39c14610474578063d544e0101461047c578063fe4f5890146104a2576101c4565b8063afd8b1d114610407578063b8bf1a051461042d578063c1b8008314610435576101c4565b8063803c6ee6116100d3578063803c6ee6146103c9578063822c530e146103d15780638d8900bd146103d957806391223d69146103e1576101c4565b806369cb9945146103745780636e3126ef1461039857806371c7132e146103a0576101c4565b806341a54550116101665780635f1b0b98116101405780635f1b0b9814610315578063610a714a1461031d5780636531fe7b146103405780636614f01014610348576101c4565b806341a54550146102a05780634635a4f4146102a857806351e59ffb146102ef576101c4565b80632af8afca116101a25780632af8afca1461026257806330d1c5151461026a5780633523af481461027257806338d65d111461027a576101c4565b80631f5b3005146101c957806326defa73146101ff57806328f2d58914610227575b600080fd5b6101e6600480360360208110156101df57600080fd5b50356104c5565b6040805192835260208301919091528051918290030190f35b6102256004803603602081101561021557600080fd5b50356001600160a01b03166105e0565b005b6102506004803603606081101561023d57600080fd5b508035906020810135906040013561064b565b60408051918252519081900360200190f35b6102506106c6565b61025061072d565b610250610794565b6102256004803603602081101561029057600080fd5b50356001600160a01b031661082a565b610250610892565b6102d1600480360360608110156102be57600080fd5b50803590602081013590604001356108f9565b60408051938452602084019290925282820152519081900360600190f35b6102506004803603602081101561030557600080fd5b50356001600160a01b03166109f8565b610250610a0a565b6102256004803603604081101561033357600080fd5b5080359060200135610a7b565b610250610be8565b6102256004803603604081101561035e57600080fd5b50803590602001356001600160a01b0316610bee565b61037c610c9a565b604080516001600160a01b039092168252519081900360200190f35b610250610ca9565b610250600480360360608110156103b657600080fd5b5080359060208101359060400135610d2e565b610250610e5a565b610250610ec1565b610250610f28565b610250600480360360208110156103f757600080fd5b50356001600160a01b0316610f8f565b6102256004803603602081101561041d57600080fd5b50356001600160a01b0316610fa1565b61025061100c565b6104586004803603604081101561044b57600080fd5b5080359060200135611012565b604080519115158252519081900360200190f35b6102506110c5565b61025061112c565b6102256004803603602081101561049257600080fd5b50356001600160a01b0316611193565b610225600480360360408110156104b857600080fd5b50803590602001356111fb565b600354336000908152600160208190526040822054919283926104ec9291821491146113bd565b6105275760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b6007548390600090821215610540576007549150610550565b6006548513156105505760065491505b6000808312801561056657506005548360000312155b90508015610582576b033b2e3c9fd0803ce7ffffff91506105d4565b60008312801561059f57506b033b2e3c9fd0803ce7fffffe198313155b156105c5576005546105be906b033b2e3c9fd0803ce7fffffe196113c1565b91506105d4565b6105d1600554846113c1565b91505b50946001945092505050565b3360009081526020819052604090205460011461062e5760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b6001600160a01b0316600090815260208190526040902060019055565b60035433600090815260016020819052604082205491926106709290821491146113bd565b6106ab5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b60006106b9858560006108f9565b93505050505b9392505050565b60035433600090815260016020819052604082205491926106eb9290821491146113bd565b6107265760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060015b90565b60035433600090815260016020819052604082205491926107529290821491146113bd565b61078d5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060095490565b60035433600090815260016020819052604082205491926107b99290821491146113bd565b6107f45760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b600061080242600954611426565b905060085481101561081857600091505061072a565b61082481600854611426565b91505090565b336000908152602081905260409020546001146108785760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b6001600160a01b0316600090815260016020526040812055565b60035433600090815260016020819052604082205491926108b79290821491146113bd565b6108f25760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060085490565b60035433600090815260016020819052604082205491928392839261092192811491146113bd565b61095c5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b60006109758661097089633b9aca00611468565b611511565b90506000670de0b6b3a764000061098e83600254611468565b8161099557fe5b0590506109aa6109a482611576565b88611012565b80156109b557508015155b156109d8576000806109c6836104c5565b9097509395509293506109ef92505050565b506b033b2e3c9fd0803ce800000093509150600190505b93509350939050565b60016020526000908152604090205481565b6003543360009081526001602081905260408220549192610a2f9290821491146113bd565b610a6a5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b506b033b2e3c9fd0803ce800000090565b33600090815260208190526040902054600114610ac95760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b81633337b63160e11b1415610b3a57610af5600082126b033b2e3c9fd0803ce7fffffe1983121561158c565b610b305760405162461bcd60e51b81526004018080602001828103825260248152602001806118466024913960400191505060405180910390fd5b6007819055610be4565b8161736760f01b1415610bad57610b68670de0b6b3a763ffff19821215670de0b6b3a764000083131561158c565b610ba35760405162461bcd60e51b81526004018080602001828103825260228152602001806118bf6022913960400191505060405180910390fd5b6002819055610be4565b60405162461bcd60e51b815260040180806020018281038252603181526020018061186a6031913960400191505060405180910390fd5b5050565b60035481565b33600090815260208190526040902054600114610c3c5760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b816b39b2b2b2283937b837b9b2b960a11b1415610bad57600a80546001600160a01b03908116600090815260016020819052604080832083905584546001600160a01b03191686851617948590559390921681529190912055610be4565b600a546001600160a01b031681565b6003543360009081526001602081905260408220549192610cce9290821491146113bd565b610d095760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b6000600954600014610d2657610d2142600954611426565b610824565b600091505090565b600a546000906001600160a01b03163314610d7a5760405162461bcd60e51b815260040180806020018281038252602a81526020018061178f602a913960400191505060405180910390fd5b600854610d8942600954611426565b101580610d965750600954155b610dd15760405162461bcd60e51b81526004018080602001828103825260218152602001806117fe6021913960400191505060405180910390fd5b6000610de58461097087633b9aca00611468565b905042600981905550670de0b6b3a7640000610e0382600254611468565b81610e0a57fe5b059050610e1f610e1982611576565b85611012565b8015610e2a57508015155b15610e45576000610e3a826104c5565b5092506106bf915050565b6b033b2e3c9fd0803ce80000009150506106bf565b6003543360009081526001602081905260408220549192610e7f9290821491146113bd565b610eba5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060065490565b6003543360009081526001602081905260408220549192610ee69290821491146113bd565b610f215760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060075490565b6003543360009081526001602081905260408220549192610f4d9290821491146113bd565b610f885760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060025490565b60006020819052908152604090205481565b33600090815260208190526040902054600114610fef5760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b6001600160a01b0316600090815260016020819052604090912055565b60025481565b60035433600090815260016020819052604082205491926110379290821491146113bd565b6110725760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b600061109261108a6002670de0b6b3a7640000611590565b600454611426565b90506110b86110b26110a48584611590565b670de0b6b3a76400006115e9565b84611426565b8410159150505b92915050565b60035433600090815260016020819052604082205491926110ea9290821491146113bd565b6111255760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060045490565b60035433600090815260016020819052604082205491926111519290821491146113bd565b61118c5760405162461bcd60e51b81526004018080602001828103825260248152602001806117286024913960400191505060405180910390fd5b5060055490565b336000908152602081905260409020546001146111e15760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b6001600160a01b0316600090815260208190526040812055565b336000908152602081905260409020546001146112495760405162461bcd60e51b81526004018080602001828103825260288152602001806118e16028913960400191505060405180910390fd5b8161373160f11b14156112b35761126e60008211670de0b6b3a764000083111561158c565b6112a95760405162461bcd60e51b815260040180806020018281038252602281526020018061174c6022913960400191505060405180910390fd5b6004819055610be4565b8161707360f01b141561131f5760008111611315576040805162461bcd60e51b815260206004820152601f60248201527f505261775065725365636f6e6443616c63756c61746f722f6e756c6c2d707300604482015290519081900360640190fd5b6008819055610be4565b81633337bab160e11b141561139957611354611349611342600019600554611426565b6001611426565b82106000831161158c565b61138f5760405162461bcd60e51b81526004018080602001828103825260248152602001806117b96024913960400191505060405180910390fd5b6006819055610be4565b816e616c6c526561646572546f67676c6560881b1415610bad576003819055610be4565b1790565b60008282018183128015906113d65750838112155b806113eb57506000831280156113eb57508381125b6106bf5760405162461bcd60e51b815260040180806020018281038252602181526020018061176e6021913960400191505060405180910390fd5b60006106bf83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061162b565b600082611477575060006110bf565b8260001914801561148b5750600160ff1b82145b156114c75760405162461bcd60e51b815260040180806020018281038252602781526020018061181f6027913960400191505060405180910390fd5b828202828482816114d457fe5b05146106bf5760405162461bcd60e51b815260040180806020018281038252602781526020018061181f6027913960400191505060405180910390fd5b60008183038183128015906115265750838113155b8061153b575060008312801561153b57508381135b6106bf5760405162461bcd60e51b815260040180806020018281038252602481526020018061189b6024913960400191505060405180910390fd5b600080821261158557816110bf565b5060000390565b1690565b60008261159f575060006110bf565b828202828482816115ac57fe5b04146106bf5760405162461bcd60e51b81526004018080602001828103825260218152602001806117dd6021913960400191505060405180910390fd5b60006106bf83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506116c2565b600081848411156116ba5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561167f578181015183820152602001611667565b50505050905090810190601f1680156116ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836117115760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561167f578181015183820152602001611667565b50600083858161171d57fe5b049594505050505056fe505261775065725365636f6e6443616c63756c61746f722f6e6f742d612d726561646572505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d6e625369676e6564536166654d6174683a206164646974696f6e206f766572666c6f77505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d6d73672d73656e646572505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d666f7562536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77505261775065725365636f6e6443616c63756c61746f722f776169742d6d6f72655369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d666f6c62505261775065725365636f6e6443616c63756c61746f722f6d6f646966792d756e7265636f676e697a65642d706172616d5369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f77505261775065725365636f6e6443616c63756c61746f722f696e76616c69642d7367505261775065725365636f6e6443616c63756c61746f722f6e6f742d616e2d617574686f72697479a26469706673582212209d68ad36136d508e915d6a012a90a167bfa4c5e1bc98001a82c178d306cf365c64736f6c63430006070033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000000000001dcd650000000000000000000000000000000000000000000000000000000000000054600000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000002cd76fe086b93ce2f768a00b22a00000000000fffffffffffffffffffffffffffffffffffffffffcc4d1c3602f7fc318000001

-----Decoded View---------------
Arg [0] : Kp_ (int256): 500000000
Arg [1] : periodSize_ (uint256): 21600
Arg [2] : noiseBarrier_ (uint256): 1000000000000000000
Arg [3] : feedbackOutputUpperBound_ (uint256): 1000000000000000000000000000000000000000000000
Arg [4] : feedbackOutputLowerBound_ (int256): -999999999999999999999999999

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000000000000000001dcd6500
Arg [1] : 0000000000000000000000000000000000000000000000000000000000005460
Arg [2] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [3] : 000000000000000000000000002cd76fe086b93ce2f768a00b22a00000000000
Arg [4] : fffffffffffffffffffffffffffffffffffffffffcc4d1c3602f7fc318000001


Deployed Bytecode Sourcemap

32413:14210:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;32413:14210:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;39293:1386:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;39293:1386:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;32560:89;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;32560:89:0;-1:-1:-1;;;;;32560:89:0;;:::i;:::-;;44789:228;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;44789:228:0;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;45900:103;;;:::i;45798:96::-;;;:::i;46116:236::-;;;:::i;33053:85::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;33053:85:0;-1:-1:-1;;;;;33053:85:0;;:::i;45585:91::-;;;:::i;43281:1290::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;43281:1290:0;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;32918:40;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;32918:40:0;-1:-1:-1;;;;;32918:40:0;;:::i;45682:110::-;;;:::i;38230:570::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;38230:570:0;;;;;;;:::i;33523:32::-;;;:::i;36740:326::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;36740:326:0;;;;;;-1:-1:-1;;;;;36740:326:0;;:::i;34700:27::-;;;:::i;:::-;;;;-1:-1:-1;;;;;34700:27:0;;;;;;;;;;;;;;46448:172;;;:::i;41482:1596::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;41482:1596:0;;;;;;;;;;;;:::i;45360:107::-;;;:::i;45473:106::-;;;:::i;45064:82::-;;;:::i;32509:44::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;32509:44:0;-1:-1:-1;;;;;32509:44:0;;:::i;32965:82::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;32965:82:0;-1:-1:-1;;;;;32965:82:0;;:::i;33385:17::-;;;:::i;40900:351::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;40900:351:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;45152:93;;;:::i;45251:103::-;;;:::i;32655:92::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;32655:92:0;-1:-1:-1;;;;;32655:92:0;;:::i;37241:815::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;37241:815:0;;;;;;;:::i;39293:1386::-;33188:15;;33218:10;39370:7;33210:19;;;33207:1;33210:19;;;;;;;;39370:7;;;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39488:24:::1;::::0;39421:7;;39399:19:::1;::::0;39478:34;::::1;39474:228;;;39544:24;;39527:41;;39474:228;;;39604:24;;39590:7;:39;39586:116;;;39665:24;;39644:46;;39586:116;39812:33;39866:1:::0;39849:14:::1;:18;:67;;;;;39894:21;;39872:14;39871:15;;:45;;39849:67;39812:105;;40005:28;40001:609;;;34792:31:::0;;-1:-1:-1;40001:609:0::1;;;40238:1;40221:14;:18;:65;;;;-1:-1:-1::0;;;40243:43:0;::::1;;40221:65;40217:382;;;40341:21;::::0;40328:63:::1;::::0;-1:-1:-1;;40328:8:0::1;:63::i;:::-;40303:89;;40217:382;;;40532:52;40545:21;;40569:14;40532:8;:52::i;:::-;40507:78;;40217:382;-1:-1:-1::0;40630:17:0;34640:1:::1;::::0;-1:-1:-1;39293:1386:0;-1:-1:-1;;;39293:1386:0:o;32560:89::-;32805:10;32793:11;:23;;;;;;;;;;;32820:1;32793:28;32785:81;;;;-1:-1:-1;;;32785:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32622:20:0::1;:11;:20:::0;;;::::1;::::0;;;;;;-1:-1:-1;32622:24:0;;32560:89::o;44789:228::-;33188:15;;33218:10;44879:7;33210:19;;;33207:1;33210:19;;;;;;;;44879:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44904:17:::1;44925:54;44947:11;44960:15;44977:1;44925:21;:54::i;:::-;44899:80:::0;-1:-1:-1;;;;33287:1:0::1;44789:228:::0;;;;;:::o;45900:103::-;33188:15;;33218:10;45947:7;33210:19;;;33207:1;33210:19;;;;;;;;45947:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34640:1:0::1;33287;45900:103:::0;:::o;45798:96::-;33188:15;;33218:10;45845:7;33210:19;;;33207:1;33210:19;;;;;;;;45845:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45872:14:0::1;::::0;45798:96;:::o;46116:236::-;33188:15;;33218:10;46164:7;33210:19;;;33207:1;33210:19;;;;;;;;46164:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46184:12:::1;46199:29;46208:3;46213:14;;46199:8;:29::i;:::-;46184:44;;46253:10;;46243:7;:20;46239:59;;;46285:1;46278:8;;;;;46239:59;46315:29;46324:7;46333:10;;46315:8;:29::i;:::-;46308:36;;;46116:236:::0;:::o;33053:85::-;32805:10;32793:11;:23;;;;;;;;;;;32820:1;32793:28;32785:81;;;;-1:-1:-1;;;32785:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33115:16:0::1;33134:1;33115:16:::0;;;-1:-1:-1;33115:16:0::1;::::0;;;;:20;33053:85::o;45585:91::-;33188:15;;33218:10;45631:7;33210:19;;;33207:1;33210:19;;;;;;;;45631:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45658:10:0::1;::::0;45585:91;:::o;43281:1290::-;33188:15;;33218:10;43395:7;33210:19;;;33207:1;33210:19;;;;;;;;43395:7;;;;;;33181:54;;33188:20;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43623:26:::1;43652:70;43665:15;43683:38;43696:11;43714:5;43683:8;:38::i;:::-;43652:8;:70::i;:::-;43623:99;;43762:27;34957:8;43792:38;43801:19;43826:2;;43792:8;:38::i;:::-;:69;;;;;;43762:99;;44020:67;44039:30;44048:20;44039:8;:30::i;:::-;44071:15;44020:18;:67::i;:::-;:107;;;;-1:-1:-1::0;44102:25:0;;::::1;44020:107;44004:560;;;44276:22;44300:17:::0;44321:46:::1;44346:20;44321:24;:46::i;:::-;44275:92:::0;;-1:-1:-1;44407:19:0;;-1:-1:-1;44275:92:0;;-1:-1:-1;44380:61:0::1;::::0;-1:-1:-1;;;44380:61:0::1;44004:560;-1:-1:-1::0;34886:8:0::1;::::0;-1:-1:-1;44509:19:0;-1:-1:-1;34640:1:0::1;::::0;-1:-1:-1;33287:1:0::1;43281:1290:::0;;;;;;;:::o;32918:40::-;;;;;;;;;;;;;:::o;45682:110::-;33188:15;;33218:10;45730:7;33210:19;;;33207:1;33210:19;;;;;;;;45730:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34886:8:0::1;45682:110:::0;:::o;38230:570::-;32805:10;32793:11;:23;;;;;;;;;;;32820:1;32793:28;32785:81;;;;-1:-1:-1;;;32785:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;38323:19:0;::::1;38319:473;;;38365:47;38376:1;38370:7:::0;::::1;-1:-1:-1::0;;38379:32:0;::::1;;38365:4;:47::i;:::-;38357:96;;;;-1:-1:-1::0;;;38357:96:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38466:24;:30:::0;;;38319:473:::1;;;-1:-1:-1::0;;;38527:17:0;::::1;38523:269;;;38567:79;-1:-1:-1::0;;38572:36:0;::::1;;34957:8;38610:35:::0;::::1;;38567:4;:79::i;:::-;38559:126;;;;-1:-1:-1::0;;;38559:126:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38698:2;:8:::0;;;38523:269:::1;;;38733:59;;-1:-1:-1::0;;;38733:59:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38523:269;38230:570:::0;;:::o;33523:32::-;;;;:::o;36740:326::-;32805:10;32793:11;:23;;;;;;;;;;;32820:1;32793:28;32785:81;;;;-1:-1:-1;;;32785:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;36835:27:0;::::1;36831:227;;;36885:12;::::0;;-1:-1:-1;;;;;36885:12:0;;::::1;36901:1;36877:21:::0;;;-1:-1:-1;36877:21:0::1;::::0;;;;;;;:25;;;36915:19;;-1:-1:-1;;;;;;36915:19:0::1;::::0;;::::1;;::::0;;;;36955:12;;;::::1;36947:21:::0;;;;;;:25;36831:227:::1;;34700:27:::0;;;-1:-1:-1;;;;;34700:27:0;;:::o;46448:172::-;33188:15;;33218:10;46495:7;33210:19;;;33207:1;33210:19;;;;;;;;46495:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46515:12:::1;46531:14;;46549:1;46531:19;46530:57;;46558:29;46567:3;46572:14;;46558:8;:29::i;:::-;46530:57;;;46554:1;46515:72:::0;-1:-1:-1;;46448:172:0;:::o;41482:1596::-;41672:12;;41595:7;;-1:-1:-1;;;;;41672:12:0;41688:10;41672:26;41664:81;;;;-1:-1:-1;;;41664:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41911:10;;41878:29;41887:3;41892:14;;41878:8;:29::i;:::-;:43;;:66;;;-1:-1:-1;41925:14:0;;:19;41878:66;41870:112;;;;-1:-1:-1;;;41870:112:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42184:23;42210:70;42223:15;42241:38;42254:11;42272:5;42241:8;:38::i;42210:70::-;42184:96;;42352:3;42335:14;:20;;;;34957:8;42414:35;42423:16;42445:2;;42414:8;:35::i;:::-;:66;;;;;;42395:85;;42639:63;42658:26;42667:16;42658:8;:26::i;:::-;42686:15;42639:18;:63::i;:::-;:99;;;;-1:-1:-1;42717:21:0;;;42639:99;42623:448;;;42887:22;42915:42;42940:16;42915:24;:42::i;:::-;-1:-1:-1;42886:71:0;-1:-1:-1;42970:24:0;;-1:-1:-1;;42970:24:0;42623:448;34886:8;43025:34;;;;;45360:107;33188:15;;33218:10;45408:7;33210:19;;;33207:1;33210:19;;;;;;;;45408:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45435:24:0::1;::::0;45360:107;:::o;45473:106::-;33188:15;;33218:10;45521:6;33210:19;;;33207:1;33210:19;;;;;;;;45521:6;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45547:24:0::1;::::0;45473:106;:::o;45064:82::-;33188:15;;33218:10;45110:6;33210:19;;;33207:1;33210:19;;;;;;;;45110:6;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45136:2:0::1;::::0;45064:82;:::o;32509:44::-;;;;;;;;;;;;;;:::o;32965:82::-;32805:10;32793:11;:23;;;;;;;;;;;32820:1;32793:28;32785:81;;;;-1:-1:-1;;;32785:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33024:16:0::1;;::::0;;;-1:-1:-1;33024:16:0::1;::::0;;;;;;;:20;32965:82::o;33385:17::-;;;;:::o;40900:351::-;33188:15;;33218:10;41005:4;33210:19;;;33207:1;33210:19;;;;;;;;41005:4;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41022:15:::1;41040:66;41049:42;41063:1;34957:8;41049;:42::i;:::-;41093:12;;41040:8;:66::i;:::-;41022:84;;41146:97;41155:70;41162:37;41171:15;41188:10;41162:8;:37::i;:::-;34957:8;41155:6;:70::i;:::-;41227:15;41146:8;:97::i;:::-;41124:18;:119;;41117:126;;;33287:1;40900:351:::0;;;;:::o;45152:93::-;33188:15;;33218:10;45198:7;33210:19;;;33207:1;33210:19;;;;;;;;45198:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45225:12:0::1;::::0;45152:93;:::o;45251:103::-;33188:15;;33218:10;45298:7;33210:19;;;33207:1;33210:19;;;;;;;;45298:7;;33181:54;;33188:20;;;;33210:24;33181:6;:54::i;:::-;33173:103;;;;-1:-1:-1;;;33173:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45325:21:0::1;::::0;45251:103;:::o;32655:92::-;32805:10;32793:11;:23;;;;;;;;;;;32820:1;32793:28;32785:81;;;;-1:-1:-1;;;32785:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32720:20:0::1;32743:1;32720:20:::0;;;::::1;::::0;;;;;;:24;32655:92::o;37241:815::-;32805:10;32793:11;:23;;;;;;;;;;;32820:1;32793:28;32785:81;;;;-1:-1:-1;;;32785:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;37335:17:0;::::1;37331:717;;;37375:45;37386:1;37380:3;:7;34957:8;37389:3;:30;;37375:4;:45::i;:::-;37367:92;;;;-1:-1:-1::0;;;37367:92:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37472:12;:18:::0;;;37331:717:::1;;;-1:-1:-1::0;;;37521:17:0;::::1;37517:531;;;37567:1;37561:3;:7;37553:51;;;::::0;;-1:-1:-1;;;37553:51:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;37617:10;:16:::0;;;37517:531:::1;;;-1:-1:-1::0;;;37664:19:0;::::1;37660:388;;;37706:75;37717:54;37726:41;-1:-1:-1::0;;37745:21:0::1;;37726:8;:41::i;:::-;37769:1;37717:8;:54::i;:::-;37711:3;:60;37779:1;37773:3;:7;37706:4;:75::i;:::-;37698:124;;;;-1:-1:-1::0;;;37698:124:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37835:24;:30:::0;;;37660:388:::1;;;-1:-1:-1::0;;;37896:30:0;::::1;37892:156;;;37941:15;:21:::0;;;37892:156:::1;;36416:105:::0;36505:8;;36498:16::o;24931:220::-;24992:6;25022:5;;;25047:6;;;;;;:16;;;25062:1;25057;:6;;25047:16;25046:38;;;;25073:1;25069;:5;:14;;;;;25082:1;25078;:5;25069:14;25038:84;;;;-1:-1:-1;;;25038:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26470:146;26533:7;26560:48;26569:1;26572;26560:48;;;;;;;;;;;;;;;;;:8;:48::i;22891:573::-;22952:6;23196;23192:47;;-1:-1:-1;23226:1:0;23219:8;;23192:47;-1:-1:-1;;23261:7:0;;:27;;;;-1:-1:-1;;;;23272:16:0;;23261:27;23259:30;23251:82;;;;-1:-1:-1;;;23251:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23357:5;;;23361:1;23357;:5;:1;23381:5;;;;;:10;23373:62;;;;-1:-1:-1;;;23373:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24463:223;24524:6;24554:5;;;24579:6;;;;;;:16;;;24594:1;24589;:6;;24579:16;24578:38;;;;24605:1;24601;:5;:14;;;;;24614:1;24610;:5;24601:14;24570:87;;;;-1:-1:-1;;;24570:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38849:107;38897:6;38925:1;38921;:5;38920:28;;38946:1;38920:28;;;-1:-1:-1;38935:2:0;;;38849:107::o;36306:104::-;36393:9;;36386:17::o;27375:476::-;27438:7;27683:6;27679:47;;-1:-1:-1;27713:1:0;27706:8;;27679:47;27750:5;;;27754:1;27750;:5;:1;27774:5;;;;;:10;27766:56;;;;-1:-1:-1;;;27766:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28327:138;28388:7;28415:42;28422:1;28425;28415:42;;;;;;;;;;;;;;;;;:6;:42::i;26919:197::-;27010:7;27046:12;27038:6;;;;27030:29;;;;-1:-1:-1;;;27030:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;27030:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;27082:5:0;;;26919:197::o;28961:281::-;29050:7;29085:12;29078:5;29070:28;;;;-1:-1:-1;;;29070:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27:10;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;29070:28:0;;29109:9;29125:1;29121;:5;;;;;;;28961:281;-1:-1:-1;;;;;28961:281:0:o

Swarm Source

ipfs://9d68ad36136d508e915d6a012a90a167bfa4c5e1bc98001a82c178d306cf365c

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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