Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,047 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Prices | 4969430 | 36 mins ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4965222 | 1 hr ago | IN | 0 APE | 0.00259725 | ||||
Set Prices | 4961387 | 2 hrs ago | IN | 0 APE | 0.00259728 | ||||
Set Prices | 4957917 | 3 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4953920 | 4 hrs ago | IN | 0 APE | 0.00259725 | ||||
Set Prices | 4950035 | 5 hrs ago | IN | 0 APE | 0.00259723 | ||||
Set Prices | 4946098 | 6 hrs ago | IN | 0 APE | 0.00259753 | ||||
Set Prices | 4941947 | 7 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4938675 | 8 hrs ago | IN | 0 APE | 0.00259728 | ||||
Set Prices | 4934179 | 9 hrs ago | IN | 0 APE | 0.00259753 | ||||
Set Prices | 4927681 | 10 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4919057 | 11 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4914808 | 12 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4910168 | 13 hrs ago | IN | 0 APE | 0.00259728 | ||||
Set Prices | 4905351 | 14 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4897446 | 15 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4892818 | 16 hrs ago | IN | 0 APE | 0.00259695 | ||||
Set Prices | 4888339 | 17 hrs ago | IN | 0 APE | 0.00259728 | ||||
Set Prices | 4883957 | 18 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4879781 | 19 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4875439 | 20 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4870928 | 21 hrs ago | IN | 0 APE | 0.00259756 | ||||
Set Prices | 4866737 | 22 hrs ago | IN | 0 APE | 0.00259758 | ||||
Set Prices | 4862895 | 23 hrs ago | IN | 0 APE | 0.00259725 | ||||
Set Prices | 4859022 | 24 hrs ago | IN | 0 APE | 0.00259728 |
Loading...
Loading
Contract Name:
PriceOracleV2
Compiler Version
v0.5.17+commit.d19bba13
Contract Source Code (Solidity Standard Json-Input format)
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; } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
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
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.