APE Price: $0.95 (+2.62%)

Contract

0x0c449E0B7B700C3dF2249184589d60250Dc43aDb

Overview

APE Balance

Apechain LogoApechain LogoApechain Logo0 APE

APE Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Prices89788622025-01-30 8:36:0322 mins ago1738226163IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975325.42069
Set Prices89772002025-01-30 7:36:031 hr ago1738222563IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972525.42069
Set Prices89756702025-01-30 6:36:012 hrs ago1738218961IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972825.42069
Set Prices89741582025-01-30 5:35:563 hrs ago1738215356IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972825.42069
Set Prices89727022025-01-30 4:35:534 hrs ago1738211753IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975825.42069
Set Prices89711262025-01-30 3:35:515 hrs ago1738208151IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89697692025-01-30 2:35:496 hrs ago1738204549IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89683072025-01-30 1:35:447 hrs ago1738200944IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975825.42069
Set Prices89668682025-01-30 0:35:418 hrs ago1738197341IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975825.42069
Set Prices89651472025-01-29 23:35:389 hrs ago1738193738IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89632532025-01-29 22:35:3310 hrs ago1738190133IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89614702025-01-29 21:35:3011 hrs ago1738186530IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972525.42069
Set Prices89593412025-01-29 20:35:2912 hrs ago1738182929IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89571152025-01-29 19:35:2513 hrs ago1738179325IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972325.42069
Set Prices89553422025-01-29 18:35:2514 hrs ago1738175725IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89537322025-01-29 17:35:2015 hrs ago1738172120IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89520672025-01-29 16:35:1916 hrs ago1738168519IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975825.42069
Set Prices89504592025-01-29 15:34:3617 hrs ago1738164876IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89487132025-01-29 14:34:3418 hrs ago1738161274IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89466442025-01-29 13:34:3119 hrs ago1738157671IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972525.42069
Set Prices89444772025-01-29 12:34:2720 hrs ago1738154067IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89430062025-01-29 11:34:2221 hrs ago1738150462IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89412952025-01-29 10:34:1922 hrs ago1738146859IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices89394832025-01-29 9:34:1923 hrs ago1738143259IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975825.42069
Set Prices89378532025-01-29 8:34:1824 hrs ago1738139658IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972525.42069
View all transactions

Parent Transaction Hash Block From To
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PriceOracleV2

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
istanbul 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 PriceOracleV2 is Exponential {
    /**
     * @dev flag for whether or not contract is paused
     *
     */
    bool public paused;

    uint256 public constant oneHour = 600; //using 10 minutes instead

    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.timestamp / oneHour) + 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 timestamp.)
        localVars.currentPeriod = (block.timestamp / oneHour) + 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":"oneHour","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"}]

