ETH Price: $2,362.45 (+0.41%)

Contract

0xB21F266E63335153798a0426DB1E256E7eC7cA52
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Prices207338562024-09-12 10:12:1114 hrs ago1726135931IN
0xB21F266E...E7eC7cA52
0 ETH0.000212614.08387322
Set Prices207278392024-09-11 14:02:4734 hrs ago1726063367IN
0xB21F266E...E7eC7cA52
0 ETH0.000390447.4997217
Set Prices207164452024-09-09 23:49:353 days ago1725925775IN
0xB21F266E...E7eC7cA52
0 ETH0.000246144.72802336
Set Prices207141782024-09-09 16:14:233 days ago1725898463IN
0xB21F266E...E7eC7cA52
0 ETH0.001132421.74657863
Set Prices207087852024-09-08 22:10:354 days ago1725833435IN
0xB21F266E...E7eC7cA52
0 ETH0.000122142.34619901
Set Prices207053202024-09-08 10:32:474 days ago1725791567IN
0xB21F266E...E7eC7cA52
0 ETH0.000125882.41801108
Set Prices207003552024-09-07 17:55:475 days ago1725731747IN
0xB21F266E...E7eC7cA52
0 ETH0.000143832.7628289
Set Prices206991872024-09-07 14:01:355 days ago1725717695IN
0xB21F266E...E7eC7cA52
0 ETH0.000163373.13807681
Set Prices206964002024-09-07 4:42:235 days ago1725684143IN
0xB21F266E...E7eC7cA52
0 ETH0.000138942.66884487
Set Prices206959252024-09-07 3:07:115 days ago1725678431IN
0xB21F266E...E7eC7cA52
0 ETH0.000128172.46198266
Set Prices206937232024-09-06 19:44:596 days ago1725651899IN
0xB21F266E...E7eC7cA52
0 ETH0.000332016.37737919
Set Prices206933992024-09-06 18:39:596 days ago1725647999IN
0xB21F266E...E7eC7cA52
0 ETH0.000434118.33669773
Set Prices206930972024-09-06 17:39:116 days ago1725644351IN
0xB21F266E...E7eC7cA52
0 ETH0.0007536814.47366535
Set Prices206920892024-09-06 14:15:596 days ago1725632159IN
0xB21F266E...E7eC7cA52
0 ETH0.0018390335.31652517
Set Prices206786852024-09-04 17:22:598 days ago1725470579IN
0xB21F266E...E7eC7cA52
0 ETH0.0005786611.11248907
Set Prices206782562024-09-04 15:56:478 days ago1725465407IN
0xB21F266E...E7eC7cA52
0 ETH0.0005714910.97485028
Set Prices206779102024-09-04 14:46:478 days ago1725461207IN
0xB21F266E...E7eC7cA52
0 ETH0.000386927.43036092
Set Prices206738272024-09-04 1:06:358 days ago1725411995IN
0xB21F266E...E7eC7cA52
0 ETH0.0007610714.61551883
Set Prices206738142024-09-04 1:03:598 days ago1725411839IN
0xB21F266E...E7eC7cA52
0 ETH0.000454365.89513484
Set Prices206636922024-09-02 15:10:4710 days ago1725289847IN
0xB21F266E...E7eC7cA52
0 ETH0.0005699910.94606295
Set Prices206622492024-09-02 10:20:1110 days ago1725272411IN
0xB21F266E...E7eC7cA52
0 ETH0.000387927.45141261
Set Prices206614712024-09-02 7:44:1110 days ago1725263051IN
0xB21F266E...E7eC7cA52
0 ETH0.000176493.39103253
Set Prices206587052024-09-01 22:29:2311 days ago1725229763IN
0xB21F266E...E7eC7cA52
0 ETH0.000119242.29002328
Set Prices206542922024-09-01 7:40:5911 days ago1725176459IN
0xB21F266E...E7eC7cA52
0 ETH0.000113172.17397822
Set Prices206541392024-09-01 7:10:2311 days ago1725174623IN
0xB21F266E...E7eC7cA52
0 ETH0.000111642.14457217
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PriceOracleV1

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, BSD-3-Clause license
File 1 of 1 : v1PriceOracle.sol
pragma solidity ^0.5.16;

