APE Price: $1.19 (+3.59%)

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 Prices49694302024-11-22 7:49:2336 mins ago1732261763IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices49652222024-11-22 6:49:191 hr ago1732258159IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972525.42069
Set Prices49613872024-11-22 5:49:152 hrs ago1732254555IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972825.42069
Set Prices49579172024-11-22 4:49:153 hrs ago1732250955IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices49539202024-11-22 3:49:144 hrs ago1732247354IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972525.42069
Set Prices49500352024-11-22 2:49:135 hrs ago1732243753IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972325.42069
Set Prices49460982024-11-22 1:49:136 hrs ago1732240153IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975325.42069
Set Prices49419472024-11-22 0:49:097 hrs ago1732236549IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices49386752024-11-21 23:49:088 hrs ago1732232948IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972825.42069
Set Prices49341792024-11-21 22:49:049 hrs ago1732229344IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975325.42069
Set Prices49276812024-11-21 21:49:0210 hrs ago1732225742IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices49190572024-11-21 20:49:0011 hrs ago1732222140IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices49148082024-11-21 19:48:5612 hrs ago1732218536IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices49101682024-11-21 18:48:5613 hrs ago1732214936IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972825.42069
Set Prices49053512024-11-21 17:48:5414 hrs ago1732211334IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices48974462024-11-21 16:48:5115 hrs ago1732207731IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices48928182024-11-21 15:48:5116 hrs ago1732204131IN
0x0c449E0B...50Dc43aDb
0 APE0.0025969525.42069
Set Prices48883392024-11-21 14:48:4817 hrs ago1732200528IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972825.42069
Set Prices48839572024-11-21 13:48:4518 hrs ago1732196925IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices48797812024-11-21 12:48:4419 hrs ago1732193324IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices48754392024-11-21 11:48:4220 hrs ago1732189722IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices48709282024-11-21 10:48:3821 hrs ago1732186118IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975625.42069
Set Prices48667372024-11-21 9:48:3622 hrs ago1732182516IN
0x0c449E0B...50Dc43aDb
0 APE0.0025975825.42069
Set Prices48628952024-11-21 8:48:3223 hrs ago1732178912IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972525.42069
Set Prices48590222024-11-21 7:48:2724 hrs ago1732175307IN
0x0c449E0B...50Dc43aDb
0 APE0.0025972825.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.