608060405234801561001057600080fd5b506040516114b63803806114b68339818101604052602081101561003357600080fd5b505160028054336001600160a01b031991821617909155600480549091166001600160a01b03909216919091179055604080516020810190915267016345785d8a00009081905260055561142a8061008c6000396000f3fe6080604052600436106101085760003560e01c80635e9a523c116100955780639e8c4d95116100645780639e8c4d95146104b9578063c5faf1d5146104ec578063c92da30214610501578063ccb13cbd14610516578063de9d0e851461052b57610108565b80635e9a523c146103f2578063692374e31461042557806380959721146104715780639964622c1461048657610108565b806326617c28116100dc57806326617c28146101d157806341976e09146101fd5780634352fa9f14610230578063451b1e3a146103b45780635c975abb146103c957610108565b8062e4768b1461010d57806308f31857146101585780630c9c630114610189578063183f34441461019e575b600080fd5b34801561011957600080fd5b506101466004803603604081101561013057600080fd5b506001600160a01b038135169060200135610564565b60408051918252519081900360200190f35b34801561016457600080fd5b5061016d6105a0565b604080516001600160a01b039092168252519081900360200190f35b34801561019557600080fd5b506101466105af565b3480156101aa57600080fd5b50610146600480360360208110156101c157600080fd5b50356001600160a01b03166105bb565b3480156101dd57600080fd5b50610146600480360360208110156101f457600080fd5b503515156105cd565b34801561020957600080fd5b506101466004803603602081101561022057600080fd5b50356001600160a01b0316610645565b34801561023c57600080fd5b506103646004803603604081101561025357600080fd5b81019060208101813564010000000081111561026e57600080fd5b82018360208201111561028057600080fd5b803590602001918460208302840111640100000000831117156102a257600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156102f257600080fd5b82018360208201111561030457600080fd5b8035906020019184602083028401116401000000008311171561032657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610650945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a0578181015183820152602001610388565b505050509050019250505060405180910390f35b3480156103c057600080fd5b5061016d61078e565b3480156103d557600080fd5b506103de61079d565b604080519115158252519081900360200190f35b3480156103fe57600080fd5b506101466004803603602081101561041557600080fd5b50356001600160a01b03166107a6565b34801561043157600080fd5b506104586004803603602081101561044857600080fd5b50356001600160a01b03166107d6565b6040805192835260208301919091528051918290030190f35b34801561047d57600080fd5b5061016d6107ef565b34801561049257600080fd5b50610146600480360360208110156104a957600080fd5b50356001600160a01b03166107fe565b3480156104c557600080fd5b50610146600480360360208110156104dc57600080fd5b50356001600160a01b0316610889565b3480156104f857600080fd5b5061014661089b565b34801561050d57600080fd5b506101466108a1565b34801561052257600080fd5b506101466108a7565b34801561053757600080fd5b506101466004803603604081101561054e57600080fd5b506001600160a01b038135169060200135610941565b6004546000906001600160a01b0316331461058d5761058683600160086109d4565b905061059a565b6105978383610a5d565b90505b92915050565b6002546001600160a01b031681565b67016345785d8a000081565b60016020526000908152604090205481565b6002546000906001600160a01b031633146105f6576105ef60006001806109d4565b9050610640565b6000805483151560ff19909116811790915560408051918252517f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b59809181900360200190a160005b90505b919050565b600061063d826107a6565b81518151600454606092919083906001600160a01b031633146106bd57604080516001808252818301909252906020808301908038833901905050905061069b6000600160086109d4565b816000815181106106a857fe5b6020908102919091010152925061059a915050565b8215806106ca5750828214155b156106fd57604080516001808252818301909252906020808301908038833901905050905061069b60006002600a6109d4565b82604051908082528060200260200182016040528015610727578160200160208202803883390190505b50905060005b838110156107845761076587828151811061074457fe5b602002602001015187838151811061075857fe5b6020026020010151610a5d565b82828151811061077157fe5b602090810291909101015260010161072d565b5095945050505050565b6003546001600160a01b031681565b60005460ff1681565b6000805460ff16156107ba57506000610640565b506001600160a01b031660009081526001602052604090205490565b6006602052600090815260409020805460019091015482565b6004546001600160a01b031681565b6002546000906001600160a01b03163314610821576105ef6000600160026109d4565b600380546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517f6c773973d5bcf264b509f4194ceb99e891251f6aabb325523a863c282958b13e929181900390910190a160009392505050565b60076020526000908152604090205481565b60055481565b61025881565b6003546000906001600160a01b031633146108d1576108ca6000600160006109d4565b905061093e565b60028054600380546001600160a01b03198084166001600160a01b03838116919091179095551690556040805192909116808352336020840152815190927fbef9248fe57ae972dd47833f68c43f0b3b2d14217612dfbc804a520a23730d4692908290030190a160009150505b90565b6002546000906001600160a01b031633146109635761058683600160036109d4565b6001600160a01b0383166000818152600760209081526040918290208054908690558251338152918201939093528082018390526060810185905290517ff0aa20c29c1f8e751bfe0a78bc49a520ed14f2dab274087d90d1341d8b76af5c9181900360800190a16000949350505050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73385856002811115610a0557fe5b85600a811115610a1157fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526000608082015290519081900360a00190a1826002811115610a5557fe5b949350505050565b600080610a68611389565b610258420460010160808201526001600160a01b0385166000908152600760209081526040918290205460e08401908152825191820190925285815282525115610b4f57600060608201526040805160208101825260e083015181529082018190528151610ad69190610db4565b602083015291506000826017811115610aeb57fe5b14610b1257610b098560026004856017811115610b0457fe5b610e3a565b9250505061059a565b6020808201516040805192830190526005548252610b2f91610ec4565b15610b4a57610b098560026006846020015160000151610e3a565b610c06565b6001600160a01b038516600081815260066020818152604080842080546060880190815282518085018452969095529290915260019091015483528301919091525115610bf457610ba881604001518260000151610ecb565b8352151560a083015291506000826017811115610bc157fe5b14610bda57610b098560026005856017811115610b0457fe5b8060a0015115610b4a5760408101515160c0820152610c06565b60408051602081018252858152908201525b610c13816040015161108a565b15610c2557610b0985600260076109d4565b8051610c309061108a565b15610c4257610b0985600260096109d4565b6001600160a01b03851660009081526007602052604090205415610c7a576001600160a01b0385166000908152600760205260408120555b806060015181608001511115610cca576040805180820182526080830151815282515160208083019182526001600160a01b03891660009081526006909152929092209051815590516001909101555b6001600160a01b038516600090815260016020526040902054815151610cf190879061108f565b815151604080516001600160a01b0389168152602081018490528082018890526060810192909252517fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae79181900360800190a18160a0015115610da85760c0820151825151604080516001600160a01b038a16815260208101899052808201939093526060830191909152517f7221f7a2708437039cc63319145b6b873a40594b9782a3bee45b975e2f3b0f689181900360800190a15b60009695505050505050565b6000610dbe6113e2565b610dc66113e2565b6000610dd28686610ec4565b15610dff57610de186866110ba565b925090506000816017811115610df357fe5b14610dfa57fe5b610e22565b610e0985876110ba565b925090506000816017811115610e1b57fe5b14610e2257fe5b610e2c82876110f4565b9350935050505b9250929050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73386866002811115610e6b57fe5b86600a811115610e7757fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526080810185905290519081900360a00190a1836002811115610ebb57fe5b95945050505050565b5190511190565b600080610ed66113e2565b610ede6113e2565b506040805160208101909152670de0b6b3a76400008152610efd6113e2565b610f056113e2565b610f0d6113e2565b610f156113e2565b60408051602081019091526005548152600090610f33908790611117565b955090506000816017811115610f4557fe5b14610f6d57604080516020810190915260008082529199509097509550611083945050505050565b610f778b86611136565b935090506000816017811115610f8957fe5b14610fb157604080516020810190915260008082529199509097509550611083945050505050565b610fbb8a84610ec4565b15610fd6576000600184985098509850505050505050611083565b60408051602081019091526005548152610ff19087906110ba565b94509050600081601781111561100357fe5b1461102b57604080516020810190915260008082529199509097509550611083945050505050565b6110358b85611136565b92509050600081601781111561104757fe5b1461104e57fe5b6110588a8361121f565b156110725750600097506001965094506110839350505050565b6000808b9850985098505050505050505b9250925092565b511590565b60408051602080820183529281526001600160a01b0390931660009081526001909252902090519055565b60006110c46113e2565b6000806110d986600001518660000151611226565b60408051602081019091529081529097909650945050505050565b60006110fe6113e2565b8351835161110c9190611249565b915091509250929050565b60006111216113e2565b6000806110d9866000015186600001516112f9565b60006111406113e2565b6000806111558660000151866000015161131f565b9092509050600082601781111561116857fe5b1461118757506040805160208101909152600081529092509050610e33565b60008061119c6706f05b59d3b20000846112f9565b909250905060008260178111156111af57fe5b146111d157506040805160208101909152600081529094509250610e33915050565b6000806111e683670de0b6b3a764000061135e565b909250905060008260178111156111f957fe5b1461120057fe5b604080516020810190915290815260009a909950975050505050505050565b5190511090565b60008083831161123d575060009050818303610e33565b50600490506000610e33565b60006112536113e2565b60008061126886670de0b6b3a764000061131f565b9092509050600082601781111561127b57fe5b1461129a57506040805160208101909152600081529092509050610e33565b6000806112a7838861135e565b909250905060008260178111156112ba57fe5b146112dc57506040805160208101909152600081529094509250610e33915050565b604080516020810190915290815260009890975095505050505050565b60008083830184811061131157600092509050610e33565b506003915060009050610e33565b6000808361133257506000905080610e33565b8383028385828161133f57fe5b041461135357506003915060009050610e33565b600092509050610e33565b600080826113725750600590506000610e33565b600083858161137d57fe5b04915091509250929050565b60405180610100016040528061139d6113e2565b81526020016113aa6113e2565b81526020016113b76113e2565b8152602001600081526020016000815260200160001515815260200160008152602001600081525090565b604051806020016040528060008152509056fea265627a7a72315820ce302dd4ef20b4cbbd560cdd67cd01380013dd683a3ca54275e2a2ac778a9c3a64736f6c634300051100320000000000000000000000004bb20ae63cb86ad4fdebeb3a434340577a7f91d1