contract ErrorReporter {
    /**
     * @dev `error` corresponds to enum Error; `info` corresponds to enum FailureInfo, and `detail` is an arbitrary
     * contract-specific code that enables us to report opaque error codes from upgradeable contracts.
     **/
    event Failure(uint256 error, uint256 info, uint256 detail);

    enum Error {
        NO_ERROR,
        OPAQUE_ERROR, // To be used when reporting errors from upgradeable contracts; the opaque code should be given as `detail` in the `Failure` event
        UNAUTHORIZED,
        INTEGER_OVERFLOW,
        INTEGER_UNDERFLOW,
        DIVISION_BY_ZERO,
        BAD_INPUT,
        TOKEN_INSUFFICIENT_ALLOWANCE,
        TOKEN_INSUFFICIENT_BALANCE,
        TOKEN_TRANSFER_FAILED,
        MARKET_NOT_SUPPORTED,
        SUPPLY_RATE_CALCULATION_FAILED,
        BORROW_RATE_CALCULATION_FAILED,
        TOKEN_INSUFFICIENT_CASH,
        TOKEN_TRANSFER_OUT_FAILED,
        INSUFFICIENT_LIQUIDITY,
        INSUFFICIENT_BALANCE,
        INVALID_COLLATERAL_RATIO,
        MISSING_ASSET_PRICE,
        EQUITY_INSUFFICIENT_BALANCE,
        INVALID_CLOSE_AMOUNT_REQUESTED,
        ASSET_NOT_PRICED,
        INVALID_LIQUIDATION_DISCOUNT,
        INVALID_COMBINED_RISK_PARAMETERS
    }

    /*
     * Note: FailureInfo (but not Error) is kept in alphabetical order
     *       This is because FailureInfo grows significantly faster, and
     *       the order of Error has some meaning, while the order of FailureInfo
     *       is entirely arbitrary.
     */
    enum FailureInfo {
        BORROW_ACCOUNT_LIQUIDITY_CALCULATION_FAILED,
        BORROW_ACCOUNT_SHORTFALL_PRESENT,
        BORROW_AMOUNT_LIQUIDITY_SHORTFALL,
        BORROW_AMOUNT_VALUE_CALCULATION_FAILED,
        BORROW_MARKET_NOT_SUPPORTED,
        BORROW_NEW_BORROW_INDEX_CALCULATION_FAILED,
        BORROW_NEW_BORROW_RATE_CALCULATION_FAILED,
        BORROW_NEW_SUPPLY_INDEX_CALCULATION_FAILED,
        BORROW_NEW_SUPPLY_RATE_CALCULATION_FAILED,
        BORROW_NEW_TOTAL_BORROW_CALCULATION_FAILED,
        BORROW_NEW_TOTAL_CASH_CALCULATION_FAILED,
        BORROW_ORIGINATION_FEE_CALCULATION_FAILED,
        BORROW_TRANSFER_OUT_FAILED,
        EQUITY_WITHDRAWAL_AMOUNT_VALIDATION,
        EQUITY_WITHDRAWAL_CALCULATE_EQUITY,
        EQUITY_WITHDRAWAL_MODEL_OWNER_CHECK,
        EQUITY_WITHDRAWAL_TRANSFER_OUT_FAILED,
        LIQUIDATE_ACCUMULATED_BORROW_BALANCE_CALCULATION_FAILED,
        LIQUIDATE_ACCUMULATED_SUPPLY_BALANCE_CALCULATION_FAILED_BORROWER_COLLATERAL_ASSET,
        LIQUIDATE_ACCUMULATED_SUPPLY_BALANCE_CALCULATION_FAILED_LIQUIDATOR_COLLATERAL_ASSET,
        LIQUIDATE_AMOUNT_SEIZE_CALCULATION_FAILED,
        LIQUIDATE_BORROW_DENOMINATED_COLLATERAL_CALCULATION_FAILED,
        LIQUIDATE_CLOSE_AMOUNT_TOO_HIGH,
        LIQUIDATE_DISCOUNTED_REPAY_TO_EVEN_AMOUNT_CALCULATION_FAILED,
        LIQUIDATE_NEW_BORROW_INDEX_CALCULATION_FAILED_BORROWED_ASSET,
        LIQUIDATE_NEW_BORROW_INDEX_CALCULATION_FAILED_COLLATERAL_ASSET,
        LIQUIDATE_NEW_BORROW_RATE_CALCULATION_FAILED_BORROWED_ASSET,
        LIQUIDATE_NEW_SUPPLY_INDEX_CALCULATION_FAILED_BORROWED_ASSET,
        LIQUIDATE_NEW_SUPPLY_INDEX_CALCULATION_FAILED_COLLATERAL_ASSET,
        LIQUIDATE_NEW_SUPPLY_RATE_CALCULATION_FAILED_BORROWED_ASSET,
        LIQUIDATE_NEW_TOTAL_BORROW_CALCULATION_FAILED_BORROWED_ASSET,
        LIQUIDATE_NEW_TOTAL_CASH_CALCULATION_FAILED_BORROWED_ASSET,
        LIQUIDATE_NEW_TOTAL_SUPPLY_BALANCE_CALCULATION_FAILED_BORROWER_COLLATERAL_ASSET,
        LIQUIDATE_NEW_TOTAL_SUPPLY_BALANCE_CALCULATION_FAILED_LIQUIDATOR_COLLATERAL_ASSET,
        LIQUIDATE_TRANSFER_IN_FAILED,
        LIQUIDATE_TRANSFER_IN_NOT_POSSIBLE,
        REPAY_BORROW_NEW_BORROW_INDEX_CALCULATION_FAILED,
        REPAY_BORROW_NEW_BORROW_RATE_CALCULATION_FAILED,
        REPAY_BORROW_NEW_SUPPLY_INDEX_CALCULATION_FAILED,
        REPAY_BORROW_NEW_SUPPLY_RATE_CALCULATION_FAILED,
        REPAY_BORROW_NEW_TOTAL_BORROW_CALCULATION_FAILED,
        REPAY_BORROW_NEW_TOTAL_CASH_CALCULATION_FAILED,
        REPAY_BORROW_TRANSFER_IN_FAILED,
        REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE,
        SET_ADMIN_OWNER_CHECK,
        SET_ASSET_PRICE_CHECK_ORACLE,
        SET_MARKET_INTEREST_RATE_MODEL_OWNER_CHECK,
        SET_ORACLE_OWNER_CHECK,
        SET_ORIGINATION_FEE_OWNER_CHECK,
        SET_RISK_PARAMETERS_OWNER_CHECK,
        SET_RISK_PARAMETERS_VALIDATION,
        SUPPLY_ACCUMULATED_BALANCE_CALCULATION_FAILED,
        SUPPLY_MARKET_NOT_SUPPORTED,
        SUPPLY_NEW_BORROW_INDEX_CALCULATION_FAILED,
        SUPPLY_NEW_BORROW_RATE_CALCULATION_FAILED,
        SUPPLY_NEW_SUPPLY_INDEX_CALCULATION_FAILED,
        SUPPLY_NEW_SUPPLY_RATE_CALCULATION_FAILED,
        SUPPLY_NEW_TOTAL_BALANCE_CALCULATION_FAILED,
        SUPPLY_NEW_TOTAL_CASH_CALCULATION_FAILED,
        SUPPLY_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,
        SUPPLY_TRANSFER_IN_FAILED,
        SUPPLY_TRANSFER_IN_NOT_POSSIBLE,
        SUPPORT_MARKET_OWNER_CHECK,
        SUPPORT_MARKET_PRICE_CHECK,
        SUSPEND_MARKET_OWNER_CHECK,
        WITHDRAW_ACCOUNT_LIQUIDITY_CALCULATION_FAILED,
        WITHDRAW_ACCOUNT_SHORTFALL_PRESENT,
        WITHDRAW_ACCUMULATED_BALANCE_CALCULATION_FAILED,
        WITHDRAW_AMOUNT_LIQUIDITY_SHORTFALL,
        WITHDRAW_AMOUNT_VALUE_CALCULATION_FAILED,
        WITHDRAW_CAPACITY_CALCULATION_FAILED,
        WITHDRAW_NEW_BORROW_INDEX_CALCULATION_FAILED,
        WITHDRAW_NEW_BORROW_RATE_CALCULATION_FAILED,
        WITHDRAW_NEW_SUPPLY_INDEX_CALCULATION_FAILED,
        WITHDRAW_NEW_SUPPLY_RATE_CALCULATION_FAILED,
        WITHDRAW_NEW_TOTAL_BALANCE_CALCULATION_FAILED,
        WITHDRAW_NEW_TOTAL_SUPPLY_CALCULATION_FAILED,
        WITHDRAW_TRANSFER_OUT_FAILED,
        WITHDRAW_TRANSFER_OUT_NOT_POSSIBLE
    }

    /**
     * @dev use this when reporting a known error from the money market or a non-upgradeable collaborator
     */
    function fail(Error err, FailureInfo info) internal returns (uint256) {
        emit Failure(uint256(err), uint256(info), 0);

        return uint256(err);
    }

    /**
     * @dev use this when reporting an opaque error from an upgradeable collaborator contract
     */
    function failOpaque(FailureInfo info, uint256 opaqueError) internal returns (uint256) {
        emit Failure(uint256(Error.OPAQUE_ERROR), uint256(info), opaqueError);

        return uint256(Error.OPAQUE_ERROR);
    }
}

contract CarefulMath is ErrorReporter {
    /**
     * @dev Multiplies two numbers, returns an error on overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (Error, uint256) {
        if (a == 0) {
            return (Error.NO_ERROR, 0);
        }

        uint256 c = a * b;

        if (c / a != b) {
            return (Error.INTEGER_OVERFLOW, 0);
        } else {
            return (Error.NO_ERROR, c);
        }
    }

    /**
     * @dev Integer division of two numbers, truncating the quotient.
     */
    function div(uint256 a, uint256 b) internal pure returns (Error, uint256) {
        if (b == 0) {
            return (Error.DIVISION_BY_ZERO, 0);
        }

        return (Error.NO_ERROR, a / b);
    }

    /**
     * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).
     */
    function sub(uint256 a, uint256 b) internal pure returns (Error, uint256) {
        if (b <= a) {
            return (Error.NO_ERROR, a - b);
        } else {
            return (Error.INTEGER_UNDERFLOW, 0);
        }
    }

    /**
     * @dev Adds two numbers, returns an error on overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (Error, uint256) {
        uint256 c = a + b;

        if (c >= a) {
            return (Error.NO_ERROR, c);
        } else {
            return (Error.INTEGER_OVERFLOW, 0);
        }
    }

    /**
     * @dev add a and b and then subtract c
     */
    function addThenSub(
        uint256 a,
        uint256 b,
        uint256 c
    ) internal pure returns (Error, uint256) {
        (Error err0, uint256 sum) = add(a, b);

        if (err0 != Error.NO_ERROR) {
            return (err0, 0);
        }

        return sub(sum, c);
    }
}