Deployed Bytecode

0x6080604052600436106101085760003560e01c80635e9a523c116100955780639e8c4d95116100645780639e8c4d95146104b9578063c5faf1d5146104ec578063c92da30214610501578063ccb13cbd14610516578063de9d0e851461052b57610108565b80635e9a523c146103f2578063692374e31461042557806380959721146104715780639964622c1461048657610108565b806326617c28116100dc57806326617c28146101d157806341976e09146101fd5780634352fa9f14610230578063451b1e3a146103b45780635c975abb146103c957610108565b8062e4768b1461010d57806308f31857146101585780630c9c630114610189578063183f34441461019e575b600080fd5b34801561011957600080fd5b506101466004803603604081101561013057600080fd5b506001600160a01b038135169060200135610564565b60408051918252519081900360200190f35b34801561016457600080fd5b5061016d6105a0565b604080516001600160a01b039092168252519081900360200190f35b34801561019557600080fd5b506101466105af565b3480156101aa57600080fd5b50610146600480360360208110156101c157600080fd5b50356001600160a01b03166105bb565b3480156101dd57600080fd5b50610146600480360360208110156101f457600080fd5b503515156105cd565b34801561020957600080fd5b506101466004803603602081101561022057600080fd5b50356001600160a01b0316610645565b34801561023c57600080fd5b506103646004803603604081101561025357600080fd5b81019060208101813564010000000081111561026e57600080fd5b82018360208201111561028057600080fd5b803590602001918460208302840111640100000000831117156102a257600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156102f257600080fd5b82018360208201111561030457600080fd5b8035906020019184602083028401116401000000008311171561032657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610650945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a0578181015183820152602001610388565b505050509050019250505060405180910390f35b3480156103c057600080fd5b5061016d61078e565b3480156103d557600080fd5b506103de61079d565b604080519115158252519081900360200190f35b3480156103fe57600080fd5b506101466004803603602081101561041557600080fd5b50356001600160a01b03166107a6565b34801561043157600080fd5b506104586004803603602081101561044857600080fd5b50356001600160a01b03166107d6565b6040805192835260208301919091528051918290030190f35b34801561047d57600080fd5b5061016d6107ef565b34801561049257600080fd5b50610146600480360360208110156104a957600080fd5b50356001600160a01b03166107fe565b3480156104c557600080fd5b50610146600480360360208110156104dc57600080fd5b50356001600160a01b0316610889565b3480156104f857600080fd5b5061014661089b565b34801561050d57600080fd5b506101466108a1565b34801561052257600080fd5b506101466108a7565b34801561053757600080fd5b506101466004803603604081101561054e57600080fd5b506001600160a01b038135169060200135610941565b6004546000906001600160a01b0316331461058d5761058683600160086109d4565b905061059a565b6105978383610a5d565b90505b92915050565b6002546001600160a01b031681565b67016345785d8a000081565b60016020526000908152604090205481565b6002546000906001600160a01b031633146105f6576105ef60006001806109d4565b9050610640565b6000805483151560ff19909116811790915560408051918252517f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b59809181900360200190a160005b90505b919050565b600061063d826107a6565b81518151600454606092919083906001600160a01b031633146106bd57604080516001808252818301909252906020808301908038833901905050905061069b6000600160086109d4565b816000815181106106a857fe5b6020908102919091010152925061059a915050565b8215806106ca5750828214155b156106fd57604080516001808252818301909252906020808301908038833901905050905061069b60006002600a6109d4565b82604051908082528060200260200182016040528015610727578160200160208202803883390190505b50905060005b838110156107845761076587828151811061074457fe5b602002602001015187838151811061075857fe5b6020026020010151610a5d565b82828151811061077157fe5b602090810291909101015260010161072d565b5095945050505050565b6003546001600160a01b031681565b60005460ff1681565b6000805460ff16156107ba57506000610640565b506001600160a01b031660009081526001602052604090205490565b6006602052600090815260409020805460019091015482565b6004546001600160a01b031681565b6002546000906001600160a01b03163314610821576105ef6000600160026109d4565b600380546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517f6c773973d5bcf264b509f4194ceb99e891251f6aabb325523a863c282958b13e929181900390910190a160009392505050565b60076020526000908152604090205481565b60055481565b61025881565b6003546000906001600160a01b031633146108d1576108ca6000600160006109d4565b905061093e565b60028054600380546001600160a01b03198084166001600160a01b03838116919091179095551690556040805192909116808352336020840152815190927fbef9248fe57ae972dd47833f68c43f0b3b2d14217612dfbc804a520a23730d4692908290030190a160009150505b90565b6002546000906001600160a01b031633146109635761058683600160036109d4565b6001600160a01b0383166000818152600760209081526040918290208054908690558251338152918201939093528082018390526060810185905290517ff0aa20c29c1f8e751bfe0a78bc49a520ed14f2dab274087d90d1341d8b76af5c9181900360800190a16000949350505050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73385856002811115610a0557fe5b85600a811115610a1157fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526000608082015290519081900360a00190a1826002811115610a5557fe5b949350505050565b600080610a68611389565b610258420460010160808201526001600160a01b0385166000908152600760209081526040918290205460e08401908152825191820190925285815282525115610b4f57600060608201526040805160208101825260e083015181529082018190528151610ad69190610db4565b602083015291506000826017811115610aeb57fe5b14610b1257610b098560026004856017811115610b0457fe5b610e3a565b9250505061059a565b6020808201516040805192830190526005548252610b2f91610ec4565b15610b4a57610b098560026006846020015160000151610e3a565b610c06565b6001600160a01b038516600081815260066020818152604080842080546060880190815282518085018452969095529290915260019091015483528301919091525115610bf457610ba881604001518260000151610ecb565b8352151560a083015291506000826017811115610bc157fe5b14610bda57610b098560026005856017811115610b0457fe5b8060a0015115610b4a5760408101515160c0820152610c06565b60408051602081018252858152908201525b610c13816040015161108a565b15610c2557610b0985600260076109d4565b8051610c309061108a565b15610c4257610b0985600260096109d4565b6001600160a01b03851660009081526007602052604090205415610c7a576001600160a01b0385166000908152600760205260408120555b806060015181608001511115610cca576040805180820182526080830151815282515160208083019182526001600160a01b03891660009081526006909152929092209051815590516001909101555b6001600160a01b038516600090815260016020526040902054815151610cf190879061108f565b815151604080516001600160a01b0389168152602081018490528082018890526060810192909252517fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae79181900360800190a18160a0015115610da85760c0820151825151604080516001600160a01b038a16815260208101899052808201939093526060830191909152517f7221f7a2708437039cc63319145b6b873a40594b9782a3bee45b975e2f3b0f689181900360800190a15b60009695505050505050565b6000610dbe6113e2565b610dc66113e2565b6000610dd28686610ec4565b15610dff57610de186866110ba565b925090506000816017811115610df357fe5b14610dfa57fe5b610e22565b610e0985876110ba565b925090506000816017811115610e1b57fe5b14610e2257fe5b610e2c82876110f4565b9350935050505b9250929050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73386866002811115610e6b57fe5b86600a811115610e7757fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526080810185905290519081900360a00190a1836002811115610ebb57fe5b95945050505050565b5190511190565b600080610ed66113e2565b610ede6113e2565b506040805160208101909152670de0b6b3a76400008152610efd6113e2565b610f056113e2565b610f0d6113e2565b610f156113e2565b60408051602081019091526005548152600090610f33908790611117565b955090506000816017811115610f4557fe5b14610f6d57604080516020810190915260008082529199509097509550611083945050505050565b610f778b86611136565b935090506000816017811115610f8957fe5b14610fb157604080516020810190915260008082529199509097509550611083945050505050565b610fbb8a84610ec4565b15610fd6576000600184985098509850505050505050611083565b60408051602081019091526005548152610ff19087906110ba565b94509050600081601781111561100357fe5b1461102b57604080516020810190915260008082529199509097509550611083945050505050565b6110358b85611136565b92509050600081601781111561104757fe5b1461104e57fe5b6110588a8361121f565b156110725750600097506001965094506110839350505050565b6000808b9850985098505050505050505b9250925092565b511590565b60408051602080820183529281526001600160a01b0390931660009081526001909252902090519055565b60006110c46113e2565b6000806110d986600001518660000151611226565b60408051602081019091529081529097909650945050505050565b60006110fe6113e2565b8351835161110c9190611249565b915091509250929050565b60006111216113e2565b6000806110d9866000015186600001516112f9565b60006111406113e2565b6000806111558660000151866000015161131f565b9092509050600082601781111561116857fe5b1461118757506040805160208101909152600081529092509050610e33565b60008061119c6706f05b59d3b20000846112f9565b909250905060008260178111156111af57fe5b146111d157506040805160208101909152600081529094509250610e33915050565b6000806111e683670de0b6b3a764000061135e565b909250905060008260178111156111f957fe5b1461120057fe5b604080516020810190915290815260009a909950975050505050505050565b5190511090565b60008083831161123d575060009050818303610e33565b50600490506000610e33565b60006112536113e2565b60008061126886670de0b6b3a764000061131f565b9092509050600082601781111561127b57fe5b1461129a57506040805160208101909152600081529092509050610e33565b6000806112a7838861135e565b909250905060008260178111156112ba57fe5b146112dc57506040805160208101909152600081529094509250610e33915050565b604080516020810190915290815260009890975095505050505050565b60008083830184811061131157600092509050610e33565b506003915060009050610e33565b6000808361133257506000905080610e33565b8383028385828161133f57fe5b041461135357506003915060009050610e33565b600092509050610e33565b600080826113725750600590506000610e33565b600083858161137d57fe5b04915091509250929050565b60405180610100016040528061139d6113e2565b81526020016113aa6113e2565b81526020016113b76113e2565b8152602001600081526020016000815260200160001515815260200160008152602001600081525090565b604051806020016040528060008152509056fea265627a7a72315820ce302dd4ef20b4cbbd560cdd67cd01380013dd683a3ca54275e2a2ac778a9c3a64736f6c63430005110032

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

0000000000000000000000004bb20ae63cb86ad4fdebeb3a434340577a7f91d1

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

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000004bb20ae63cb86ad4fdebeb3a434340577a7f91d1


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
[ 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.