contract Exponential is ErrorReporter, CarefulMath {
    // TODO: We may wish to put the result of 10**18 here instead of the expression.
    // Per https://solidity.readthedocs.io/en/latest/contracts.html#constant-state-variables
    // the optimizer MAY replace the expression 10**18 with its calculated value.
    uint256 constant expScale = 10**18;

    // See TODO on expScale
    uint256 constant halfExpScale = expScale / 2;

    struct Exp {
        uint256 mantissa;
    }

    uint256 constant mantissaOne = 10**18;
    uint256 constant mantissaOneTenth = 10**17;

    /**
     * @dev Creates an exponential from numerator and denominator values.
     *      Note: Returns an error if (`num` * 10e18) > MAX_INT,
     *            or if `denom` is zero.
     */
    function getExp(uint256 num, uint256 denom) internal pure returns (Error, Exp memory) {
        (Error err0, uint256 scaledNumerator) = mul(num, expScale);
        if (err0 != Error.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }

        (Error err1, uint256 rational) = div(scaledNumerator, denom);
        if (err1 != Error.NO_ERROR) {
            return (err1, Exp({mantissa: 0}));
        }

        return (Error.NO_ERROR, Exp({mantissa: rational}));
    }

    /**
     * @dev Adds two exponentials, returning a new exponential.
     */
    function addExp(Exp memory a, Exp memory b) internal pure returns (Error, Exp memory) {
        (Error error, uint256 result) = add(a.mantissa, b.mantissa);

        return (error, Exp({mantissa: result}));
    }

    /**
     * @dev Subtracts two exponentials, returning a new exponential.
     */
    function subExp(Exp memory a, Exp memory b) internal pure returns (Error, Exp memory) {
        (Error error, uint256 result) = sub(a.mantissa, b.mantissa);

        return (error, Exp({mantissa: result}));
    }

    /**
     * @dev Multiply an Exp by a scalar, returning a new Exp.
     */
    function mulScalar(Exp memory a, uint256 scalar) internal pure returns (Error, Exp memory) {
        (Error err0, uint256 scaledMantissa) = mul(a.mantissa, scalar);
        if (err0 != Error.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }

        return (Error.NO_ERROR, Exp({mantissa: scaledMantissa}));
    }

    /**
     * @dev Divide an Exp by a scalar, returning a new Exp.
     */
    function divScalar(Exp memory a, uint256 scalar) internal pure returns (Error, Exp memory) {
        (Error err0, uint256 descaledMantissa) = div(a.mantissa, scalar);
        if (err0 != Error.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }

        return (Error.NO_ERROR, Exp({mantissa: descaledMantissa}));
    }

    /**
     * @dev Divide a scalar by an Exp, returning a new Exp.
     */
    function divScalarByExp(uint256 scalar, Exp memory divisor) internal pure returns (Error, Exp memory) {
        /*
            We are doing this as:
            getExp(mul(expScale, scalar), divisor.mantissa)

            How it works:
            Exp = a / b;
            Scalar = s;
            `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`
        */
        (Error err0, uint256 numerator) = mul(expScale, scalar);
        if (err0 != Error.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }
        return getExp(numerator, divisor.mantissa);
    }

    /**
     * @dev Multiplies two exponentials, returning a new exponential.
     */
    function mulExp(Exp memory a, Exp memory b) internal pure returns (Error, Exp memory) {
        (Error err0, uint256 doubleScaledProduct) = mul(a.mantissa, b.mantissa);
        if (err0 != Error.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }

        // We add half the scale before dividing so that we get rounding instead of truncation.
        //  See "Listing 6" and text above it at https://accu.org/index.php/journals/1717
        // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.
        (Error err1, uint256 doubleScaledProductWithHalfScale) = add(halfExpScale, doubleScaledProduct);
        if (err1 != Error.NO_ERROR) {
            return (err1, Exp({mantissa: 0}));
        }

        (Error err2, uint256 product) = div(doubleScaledProductWithHalfScale, expScale);
        // The only error `div` can return is Error.DIVISION_BY_ZERO but we control `expScale` and it is not zero.
        assert(err2 == Error.NO_ERROR);

        return (Error.NO_ERROR, Exp({mantissa: product}));
    }

    /**
     * @dev Divides two exponentials, returning a new exponential.
     *     (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,
     *  which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)
     */
    function divExp(Exp memory a, Exp memory b) internal pure returns (Error, Exp memory) {
        return getExp(a.mantissa, b.mantissa);
    }

    /**
     * @dev Truncates the given exp to a whole number value.
     *      For example, truncate(Exp{mantissa: 15 * (10**18)}) = 15
     */
    function truncate(Exp memory exp) internal pure returns (uint256) {
        // Note: We are not using careful math here as we're performing a division that cannot fail
        return exp.mantissa / 10**18;
    }

    /**
     * @dev Checks if first Exp is less than second Exp.
     */
    function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {
        return left.mantissa < right.mantissa; //TODO: Add some simple tests and this in another PR yo.
    }

    /**
     * @dev Checks if left Exp <= right Exp.
     */
    function lessThanOrEqualExp(Exp memory left, Exp memory right) internal pure returns (bool) {
        return left.mantissa <= right.mantissa;
    }

    /**
     * @dev Checks if first Exp is greater than second Exp.
     */
    function greaterThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {
        return left.mantissa > right.mantissa;
    }

    /**
     * @dev returns true if Exp is exactly zero
     */
    function isZeroExp(Exp memory value) internal pure returns (bool) {
        return value.mantissa == 0;
    }
}

contract PriceOracleV1 is Exponential {
    /**
     * @dev flag for whether or not contract is paused
     *
     */
    bool public paused;

    uint256 public constant numBlocksPerPeriod = 300; // approximately 1 hour: 60 seconds/minute * 60 minutes/hour * 1 block/12 seconds

    uint256 public constant maxSwingMantissa = (10**17); // 0.1

    /**
     * @dev Mapping of asset addresses and their corresponding price in terms of Eth-Wei
     *      which is simply equal to AssetWeiPrice * 10e18. For instance, if OMG token was
     *      worth 5x Eth then the price for OMG would be 5*10e18 or Exp({mantissa: 5000000000000000000}).
     * map: assetAddress -> Exp
     */
    mapping(address => Exp) public _assetPrices;

    constructor(address _poster) public {
        anchorAdmin = msg.sender;
        poster = _poster;
        maxSwing = Exp({mantissa: maxSwingMantissa});
    }

    /**
     * @notice Do not pay into PriceOracle
     */
    function() external payable {
        revert();
    }

    enum OracleError {
        NO_ERROR,
        UNAUTHORIZED,
        FAILED_TO_SET_PRICE
    }

    enum OracleFailureInfo {
        ACCEPT_ANCHOR_ADMIN_PENDING_ANCHOR_ADMIN_CHECK,
        SET_PAUSED_OWNER_CHECK,
        SET_PENDING_ANCHOR_ADMIN_OWNER_CHECK,
        SET_PENDING_ANCHOR_PERMISSION_CHECK,
        SET_PRICE_CALCULATE_SWING,
        SET_PRICE_CAP_TO_MAX,
        SET_PRICE_MAX_SWING_CHECK,
        SET_PRICE_NO_ANCHOR_PRICE_OR_INITIAL_PRICE_ZERO,
        SET_PRICE_PERMISSION_CHECK,
        SET_PRICE_ZERO_PRICE,
        SET_PRICES_PARAM_VALIDATION
    }

    /**
     * @dev `msgSender` is msg.sender; `error` corresponds to enum OracleError; `info` corresponds to enum OracleFailureInfo, and `detail` is an arbitrary
     * contract-specific code that enables us to report opaque error codes from upgradeable contracts.
     **/
    event OracleFailure(address msgSender, address asset, uint256 error, uint256 info, uint256 detail);

    /**
     * @dev use this when reporting a known error from the price oracle or a non-upgradeable collaborator
     *      Using Oracle in name because we already inherit a `fail` function from ErrorReporter.sol via Exponential.sol
     */
    function failOracle(
        address asset,
        OracleError err,
        OracleFailureInfo info
    ) internal returns (uint256) {
        emit OracleFailure(msg.sender, asset, uint256(err), uint256(info), 0);

        return uint256(err);
    }

    /**
     * @dev Use this when reporting an error from the money market. Give the money market result as `details`
     */
    function failOracleWithDetails(
        address asset,
        OracleError err,
        OracleFailureInfo info,
        uint256 details
    ) internal returns (uint256) {
        emit OracleFailure(msg.sender, asset, uint256(err), uint256(info), details);

        return uint256(err);
    }

    /**
     * @dev An administrator who can set the pending anchor value for assets.
     *      Set in the constructor.
     */
    address public anchorAdmin;

    /**
     * @dev pending anchor administrator for this contract.
     */
    address public pendingAnchorAdmin;

    /**
     * @dev Address of the price poster.
     *      Set in the constructor.
     */
    address public poster;

    /**
     * @dev maxSwing the maximum allowed percentage difference between a new price and the anchor's price
     *      Set only in the constructor
     */
    Exp public maxSwing;

    struct Anchor {
        // floor(block.number / numBlocksPerPeriod) + 1
        uint256 period;
        // Price in ETH, scaled by 10**18
        uint256 priceMantissa;
    }

    /**
     * @dev anchors by asset
     */
    mapping(address => Anchor) public anchors;

    /**
     * @dev pending anchor prices by asset
     */
    mapping(address => uint256) public pendingAnchors;

    /**
     * @dev emitted when a pending anchor is set
     * @param asset Asset for which to set a pending anchor
     * @param oldScaledPrice if an unused pending anchor was present, its value; otherwise 0.
     * @param newScaledPrice the new scaled pending anchor price
     */
    event NewPendingAnchor(address anchorAdmin, address asset, uint256 oldScaledPrice, uint256 newScaledPrice);

    /**
     * @notice provides ability to override the anchor price for an asset
     * @dev Admin function to set the anchor price for an asset
     * @param asset Asset for which to override the anchor price
     * @param newScaledPrice New anchor price
     * @return uint 0=success, otherwise a failure (see enum OracleError for details)
     */
    function _setPendingAnchor(address asset, uint256 newScaledPrice) public returns (uint256) {
        // Check caller = anchorAdmin. Note: Deliberately not allowing admin. They can just change anchorAdmin if desired.
        if (msg.sender != anchorAdmin) {
            return failOracle(asset, OracleError.UNAUTHORIZED, OracleFailureInfo.SET_PENDING_ANCHOR_PERMISSION_CHECK);
        }

        uint256 oldScaledPrice = pendingAnchors[asset];
        pendingAnchors[asset] = newScaledPrice;

        emit NewPendingAnchor(msg.sender, asset, oldScaledPrice, newScaledPrice);

        return uint256(OracleError.NO_ERROR);
    }

    /**
     * @dev emitted for all price changes
     */
    event PricePosted(
        address asset,
        uint256 previousPriceMantissa,
        uint256 requestedPriceMantissa,
        uint256 newPriceMantissa
    );

    /**
     * @dev emitted if this contract successfully posts a capped-to-max price to the money market
     */
    event CappedPricePosted(
        address asset,
        uint256 requestedPriceMantissa,
        uint256 anchorPriceMantissa,
        uint256 cappedPriceMantissa
    );

    /**
     * @dev emitted when admin either pauses or resumes the contract; newState is the resulting state
     */
    event SetPaused(bool newState);

    /**
     * @dev emitted when pendingAnchorAdmin is changed
     */
    event NewPendingAnchorAdmin(address oldPendingAnchorAdmin, address newPendingAnchorAdmin);

    /**
     * @dev emitted when pendingAnchorAdmin is accepted, which means anchor admin is updated
     */
    event NewAnchorAdmin(address oldAnchorAdmin, address newAnchorAdmin);

    /**
     * @notice set `paused` to the specified state
     * @dev Admin function to pause or resume the market
     * @param requestedState value to assign to `paused`
     * @return uint 0=success, otherwise a failure
     */
    function _setPaused(bool requestedState) public returns (uint256) {
        // Check caller = anchorAdmin
        if (msg.sender != anchorAdmin) {
            return failOracle(address(0), OracleError.UNAUTHORIZED, OracleFailureInfo.SET_PAUSED_OWNER_CHECK);
        }

        paused = requestedState;
        emit SetPaused(requestedState);

        return uint256(Error.NO_ERROR);
    }

    /**
     * @notice Begins transfer of anchor admin rights. The newPendingAnchorAdmin must call `_acceptAnchorAdmin` to finalize the transfer.
     * @dev Admin function to begin change of anchor admin. The newPendingAnchorAdmin must call `_acceptAnchorAdmin` to finalize the transfer.
     * @param newPendingAnchorAdmin New pending anchor admin.
     * @return uint 0=success, otherwise a failure
     *
     * TODO: Should we add a second arg to verify, like a checksum of `newAnchorAdmin` address?
     */
    function _setPendingAnchorAdmin(address newPendingAnchorAdmin) public returns (uint256) {
        // Check caller = anchorAdmin
        if (msg.sender != anchorAdmin) {
            return
                failOracle(
                    address(0),
                    OracleError.UNAUTHORIZED,
                    OracleFailureInfo.SET_PENDING_ANCHOR_ADMIN_OWNER_CHECK
                );
        }

        // save current value, if any, for inclusion in log
        address oldPendingAnchorAdmin = pendingAnchorAdmin;
        // Store pendingAdmin = newPendingAdmin
        pendingAnchorAdmin = newPendingAnchorAdmin;

        emit NewPendingAnchorAdmin(oldPendingAnchorAdmin, newPendingAnchorAdmin);

        return uint256(Error.NO_ERROR);
    }

    /**
     * @notice Accepts transfer of anchor admin rights. msg.sender must be pendingAnchorAdmin
     * @dev Admin function for pending anchor admin to accept role and update anchor admin
     * @return uint 0=success, otherwise a failure
     */
    function _acceptAnchorAdmin() public returns (uint256) {
        // Check caller = pendingAnchorAdmin
        // msg.sender can't be zero
        if (msg.sender != pendingAnchorAdmin) {
            return
                failOracle(
                    address(0),
                    OracleError.UNAUTHORIZED,
                    OracleFailureInfo.ACCEPT_ANCHOR_ADMIN_PENDING_ANCHOR_ADMIN_CHECK
                );
        }

        // Save current value for inclusion in log
        address oldAnchorAdmin = anchorAdmin;
        // Store admin = pendingAnchorAdmin
        anchorAdmin = pendingAnchorAdmin;
        // Clear the pending value
        pendingAnchorAdmin = address(0);

        emit NewAnchorAdmin(oldAnchorAdmin, msg.sender);

        return uint256(Error.NO_ERROR);
    }

    /**
     * @notice retrieves price of an asset
     * @dev function to get price for an asset
     * @param asset Asset for which to get the price
     * @return uint mantissa of asset price (scaled by 1e18) or zero if unset or contract paused
     */
    function assetPrices(address asset) public view returns (uint256) {
        // Note: zero is treated by the money market as an invalid
        //       price and will cease operations with that asset
        //       when zero.
        //
        // We get the price as:
        //
        //  1. If the contract is paused, return 0.
        //  2. Return price in `_assetPrices`, which may be zero.

        if (paused) {
            return 0;
        }
        return _assetPrices[asset].mantissa;
    }

    /**
     * @notice retrieves price of an asset
     * @dev function to get price for an asset
     * @param asset Asset for which to get the price
     * @return uint mantissa of asset price (scaled by 1e18) or zero if unset or contract paused
     */
    function getPrice(address asset) public view returns (uint256) {
        return assetPrices(asset);
    }

    struct SetPriceLocalVars {
        Exp price;
        Exp swing;
        Exp anchorPrice;
        uint256 anchorPeriod;
        uint256 currentPeriod;
        bool priceCapped;
        uint256 cappingAnchorPriceMantissa;
        uint256 pendingAnchorMantissa;
    }

    /**
     * @notice entry point for updating prices
     * @dev function to set price for an asset
     * @param asset Asset for which to set the price
     * @param requestedPriceMantissa requested new price, scaled by 10**18
     * @return uint 0=success, otherwise a failure (see enum OracleError for details)
     */
    function setPrice(address asset, uint256 requestedPriceMantissa) public returns (uint256) {
        // Fail when msg.sender is not poster
        if (msg.sender != poster) {
            return failOracle(asset, OracleError.UNAUTHORIZED, OracleFailureInfo.SET_PRICE_PERMISSION_CHECK);
        }

        return setPriceInternal(asset, requestedPriceMantissa);
    }

    function setPriceInternal(address asset, uint256 requestedPriceMantissa) internal returns (uint256) {
        // re-used for intermediate errors
        Error err;
        SetPriceLocalVars memory localVars;
        // We add 1 for currentPeriod so that it can never be zero and there's no ambiguity about an unset value.
        // (It can be a problem in tests with low block numbers.)
        localVars.currentPeriod = (block.number / numBlocksPerPeriod) + 1;
        localVars.pendingAnchorMantissa = pendingAnchors[asset];
        localVars.price = Exp({mantissa: requestedPriceMantissa});

        if (localVars.pendingAnchorMantissa != 0) {
            // let's explicitly set to 0 rather than relying on default of declaration
            localVars.anchorPeriod = 0;
            localVars.anchorPrice = Exp({mantissa: localVars.pendingAnchorMantissa});

            // Verify movement is within max swing of pending anchor (currently: 10%)
            (err, localVars.swing) = calculateSwing(localVars.anchorPrice, localVars.price);
            if (err != Error.NO_ERROR) {
                return
                    failOracleWithDetails(
                        asset,
                        OracleError.FAILED_TO_SET_PRICE,
                        OracleFailureInfo.SET_PRICE_CALCULATE_SWING,
                        uint256(err)
                    );
            }

            // Fail when swing > maxSwing
            if (greaterThanExp(localVars.swing, maxSwing)) {
                return
                    failOracleWithDetails(
                        asset,
                        OracleError.FAILED_TO_SET_PRICE,
                        OracleFailureInfo.SET_PRICE_MAX_SWING_CHECK,
                        localVars.swing.mantissa
                    );
            }
        } else {
            localVars.anchorPeriod = anchors[asset].period;
            localVars.anchorPrice = Exp({mantissa: anchors[asset].priceMantissa});

            if (localVars.anchorPeriod != 0) {
                (err, localVars.priceCapped, localVars.price) = capToMax(localVars.anchorPrice, localVars.price);
                if (err != Error.NO_ERROR) {
                    return
                        failOracleWithDetails(
                            asset,
                            OracleError.FAILED_TO_SET_PRICE,
                            OracleFailureInfo.SET_PRICE_CAP_TO_MAX,
                            uint256(err)
                        );
                }
                if (localVars.priceCapped) {
                    // save for use in log
                    localVars.cappingAnchorPriceMantissa = localVars.anchorPrice.mantissa;
                }
            } else {
                // Setting first price. Accept as is (already assigned above from requestedPriceMantissa) and use as anchor
                localVars.anchorPrice = Exp({mantissa: requestedPriceMantissa});
            }
        }

        // Fail if anchorPrice or price is zero.
        // zero anchor represents an unexpected situation likely due to a problem in this contract
        // zero price is more likely as the result of bad input from the caller of this function
        if (isZeroExp(localVars.anchorPrice)) {
            // If we get here price could also be zero, but it does not seem worthwhile to distinguish the 3rd case
            return
                failOracle(
                    asset,
                    OracleError.FAILED_TO_SET_PRICE,
                    OracleFailureInfo.SET_PRICE_NO_ANCHOR_PRICE_OR_INITIAL_PRICE_ZERO
                );
        }

        if (isZeroExp(localVars.price)) {
            return failOracle(asset, OracleError.FAILED_TO_SET_PRICE, OracleFailureInfo.SET_PRICE_ZERO_PRICE);
        }

        // BEGIN SIDE EFFECTS

        // Set pendingAnchor = Nothing
        // Pending anchor is only used once.
        if (pendingAnchors[asset] != 0) {
            pendingAnchors[asset] = 0;
        }

        // If currentPeriod > anchorPeriod:
        //  Set anchors[asset] = (currentPeriod, price)
        //  The new anchor is if we're in a new period or we had a pending anchor, then we become the new anchor
        if (localVars.currentPeriod > localVars.anchorPeriod) {
            anchors[asset] = Anchor({period: localVars.currentPeriod, priceMantissa: localVars.price.mantissa});
        }

        uint256 previousPrice = _assetPrices[asset].mantissa;

        setPriceStorageInternal(asset, localVars.price.mantissa);

        emit PricePosted(asset, previousPrice, requestedPriceMantissa, localVars.price.mantissa);

        if (localVars.priceCapped) {
            // We have set a capped price. Log it so we can detect the situation and investigate.
            emit CappedPricePosted(
                asset,
                requestedPriceMantissa,
                localVars.cappingAnchorPriceMantissa,
                localVars.price.mantissa
            );
        }

        return uint256(OracleError.NO_ERROR);
    }

    // As a function to allow harness overrides
    function setPriceStorageInternal(address asset, uint256 priceMantissa) internal {
        _assetPrices[asset] = Exp({mantissa: priceMantissa});
    }

    // abs(price - anchorPrice) / anchorPrice
    function calculateSwing(Exp memory anchorPrice, Exp memory price) internal pure returns (Error, Exp memory) {
        Exp memory numerator;
        Error err;

        if (greaterThanExp(anchorPrice, price)) {
            (err, numerator) = subExp(anchorPrice, price);
            // can't underflow
            assert(err == Error.NO_ERROR);
        } else {
            (err, numerator) = subExp(price, anchorPrice);
            // Given greaterThan check above, price >= anchorPrice so can't underflow.
            assert(err == Error.NO_ERROR);
        }

        return divExp(numerator, anchorPrice);
    }

    function capToMax(Exp memory anchorPrice, Exp memory price)
        internal
        view
        returns (
            Error,
            bool,
            Exp memory
        )
    {
        Exp memory one = Exp({mantissa: mantissaOne});
        Exp memory onePlusMaxSwing;
        Exp memory oneMinusMaxSwing;
        Exp memory max;
        Exp memory min;
        // re-used for intermediate errors
        Error err;

        (err, onePlusMaxSwing) = addExp(one, maxSwing);
        if (err != Error.NO_ERROR) {
            return (err, false, Exp({mantissa: 0}));
        }

        // max = anchorPrice * (1 + maxSwing)
        (err, max) = mulExp(anchorPrice, onePlusMaxSwing);
        if (err != Error.NO_ERROR) {
            return (err, false, Exp({mantissa: 0}));
        }

        // If price > anchorPrice * (1 + maxSwing)
        // Set price = anchorPrice * (1 + maxSwing)
        if (greaterThanExp(price, max)) {
            return (Error.NO_ERROR, true, max);
        }

        (err, oneMinusMaxSwing) = subExp(one, maxSwing);
        if (err != Error.NO_ERROR) {
            return (err, false, Exp({mantissa: 0}));
        }

        // min = anchorPrice * (1 - maxSwing)
        (err, min) = mulExp(anchorPrice, oneMinusMaxSwing);
        // We can't overflow here or we would have already overflowed above when calculating `max`
        assert(err == Error.NO_ERROR);

        // If  price < anchorPrice * (1 - maxSwing)
        // Set price = anchorPrice * (1 - maxSwing)
        if (lessThanExp(price, min)) {
            return (Error.NO_ERROR, true, min);
        }

        return (Error.NO_ERROR, false, price);
    }

    /**
     * @notice entry point for updating multiple prices
     * @dev function to set prices for a variable number of assets.
     * @param assets a list of up to assets for which to set a price. required: 0 < assets.length == requestedPriceMantissas.length
     * @param requestedPriceMantissas requested new prices for the assets, scaled by 10**18. required: 0 < assets.length == requestedPriceMantissas.length
     * @return uint values in same order as inputs. For each: 0=success, otherwise a failure (see enum OracleError for details)
     */
    function setPrices(address[] memory assets, uint256[] memory requestedPriceMantissas)
        public
        returns (uint256[] memory)
    {
        uint256 numAssets = assets.length;
        uint256 numPrices = requestedPriceMantissas.length;
        uint256[] memory result;

        // Fail when msg.sender is not poster
        if (msg.sender != poster) {
            result = new uint256[](1);
            result[0] = failOracle(address(0), OracleError.UNAUTHORIZED, OracleFailureInfo.SET_PRICE_PERMISSION_CHECK);
            return result;
        }

        if ((numAssets == 0) || (numPrices != numAssets)) {
            result = new uint256[](1);
            result[0] = failOracle(
                address(0),
                OracleError.FAILED_TO_SET_PRICE,
                OracleFailureInfo.SET_PRICES_PARAM_VALIDATION
            );
            return result;
        }

        result = new uint256[](numAssets);

        for (uint256 i = 0; i < numAssets; i++) {
            result[i] = setPriceInternal(assets[i], requestedPriceMantissas[i]);
        }

        return result;
    }
}

Settings
{
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_poster","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"requestedPriceMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"anchorPriceMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cappedPriceMantissa","type":"uint256"}],"name":"CappedPricePosted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"error","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"info","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"detail","type":"uint256"}],"name":"Failure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAnchorAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAnchorAdmin","type":"address"}],"name":"NewAnchorAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"anchorAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldScaledPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newScaledPrice","type":"uint256"}],"name":"NewPendingAnchor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPendingAnchorAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newPendingAnchorAdmin","type":"address"}],"name":"NewPendingAnchorAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"msgSender","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"error","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"info","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"detail","type":"uint256"}],"name":"OracleFailure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousPriceMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestedPriceMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPriceMantissa","type":"uint256"}],"name":"PricePosted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newState","type":"bool"}],"name":"SetPaused","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[],"name":"_acceptAnchorAdmin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_assetPrices","outputs":[{"internalType":"uint256","name":"mantissa","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"requestedState","type":"bool"}],"name":"_setPaused","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"newScaledPrice","type":"uint256"}],"name":"_setPendingAnchor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newPendingAnchorAdmin","type":"address"}],"name":"_setPendingAnchorAdmin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"anchorAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"anchors","outputs":[{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"priceMantissa","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"assetPrices","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxSwing","outputs":[{"internalType":"uint256","name":"mantissa","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxSwingMantissa","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"numBlocksPerPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingAnchorAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pendingAnchors","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"poster","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"requestedPriceMantissa","type":"uint256"}],"name":"setPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"requestedPriceMantissas","type":"uint256[]"}],"name":"setPrices","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506040516114b63803806114b68339818101604052602081101561003357600080fd5b505160028054336001600160a01b031991821617909155600480549091166001600160a01b03909216919091179055604080516020810190915267016345785d8a00009081905260055561142a8061008c6000396000f3fe6080604052600436106101085760003560e01c80635c975abb116100955780639964622c116100645780639964622c1461049b5780639e8c4d95146104ce578063c5faf1d514610501578063ccb13cbd14610516578063de9d0e851461052b57610108565b80635c975abb146103de5780635e9a523c14610407578063692374e31461043a578063809597211461048657610108565b806326617c28116100dc57806326617c28146101d157806341976e09146101fd5780634352fa9f14610230578063451b1e3a146103b4578063485feabe146103c957610108565b8062e4768b1461010d57806308f31857146101585780630c9c630114610189578063183f34441461019e575b600080fd5b34801561011957600080fd5b506101466004803603604081101561013057600080fd5b506001600160a01b038135169060200135610564565b60408051918252519081900360200190f35b34801561016457600080fd5b5061016d6105a0565b604080516001600160a01b039092168252519081900360200190f35b34801561019557600080fd5b506101466105af565b3480156101aa57600080fd5b50610146600480360360208110156101c157600080fd5b50356001600160a01b03166105bb565b3480156101dd57600080fd5b50610146600480360360208110156101f457600080fd5b503515156105cd565b34801561020957600080fd5b506101466004803603602081101561022057600080fd5b50356001600160a01b0316610645565b34801561023c57600080fd5b506103646004803603604081101561025357600080fd5b81019060208101813564010000000081111561026e57600080fd5b82018360208201111561028057600080fd5b803590602001918460208302840111640100000000831117156102a257600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156102f257600080fd5b82018360208201111561030457600080fd5b8035906020019184602083028401116401000000008311171561032657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610650945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a0578181015183820152602001610388565b505050509050019250505060405180910390f35b3480156103c057600080fd5b5061016d61078e565b3480156103d557600080fd5b5061014661079d565b3480156103ea57600080fd5b506103f36107a3565b604080519115158252519081900360200190f35b34801561041357600080fd5b506101466004803603602081101561042a57600080fd5b50356001600160a01b03166107ac565b34801561044657600080fd5b5061046d6004803603602081101561045d57600080fd5b50356001600160a01b03166107dc565b6040805192835260208301919091528051918290030190f35b34801561049257600080fd5b5061016d6107f5565b3480156104a757600080fd5b50610146600480360360208110156104be57600080fd5b50356001600160a01b0316610804565b3480156104da57600080fd5b50610146600480360360208110156104f157600080fd5b50356001600160a01b031661088f565b34801561050d57600080fd5b506101466108a1565b34801561052257600080fd5b506101466108a7565b34801561053757600080fd5b506101466004803603604081101561054e57600080fd5b506001600160a01b038135169060200135610941565b6004546000906001600160a01b0316331461058d5761058683600160086109d4565b905061059a565b6105978383610a5d565b90505b92915050565b6002546001600160a01b031681565b67016345785d8a000081565b60016020526000908152604090205481565b6002546000906001600160a01b031633146105f6576105ef60006001806109d4565b9050610640565b6000805483151560ff19909116811790915560408051918252517f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b59809181900360200190a160005b90505b919050565b600061063d826107ac565b81518151600454606092919083906001600160a01b031633146106bd57604080516001808252818301909252906020808301908038833901905050905061069b6000600160086109d4565b816000815181106106a857fe5b6020908102919091010152925061059a915050565b8215806106ca5750828214155b156106fd57604080516001808252818301909252906020808301908038833901905050905061069b60006002600a6109d4565b82604051908082528060200260200182016040528015610727578160200160208202803883390190505b50905060005b838110156107845761076587828151811061074457fe5b602002602001015187838151811061075857fe5b6020026020010151610a5d565b82828151811061077157fe5b602090810291909101015260010161072d565b5095945050505050565b6003546001600160a01b031681565b61012c81565b60005460ff1681565b6000805460ff16156107c057506000610640565b506001600160a01b031660009081526001602052604090205490565b6006602052600090815260409020805460019091015482565b6004546001600160a01b031681565b6002546000906001600160a01b03163314610827576105ef6000600160026109d4565b600380546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517f6c773973d5bcf264b509f4194ceb99e891251f6aabb325523a863c282958b13e929181900390910190a160009392505050565b60076020526000908152604090205481565b60055481565b6003546000906001600160a01b031633146108d1576108ca6000600160006109d4565b905061093e565b60028054600380546001600160a01b03198084166001600160a01b03838116919091179095551690556040805192909116808352336020840152815190927fbef9248fe57ae972dd47833f68c43f0b3b2d14217612dfbc804a520a23730d4692908290030190a160009150505b90565b6002546000906001600160a01b031633146109635761058683600160036109d4565b6001600160a01b0383166000818152600760209081526040918290208054908690558251338152918201939093528082018390526060810185905290517ff0aa20c29c1f8e751bfe0a78bc49a520ed14f2dab274087d90d1341d8b76af5c9181900360800190a16000949350505050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73385856002811115610a0557fe5b85600a811115610a1157fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526000608082015290519081900360a00190a1826002811115610a5557fe5b949350505050565b600080610a68611389565b61012c430460010160808201526001600160a01b0385166000908152600760209081526040918290205460e08401908152825191820190925285815282525115610b4f57600060608201526040805160208101825260e083015181529082018190528151610ad69190610db4565b602083015291506000826017811115610aeb57fe5b14610b1257610b098560026004856017811115610b0457fe5b610e3a565b9250505061059a565b6020808201516040805192830190526005548252610b2f91610ec4565b15610b4a57610b098560026006846020015160000151610e3a565b610c06565b6001600160a01b038516600081815260066020818152604080842080546060880190815282518085018452969095529290915260019091015483528301919091525115610bf457610ba881604001518260000151610ecb565b8352151560a083015291506000826017811115610bc157fe5b14610bda57610b098560026005856017811115610b0457fe5b8060a0015115610b4a5760408101515160c0820152610c06565b60408051602081018252858152908201525b610c13816040015161108a565b15610c2557610b0985600260076109d4565b8051610c309061108a565b15610c4257610b0985600260096109d4565b6001600160a01b03851660009081526007602052604090205415610c7a576001600160a01b0385166000908152600760205260408120555b806060015181608001511115610cca576040805180820182526080830151815282515160208083019182526001600160a01b03891660009081526006909152929092209051815590516001909101555b6001600160a01b038516600090815260016020526040902054815151610cf190879061108f565b815151604080516001600160a01b0389168152602081018490528082018890526060810192909252517fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae79181900360800190a18160a0015115610da85760c0820151825151604080516001600160a01b038a16815260208101899052808201939093526060830191909152517f7221f7a2708437039cc63319145b6b873a40594b9782a3bee45b975e2f3b0f689181900360800190a15b60009695505050505050565b6000610dbe6113e2565b610dc66113e2565b6000610dd28686610ec4565b15610dff57610de186866110ba565b925090506000816017811115610df357fe5b14610dfa57fe5b610e22565b610e0985876110ba565b925090506000816017811115610e1b57fe5b14610e2257fe5b610e2c82876110f4565b9350935050505b9250929050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73386866002811115610e6b57fe5b86600a811115610e7757fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526080810185905290519081900360a00190a1836002811115610ebb57fe5b95945050505050565b5190511190565b600080610ed66113e2565b610ede6113e2565b506040805160208101909152670de0b6b3a76400008152610efd6113e2565b610f056113e2565b610f0d6113e2565b610f156113e2565b60408051602081019091526005548152600090610f33908790611117565b955090506000816017811115610f4557fe5b14610f6d57604080516020810190915260008082529199509097509550611083945050505050565b610f778b86611136565b935090506000816017811115610f8957fe5b14610fb157604080516020810190915260008082529199509097509550611083945050505050565b610fbb8a84610ec4565b15610fd6576000600184985098509850505050505050611083565b60408051602081019091526005548152610ff19087906110ba565b94509050600081601781111561100357fe5b1461102b57604080516020810190915260008082529199509097509550611083945050505050565b6110358b85611136565b92509050600081601781111561104757fe5b1461104e57fe5b6110588a8361121f565b156110725750600097506001965094506110839350505050565b6000808b9850985098505050505050505b9250925092565b511590565b60408051602080820183529281526001600160a01b0390931660009081526001909252902090519055565b60006110c46113e2565b6000806110d986600001518660000151611226565b60408051602081019091529081529097909650945050505050565b60006110fe6113e2565b8351835161110c9190611249565b915091509250929050565b60006111216113e2565b6000806110d9866000015186600001516112f9565b60006111406113e2565b6000806111558660000151866000015161131f565b9092509050600082601781111561116857fe5b1461118757506040805160208101909152600081529092509050610e33565b60008061119c6706f05b59d3b20000846112f9565b909250905060008260178111156111af57fe5b146111d157506040805160208101909152600081529094509250610e33915050565b6000806111e683670de0b6b3a764000061135e565b909250905060008260178111156111f957fe5b1461120057fe5b604080516020810190915290815260009a909950975050505050505050565b5190511090565b60008083831161123d575060009050818303610e33565b50600490506000610e33565b60006112536113e2565b60008061126886670de0b6b3a764000061131f565b9092509050600082601781111561127b57fe5b1461129a57506040805160208101909152600081529092509050610e33565b6000806112a7838861135e565b909250905060008260178111156112ba57fe5b146112dc57506040805160208101909152600081529094509250610e33915050565b604080516020810190915290815260009890975095505050505050565b60008083830184811061131157600092509050610e33565b506003915060009050610e33565b6000808361133257506000905080610e33565b8383028385828161133f57fe5b041461135357506003915060009050610e33565b600092509050610e33565b600080826113725750600590506000610e33565b600083858161137d57fe5b04915091509250929050565b60405180610100016040528061139d6113e2565b81526020016113aa6113e2565b81526020016113b76113e2565b8152602001600081526020016000815260200160001515815260200160008152602001600081525090565b604051806020016040528060008152509056fea265627a7a72315820a18570e049204ad2b12731fbd842659e4986502c5882b5f0d5f8b30aed5bcd5164736f6c63430005110032000000000000000000000000d830a7413cb25fee57f8115cd64e565b0be466c3

Deployed Bytecode

0x6080604052600436106101085760003560e01c80635c975abb116100955780639964622c116100645780639964622c1461049b5780639e8c4d95146104ce578063c5faf1d514610501578063ccb13cbd14610516578063de9d0e851461052b57610108565b80635c975abb146103de5780635e9a523c14610407578063692374e31461043a578063809597211461048657610108565b806326617c28116100dc57806326617c28146101d157806341976e09146101fd5780634352fa9f14610230578063451b1e3a146103b4578063485feabe146103c957610108565b8062e4768b1461010d57806308f31857146101585780630c9c630114610189578063183f34441461019e575b600080fd5b34801561011957600080fd5b506101466004803603604081101561013057600080fd5b506001600160a01b038135169060200135610564565b60408051918252519081900360200190f35b34801561016457600080fd5b5061016d6105a0565b604080516001600160a01b039092168252519081900360200190f35b34801561019557600080fd5b506101466105af565b3480156101aa57600080fd5b50610146600480360360208110156101c157600080fd5b50356001600160a01b03166105bb565b3480156101dd57600080fd5b50610146600480360360208110156101f457600080fd5b503515156105cd565b34801561020957600080fd5b506101466004803603602081101561022057600080fd5b50356001600160a01b0316610645565b34801561023c57600080fd5b506103646004803603604081101561025357600080fd5b81019060208101813564010000000081111561026e57600080fd5b82018360208201111561028057600080fd5b803590602001918460208302840111640100000000831117156102a257600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156102f257600080fd5b82018360208201111561030457600080fd5b8035906020019184602083028401116401000000008311171561032657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610650945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a0578181015183820152602001610388565b505050509050019250505060405180910390f35b3480156103c057600080fd5b5061016d61078e565b3480156103d557600080fd5b5061014661079d565b3480156103ea57600080fd5b506103f36107a3565b604080519115158252519081900360200190f35b34801561041357600080fd5b506101466004803603602081101561042a57600080fd5b50356001600160a01b03166107ac565b34801561044657600080fd5b5061046d6004803603602081101561045d57600080fd5b50356001600160a01b03166107dc565b6040805192835260208301919091528051918290030190f35b34801561049257600080fd5b5061016d6107f5565b3480156104a757600080fd5b50610146600480360360208110156104be57600080fd5b50356001600160a01b0316610804565b3480156104da57600080fd5b50610146600480360360208110156104f157600080fd5b50356001600160a01b031661088f565b34801561050d57600080fd5b506101466108a1565b34801561052257600080fd5b506101466108a7565b34801561053757600080fd5b506101466004803603604081101561054e57600080fd5b506001600160a01b038135169060200135610941565b6004546000906001600160a01b0316331461058d5761058683600160086109d4565b905061059a565b6105978383610a5d565b90505b92915050565b6002546001600160a01b031681565b67016345785d8a000081565b60016020526000908152604090205481565b6002546000906001600160a01b031633146105f6576105ef60006001806109d4565b9050610640565b6000805483151560ff19909116811790915560408051918252517f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b59809181900360200190a160005b90505b919050565b600061063d826107ac565b81518151600454606092919083906001600160a01b031633146106bd57604080516001808252818301909252906020808301908038833901905050905061069b6000600160086109d4565b816000815181106106a857fe5b6020908102919091010152925061059a915050565b8215806106ca5750828214155b156106fd57604080516001808252818301909252906020808301908038833901905050905061069b60006002600a6109d4565b82604051908082528060200260200182016040528015610727578160200160208202803883390190505b50905060005b838110156107845761076587828151811061074457fe5b602002602001015187838151811061075857fe5b6020026020010151610a5d565b82828151811061077157fe5b602090810291909101015260010161072d565b5095945050505050565b6003546001600160a01b031681565b61012c81565b60005460ff1681565b6000805460ff16156107c057506000610640565b506001600160a01b031660009081526001602052604090205490565b6006602052600090815260409020805460019091015482565b6004546001600160a01b031681565b6002546000906001600160a01b03163314610827576105ef6000600160026109d4565b600380546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517f6c773973d5bcf264b509f4194ceb99e891251f6aabb325523a863c282958b13e929181900390910190a160009392505050565b60076020526000908152604090205481565b60055481565b6003546000906001600160a01b031633146108d1576108ca6000600160006109d4565b905061093e565b60028054600380546001600160a01b03198084166001600160a01b03838116919091179095551690556040805192909116808352336020840152815190927fbef9248fe57ae972dd47833f68c43f0b3b2d14217612dfbc804a520a23730d4692908290030190a160009150505b90565b6002546000906001600160a01b031633146109635761058683600160036109d4565b6001600160a01b0383166000818152600760209081526040918290208054908690558251338152918201939093528082018390526060810185905290517ff0aa20c29c1f8e751bfe0a78bc49a520ed14f2dab274087d90d1341d8b76af5c9181900360800190a16000949350505050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73385856002811115610a0557fe5b85600a811115610a1157fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526000608082015290519081900360a00190a1826002811115610a5557fe5b949350505050565b600080610a68611389565b61012c430460010160808201526001600160a01b0385166000908152600760209081526040918290205460e08401908152825191820190925285815282525115610b4f57600060608201526040805160208101825260e083015181529082018190528151610ad69190610db4565b602083015291506000826017811115610aeb57fe5b14610b1257610b098560026004856017811115610b0457fe5b610e3a565b9250505061059a565b6020808201516040805192830190526005548252610b2f91610ec4565b15610b4a57610b098560026006846020015160000151610e3a565b610c06565b6001600160a01b038516600081815260066020818152604080842080546060880190815282518085018452969095529290915260019091015483528301919091525115610bf457610ba881604001518260000151610ecb565b8352151560a083015291506000826017811115610bc157fe5b14610bda57610b098560026005856017811115610b0457fe5b8060a0015115610b4a5760408101515160c0820152610c06565b60408051602081018252858152908201525b610c13816040015161108a565b15610c2557610b0985600260076109d4565b8051610c309061108a565b15610c4257610b0985600260096109d4565b6001600160a01b03851660009081526007602052604090205415610c7a576001600160a01b0385166000908152600760205260408120555b806060015181608001511115610cca576040805180820182526080830151815282515160208083019182526001600160a01b03891660009081526006909152929092209051815590516001909101555b6001600160a01b038516600090815260016020526040902054815151610cf190879061108f565b815151604080516001600160a01b0389168152602081018490528082018890526060810192909252517fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae79181900360800190a18160a0015115610da85760c0820151825151604080516001600160a01b038a16815260208101899052808201939093526060830191909152517f7221f7a2708437039cc63319145b6b873a40594b9782a3bee45b975e2f3b0f689181900360800190a15b60009695505050505050565b6000610dbe6113e2565b610dc66113e2565b6000610dd28686610ec4565b15610dff57610de186866110ba565b925090506000816017811115610df357fe5b14610dfa57fe5b610e22565b610e0985876110ba565b925090506000816017811115610e1b57fe5b14610e2257fe5b610e2c82876110f4565b9350935050505b9250929050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73386866002811115610e6b57fe5b86600a811115610e7757fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526080810185905290519081900360a00190a1836002811115610ebb57fe5b95945050505050565b5190511190565b600080610ed66113e2565b610ede6113e2565b506040805160208101909152670de0b6b3a76400008152610efd6113e2565b610f056113e2565b610f0d6113e2565b610f156113e2565b60408051602081019091526005548152600090610f33908790611117565b955090506000816017811115610f4557fe5b14610f6d57604080516020810190915260008082529199509097509550611083945050505050565b610f778b86611136565b935090506000816017811115610f8957fe5b14610fb157604080516020810190915260008082529199509097509550611083945050505050565b610fbb8a84610ec4565b15610fd6576000600184985098509850505050505050611083565b60408051602081019091526005548152610ff19087906110ba565b94509050600081601781111561100357fe5b1461102b57604080516020810190915260008082529199509097509550611083945050505050565b6110358b85611136565b92509050600081601781111561104757fe5b1461104e57fe5b6110588a8361121f565b156110725750600097506001965094506110839350505050565b6000808b9850985098505050505050505b9250925092565b511590565b60408051602080820183529281526001600160a01b0390931660009081526001909252902090519055565b60006110c46113e2565b6000806110d986600001518660000151611226565b60408051602081019091529081529097909650945050505050565b60006110fe6113e2565b8351835161110c9190611249565b915091509250929050565b60006111216113e2565b6000806110d9866000015186600001516112f9565b60006111406113e2565b6000806111558660000151866000015161131f565b9092509050600082601781111561116857fe5b1461118757506040805160208101909152600081529092509050610e33565b60008061119c6706f05b59d3b20000846112f9565b909250905060008260178111156111af57fe5b146111d157506040805160208101909152600081529094509250610e33915050565b6000806111e683670de0b6b3a764000061135e565b909250905060008260178111156111f957fe5b1461120057fe5b604080516020810190915290815260009a909950975050505050505050565b5190511090565b60008083831161123d575060009050818303610e33565b50600490506000610e33565b60006112536113e2565b60008061126886670de0b6b3a764000061131f565b9092509050600082601781111561127b57fe5b1461129a57506040805160208101909152600081529092509050610e33565b6000806112a7838861135e565b909250905060008260178111156112ba57fe5b146112dc57506040805160208101909152600081529094509250610e33915050565b604080516020810190915290815260009890975095505050505050565b60008083830184811061131157600092509050610e33565b506003915060009050610e33565b6000808361133257506000905080610e33565b8383028385828161133f57fe5b041461135357506003915060009050610e33565b600092509050610e33565b600080826113725750600590506000610e33565b600083858161137d57fe5b04915091509250929050565b60405180610100016040528061139d6113e2565b81526020016113aa6113e2565b81526020016113b76113e2565b8152602001600081526020016000815260200160001515815260200160008152602001600081525090565b604051806020016040528060008152509056fea265627a7a72315820a18570e049204ad2b12731fbd842659e4986502c5882b5f0d5f8b30aed5bcd5164736f6c63430005110032

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

000000000000000000000000d830a7413cb25fee57f8115cd64e565b0be466c3

-----Decoded View---------------
Arg [0] : _poster (address): 0xd830A7413CB25FEe57f8115CD64E565B0Be466c3

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d830a7413cb25fee57f8115cd64e565b0be466c3


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.