Source Code
Latest 25 from a total of 17,403 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Prices | 433132642 | 1 min ago | IN | 0 ETH | 0.00000161 | ||||
| Set Prices | 433098260 | 2 hrs ago | IN | 0 ETH | 0.00000106 | ||||
| Set Prices | 433086052 | 3 hrs ago | IN | 0 ETH | 0.00000155 | ||||
| Set Prices | 433051604 | 5 hrs ago | IN | 0 ETH | 0.00000104 | ||||
| Set Prices | 433039395 | 6 hrs ago | IN | 0 ETH | 0.00000154 | ||||
| Set Prices | 433005084 | 8 hrs ago | IN | 0 ETH | 0.00000104 | ||||
| Set Prices | 432994003 | 9 hrs ago | IN | 0 ETH | 0.00000155 | ||||
| Set Prices | 432958616 | 12 hrs ago | IN | 0 ETH | 0.00000104 | ||||
| Set Prices | 432947545 | 12 hrs ago | IN | 0 ETH | 0.00000154 | ||||
| Set Prices | 432912133 | 15 hrs ago | IN | 0 ETH | 0.00000104 | ||||
| Set Prices | 432901069 | 16 hrs ago | IN | 0 ETH | 0.00000155 | ||||
| Set Prices | 432865653 | 18 hrs ago | IN | 0 ETH | 0.00000105 | ||||
| Set Prices | 432854606 | 19 hrs ago | IN | 0 ETH | 0.00000156 | ||||
| Set Prices | 432819226 | 21 hrs ago | IN | 0 ETH | 0.00000104 | ||||
| Set Prices | 432808168 | 22 hrs ago | IN | 0 ETH | 0.00000154 | ||||
| Set Prices | 432772767 | 24 hrs ago | IN | 0 ETH | 0.00000104 | ||||
| Set Prices | 432761691 | 25 hrs ago | IN | 0 ETH | 0.00000154 | ||||
| Set Prices | 432727327 | 28 hrs ago | IN | 0 ETH | 0.00000105 | ||||
| Set Prices | 432715117 | 28 hrs ago | IN | 0 ETH | 0.00000156 | ||||
| Set Prices | 432680744 | 31 hrs ago | IN | 0 ETH | 0.00000104 | ||||
| Set Prices | 432668521 | 32 hrs ago | IN | 0 ETH | 0.00000157 | ||||
| Set Prices | 432634132 | 34 hrs ago | IN | 0 ETH | 0.00000104 | ||||
| Set Prices | 432621950 | 35 hrs ago | IN | 0 ETH | 0.00000143 | ||||
| Set Prices | 432587657 | 37 hrs ago | IN | 0 ETH | 0.00000105 | ||||
| Set Prices | 432576589 | 38 hrs ago | IN | 0 ETH | 0.00000154 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PriceOracleV1
Compiler Version
v0.5.17+commit.d19bba13
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
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 PriceOracleV1 is Exponential {
/**
* @dev flag for whether or not contract is paused
*
*/
bool public paused;
uint256 public constant numBlocksPerPeriod = 240; // approximately 1 hour: 60 seconds/minute * 60 minutes/hour * 1 block/15 seconds
uint256 public constant maxSwingMantissa = (10**17); // 0.1
/**
* @dev Mapping of asset addresses and their corresponding price in terms of Eth-Wei
* which is simply equal to AssetWeiPrice * 10e18. For instance, if OMG token was
* worth 5x Eth then the price for OMG would be 5*10e18 or Exp({mantissa: 5000000000000000000}).
* map: assetAddress -> Exp
*/
mapping(address => Exp) public _assetPrices;
constructor(address _poster) public {
anchorAdmin = msg.sender;
poster = _poster;
maxSwing = Exp({mantissa: maxSwingMantissa});
}
/**
* @notice Do not pay into PriceOracle
*/
function() external payable {
revert();
}
enum OracleError {
NO_ERROR,
UNAUTHORIZED,
FAILED_TO_SET_PRICE
}
enum OracleFailureInfo {
ACCEPT_ANCHOR_ADMIN_PENDING_ANCHOR_ADMIN_CHECK,
SET_PAUSED_OWNER_CHECK,
SET_PENDING_ANCHOR_ADMIN_OWNER_CHECK,
SET_PENDING_ANCHOR_PERMISSION_CHECK,
SET_PRICE_CALCULATE_SWING,
SET_PRICE_CAP_TO_MAX,
SET_PRICE_MAX_SWING_CHECK,
SET_PRICE_NO_ANCHOR_PRICE_OR_INITIAL_PRICE_ZERO,
SET_PRICE_PERMISSION_CHECK,
SET_PRICE_ZERO_PRICE,
SET_PRICES_PARAM_VALIDATION
}
/**
* @dev `msgSender` is msg.sender; `error` corresponds to enum OracleError; `info` corresponds to enum OracleFailureInfo, and `detail` is an arbitrary
* contract-specific code that enables us to report opaque error codes from upgradeable contracts.
**/
event OracleFailure(address msgSender, address asset, uint256 error, uint256 info, uint256 detail);
/**
* @dev use this when reporting a known error from the price oracle or a non-upgradeable collaborator
* Using Oracle in name because we already inherit a `fail` function from ErrorReporter.sol via Exponential.sol
*/
function failOracle(
address asset,
OracleError err,
OracleFailureInfo info
) internal returns (uint256) {
emit OracleFailure(msg.sender, asset, uint256(err), uint256(info), 0);
return uint256(err);
}
/**
* @dev Use this when reporting an error from the money market. Give the money market result as `details`
*/
function failOracleWithDetails(
address asset,
OracleError err,
OracleFailureInfo info,
uint256 details
) internal returns (uint256) {
emit OracleFailure(msg.sender, asset, uint256(err), uint256(info), details);
return uint256(err);
}
/**
* @dev An administrator who can set the pending anchor value for assets.
* Set in the constructor.
*/
address public anchorAdmin;
/**
* @dev pending anchor administrator for this contract.
*/
address public pendingAnchorAdmin;
/**
* @dev Address of the price poster.
* Set in the constructor.
*/
address public poster;
/**
* @dev maxSwing the maximum allowed percentage difference between a new price and the anchor's price
* Set only in the constructor
*/
Exp public maxSwing;
struct Anchor {
// floor(block.number / numBlocksPerPeriod) + 1
uint256 period;
// Price in ETH, scaled by 10**18
uint256 priceMantissa;
}
/**
* @dev anchors by asset
*/
mapping(address => Anchor) public anchors;
/**
* @dev pending anchor prices by asset
*/
mapping(address => uint256) public pendingAnchors;
/**
* @dev emitted when a pending anchor is set
* @param asset Asset for which to set a pending anchor
* @param oldScaledPrice if an unused pending anchor was present, its value; otherwise 0.
* @param newScaledPrice the new scaled pending anchor price
*/
event NewPendingAnchor(address anchorAdmin, address asset, uint256 oldScaledPrice, uint256 newScaledPrice);
/**
* @notice provides ability to override the anchor price for an asset
* @dev Admin function to set the anchor price for an asset
* @param asset Asset for which to override the anchor price
* @param newScaledPrice New anchor price
* @return uint 0=success, otherwise a failure (see enum OracleError for details)
*/
function _setPendingAnchor(address asset, uint256 newScaledPrice) public returns (uint256) {
// Check caller = anchorAdmin. Note: Deliberately not allowing admin. They can just change anchorAdmin if desired.
if (msg.sender != anchorAdmin) {
return failOracle(asset, OracleError.UNAUTHORIZED, OracleFailureInfo.SET_PENDING_ANCHOR_PERMISSION_CHECK);
}
uint256 oldScaledPrice = pendingAnchors[asset];
pendingAnchors[asset] = newScaledPrice;
emit NewPendingAnchor(msg.sender, asset, oldScaledPrice, newScaledPrice);
return uint256(OracleError.NO_ERROR);
}
/**
* @dev emitted for all price changes
*/
event PricePosted(
address asset,
uint256 previousPriceMantissa,
uint256 requestedPriceMantissa,
uint256 newPriceMantissa
);
/**
* @dev emitted if this contract successfully posts a capped-to-max price to the money market
*/
event CappedPricePosted(
address asset,
uint256 requestedPriceMantissa,
uint256 anchorPriceMantissa,
uint256 cappedPriceMantissa
);
/**
* @dev emitted when admin either pauses or resumes the contract; newState is the resulting state
*/
event SetPaused(bool newState);
/**
* @dev emitted when pendingAnchorAdmin is changed
*/
event NewPendingAnchorAdmin(address oldPendingAnchorAdmin, address newPendingAnchorAdmin);
/**
* @dev emitted when pendingAnchorAdmin is accepted, which means anchor admin is updated
*/
event NewAnchorAdmin(address oldAnchorAdmin, address newAnchorAdmin);
/**
* @notice set `paused` to the specified state
* @dev Admin function to pause or resume the market
* @param requestedState value to assign to `paused`
* @return uint 0=success, otherwise a failure
*/
function _setPaused(bool requestedState) public returns (uint256) {
// Check caller = anchorAdmin
if (msg.sender != anchorAdmin) {
return failOracle(address(0), OracleError.UNAUTHORIZED, OracleFailureInfo.SET_PAUSED_OWNER_CHECK);
}
paused = requestedState;
emit SetPaused(requestedState);
return uint256(Error.NO_ERROR);
}
/**
* @notice Begins transfer of anchor admin rights. The newPendingAnchorAdmin must call `_acceptAnchorAdmin` to finalize the transfer.
* @dev Admin function to begin change of anchor admin. The newPendingAnchorAdmin must call `_acceptAnchorAdmin` to finalize the transfer.
* @param newPendingAnchorAdmin New pending anchor admin.
* @return uint 0=success, otherwise a failure
*
* TODO: Should we add a second arg to verify, like a checksum of `newAnchorAdmin` address?
*/
function _setPendingAnchorAdmin(address newPendingAnchorAdmin) public returns (uint256) {
// Check caller = anchorAdmin
if (msg.sender != anchorAdmin) {
return
failOracle(
address(0),
OracleError.UNAUTHORIZED,
OracleFailureInfo.SET_PENDING_ANCHOR_ADMIN_OWNER_CHECK
);
}
// save current value, if any, for inclusion in log
address oldPendingAnchorAdmin = pendingAnchorAdmin;
// Store pendingAdmin = newPendingAdmin
pendingAnchorAdmin = newPendingAnchorAdmin;
emit NewPendingAnchorAdmin(oldPendingAnchorAdmin, newPendingAnchorAdmin);
return uint256(Error.NO_ERROR);
}
/**
* @notice Accepts transfer of anchor admin rights. msg.sender must be pendingAnchorAdmin
* @dev Admin function for pending anchor admin to accept role and update anchor admin
* @return uint 0=success, otherwise a failure
*/
function _acceptAnchorAdmin() public returns (uint256) {
// Check caller = pendingAnchorAdmin
// msg.sender can't be zero
if (msg.sender != pendingAnchorAdmin) {
return
failOracle(
address(0),
OracleError.UNAUTHORIZED,
OracleFailureInfo.ACCEPT_ANCHOR_ADMIN_PENDING_ANCHOR_ADMIN_CHECK
);
}
// Save current value for inclusion in log
address oldAnchorAdmin = anchorAdmin;
// Store admin = pendingAnchorAdmin
anchorAdmin = pendingAnchorAdmin;
// Clear the pending value
pendingAnchorAdmin = address(0);
emit NewAnchorAdmin(oldAnchorAdmin, msg.sender);
return uint256(Error.NO_ERROR);
}
/**
* @notice retrieves price of an asset
* @dev function to get price for an asset
* @param asset Asset for which to get the price
* @return uint mantissa of asset price (scaled by 1e18) or zero if unset or contract paused
*/
function assetPrices(address asset) public view returns (uint256) {
// Note: zero is treated by the money market as an invalid
// price and will cease operations with that asset
// when zero.
//
// We get the price as:
//
// 1. If the contract is paused, return 0.
// 2. Return price in `_assetPrices`, which may be zero.
if (paused) {
return 0;
}
return _assetPrices[asset].mantissa;
}
/**
* @notice retrieves price of an asset
* @dev function to get price for an asset
* @param asset Asset for which to get the price
* @return uint mantissa of asset price (scaled by 1e18) or zero if unset or contract paused
*/
function getPrice(address asset) public view returns (uint256) {
return assetPrices(asset);
}
struct SetPriceLocalVars {
Exp price;
Exp swing;
Exp anchorPrice;
uint256 anchorPeriod;
uint256 currentPeriod;
bool priceCapped;
uint256 cappingAnchorPriceMantissa;
uint256 pendingAnchorMantissa;
}
/**
* @notice entry point for updating prices
* @dev function to set price for an asset
* @param asset Asset for which to set the price
* @param requestedPriceMantissa requested new price, scaled by 10**18
* @return uint 0=success, otherwise a failure (see enum OracleError for details)
*/
function setPrice(address asset, uint256 requestedPriceMantissa) public returns (uint256) {
// Fail when msg.sender is not poster
if (msg.sender != poster) {
return failOracle(asset, OracleError.UNAUTHORIZED, OracleFailureInfo.SET_PRICE_PERMISSION_CHECK);
}
return setPriceInternal(asset, requestedPriceMantissa);
}
function setPriceInternal(address asset, uint256 requestedPriceMantissa) internal returns (uint256) {
// re-used for intermediate errors
Error err;
SetPriceLocalVars memory localVars;
// We add 1 for currentPeriod so that it can never be zero and there's no ambiguity about an unset value.
// (It can be a problem in tests with low block numbers.)
localVars.currentPeriod = (block.number / numBlocksPerPeriod) + 1;
localVars.pendingAnchorMantissa = pendingAnchors[asset];
localVars.price = Exp({mantissa: requestedPriceMantissa});
if (localVars.pendingAnchorMantissa != 0) {
// let's explicitly set to 0 rather than relying on default of declaration
localVars.anchorPeriod = 0;
localVars.anchorPrice = Exp({mantissa: localVars.pendingAnchorMantissa});
// Verify movement is within max swing of pending anchor (currently: 10%)
(err, localVars.swing) = calculateSwing(localVars.anchorPrice, localVars.price);
if (err != Error.NO_ERROR) {
return
failOracleWithDetails(
asset,
OracleError.FAILED_TO_SET_PRICE,
OracleFailureInfo.SET_PRICE_CALCULATE_SWING,
uint256(err)
);
}
// Fail when swing > maxSwing
if (greaterThanExp(localVars.swing, maxSwing)) {
return
failOracleWithDetails(
asset,
OracleError.FAILED_TO_SET_PRICE,
OracleFailureInfo.SET_PRICE_MAX_SWING_CHECK,
localVars.swing.mantissa
);
}
} else {
localVars.anchorPeriod = anchors[asset].period;
localVars.anchorPrice = Exp({mantissa: anchors[asset].priceMantissa});
if (localVars.anchorPeriod != 0) {
(err, localVars.priceCapped, localVars.price) = capToMax(localVars.anchorPrice, localVars.price);
if (err != Error.NO_ERROR) {
return
failOracleWithDetails(
asset,
OracleError.FAILED_TO_SET_PRICE,
OracleFailureInfo.SET_PRICE_CAP_TO_MAX,
uint256(err)
);
}
if (localVars.priceCapped) {
// save for use in log
localVars.cappingAnchorPriceMantissa = localVars.anchorPrice.mantissa;
}
} else {
// Setting first price. Accept as is (already assigned above from requestedPriceMantissa) and use as anchor
localVars.anchorPrice = Exp({mantissa: requestedPriceMantissa});
}
}
// Fail if anchorPrice or price is zero.
// zero anchor represents an unexpected situation likely due to a problem in this contract
// zero price is more likely as the result of bad input from the caller of this function
if (isZeroExp(localVars.anchorPrice)) {
// If we get here price could also be zero, but it does not seem worthwhile to distinguish the 3rd case
return
failOracle(
asset,
OracleError.FAILED_TO_SET_PRICE,
OracleFailureInfo.SET_PRICE_NO_ANCHOR_PRICE_OR_INITIAL_PRICE_ZERO
);
}
if (isZeroExp(localVars.price)) {
return failOracle(asset, OracleError.FAILED_TO_SET_PRICE, OracleFailureInfo.SET_PRICE_ZERO_PRICE);
}
// BEGIN SIDE EFFECTS
// Set pendingAnchor = Nothing
// Pending anchor is only used once.
if (pendingAnchors[asset] != 0) {
pendingAnchors[asset] = 0;
}
// If currentPeriod > anchorPeriod:
// Set anchors[asset] = (currentPeriod, price)
// The new anchor is if we're in a new period or we had a pending anchor, then we become the new anchor
if (localVars.currentPeriod > localVars.anchorPeriod) {
anchors[asset] = Anchor({period: localVars.currentPeriod, priceMantissa: localVars.price.mantissa});
}
uint256 previousPrice = _assetPrices[asset].mantissa;
setPriceStorageInternal(asset, localVars.price.mantissa);
emit PricePosted(asset, previousPrice, requestedPriceMantissa, localVars.price.mantissa);
if (localVars.priceCapped) {
// We have set a capped price. Log it so we can detect the situation and investigate.
emit CappedPricePosted(
asset,
requestedPriceMantissa,
localVars.cappingAnchorPriceMantissa,
localVars.price.mantissa
);
}
return uint256(OracleError.NO_ERROR);
}
// As a function to allow harness overrides
function setPriceStorageInternal(address asset, uint256 priceMantissa) internal {
_assetPrices[asset] = Exp({mantissa: priceMantissa});
}
// abs(price - anchorPrice) / anchorPrice
function calculateSwing(Exp memory anchorPrice, Exp memory price) internal pure returns (Error, Exp memory) {
Exp memory numerator;
Error err;
if (greaterThanExp(anchorPrice, price)) {
(err, numerator) = subExp(anchorPrice, price);
// can't underflow
assert(err == Error.NO_ERROR);
} else {
(err, numerator) = subExp(price, anchorPrice);
// Given greaterThan check above, price >= anchorPrice so can't underflow.
assert(err == Error.NO_ERROR);
}
return divExp(numerator, anchorPrice);
}
function capToMax(Exp memory anchorPrice, Exp memory price)
internal
view
returns (
Error,
bool,
Exp memory
)
{
Exp memory one = Exp({mantissa: mantissaOne});
Exp memory onePlusMaxSwing;
Exp memory oneMinusMaxSwing;
Exp memory max;
Exp memory min;
// re-used for intermediate errors
Error err;
(err, onePlusMaxSwing) = addExp(one, maxSwing);
if (err != Error.NO_ERROR) {
return (err, false, Exp({mantissa: 0}));
}
// max = anchorPrice * (1 + maxSwing)
(err, max) = mulExp(anchorPrice, onePlusMaxSwing);
if (err != Error.NO_ERROR) {
return (err, false, Exp({mantissa: 0}));
}
// If price > anchorPrice * (1 + maxSwing)
// Set price = anchorPrice * (1 + maxSwing)
if (greaterThanExp(price, max)) {
return (Error.NO_ERROR, true, max);
}
(err, oneMinusMaxSwing) = subExp(one, maxSwing);
if (err != Error.NO_ERROR) {
return (err, false, Exp({mantissa: 0}));
}
// min = anchorPrice * (1 - maxSwing)
(err, min) = mulExp(anchorPrice, oneMinusMaxSwing);
// We can't overflow here or we would have already overflowed above when calculating `max`
assert(err == Error.NO_ERROR);
// If price < anchorPrice * (1 - maxSwing)
// Set price = anchorPrice * (1 - maxSwing)
if (lessThanExp(price, min)) {
return (Error.NO_ERROR, true, min);
}
return (Error.NO_ERROR, false, price);
}
/**
* @notice entry point for updating multiple prices
* @dev function to set prices for a variable number of assets.
* @param assets a list of up to assets for which to set a price. required: 0 < assets.length == requestedPriceMantissas.length
* @param requestedPriceMantissas requested new prices for the assets, scaled by 10**18. required: 0 < assets.length == requestedPriceMantissas.length
* @return uint values in same order as inputs. For each: 0=success, otherwise a failure (see enum OracleError for details)
*/
function setPrices(address[] memory assets, uint256[] memory requestedPriceMantissas)
public
returns (uint256[] memory)
{
uint256 numAssets = assets.length;
uint256 numPrices = requestedPriceMantissas.length;
uint256[] memory result;
// Fail when msg.sender is not poster
if (msg.sender != poster) {
result = new uint256[](1);
result[0] = failOracle(address(0), OracleError.UNAUTHORIZED, OracleFailureInfo.SET_PRICE_PERMISSION_CHECK);
return result;
}
if ((numAssets == 0) || (numPrices != numAssets)) {
result = new uint256[](1);
result[0] = failOracle(
address(0),
OracleError.FAILED_TO_SET_PRICE,
OracleFailureInfo.SET_PRICES_PARAM_VALIDATION
);
return result;
}
result = new uint256[](numAssets);
for (uint256 i = 0; i < numAssets; i++) {
result[i] = setPriceInternal(assets[i], requestedPriceMantissas[i]);
}
return result;
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_poster","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"requestedPriceMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"anchorPriceMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cappedPriceMantissa","type":"uint256"}],"name":"CappedPricePosted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"error","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"info","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"detail","type":"uint256"}],"name":"Failure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAnchorAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAnchorAdmin","type":"address"}],"name":"NewAnchorAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"anchorAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldScaledPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newScaledPrice","type":"uint256"}],"name":"NewPendingAnchor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPendingAnchorAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newPendingAnchorAdmin","type":"address"}],"name":"NewPendingAnchorAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"msgSender","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"error","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"info","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"detail","type":"uint256"}],"name":"OracleFailure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousPriceMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestedPriceMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPriceMantissa","type":"uint256"}],"name":"PricePosted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newState","type":"bool"}],"name":"SetPaused","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[],"name":"_acceptAnchorAdmin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_assetPrices","outputs":[{"internalType":"uint256","name":"mantissa","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"requestedState","type":"bool"}],"name":"_setPaused","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"newScaledPrice","type":"uint256"}],"name":"_setPendingAnchor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newPendingAnchorAdmin","type":"address"}],"name":"_setPendingAnchorAdmin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"anchorAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"anchors","outputs":[{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"priceMantissa","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"assetPrices","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxSwing","outputs":[{"internalType":"uint256","name":"mantissa","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxSwingMantissa","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"numBlocksPerPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingAnchorAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pendingAnchors","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"poster","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"requestedPriceMantissa","type":"uint256"}],"name":"setPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"requestedPriceMantissas","type":"uint256[]"}],"name":"setPrices","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b506040516114b43803806114b48339818101604052602081101561003357600080fd5b505160028054336001600160a01b031991821617909155600480549091166001600160a01b03909216919091179055604080516020810190915267016345785d8a0000908190526005556114288061008c6000396000f3fe6080604052600436106101085760003560e01c80635c975abb116100955780639964622c116100645780639964622c1461049b5780639e8c4d95146104ce578063c5faf1d514610501578063ccb13cbd14610516578063de9d0e851461052b57610108565b80635c975abb146103de5780635e9a523c14610407578063692374e31461043a578063809597211461048657610108565b806326617c28116100dc57806326617c28146101d157806341976e09146101fd5780634352fa9f14610230578063451b1e3a146103b4578063485feabe146103c957610108565b8062e4768b1461010d57806308f31857146101585780630c9c630114610189578063183f34441461019e575b600080fd5b34801561011957600080fd5b506101466004803603604081101561013057600080fd5b506001600160a01b038135169060200135610564565b60408051918252519081900360200190f35b34801561016457600080fd5b5061016d6105a0565b604080516001600160a01b039092168252519081900360200190f35b34801561019557600080fd5b506101466105af565b3480156101aa57600080fd5b50610146600480360360208110156101c157600080fd5b50356001600160a01b03166105bb565b3480156101dd57600080fd5b50610146600480360360208110156101f457600080fd5b503515156105cd565b34801561020957600080fd5b506101466004803603602081101561022057600080fd5b50356001600160a01b0316610645565b34801561023c57600080fd5b506103646004803603604081101561025357600080fd5b81019060208101813564010000000081111561026e57600080fd5b82018360208201111561028057600080fd5b803590602001918460208302840111640100000000831117156102a257600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156102f257600080fd5b82018360208201111561030457600080fd5b8035906020019184602083028401116401000000008311171561032657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610650945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a0578181015183820152602001610388565b505050509050019250505060405180910390f35b3480156103c057600080fd5b5061016d61078e565b3480156103d557600080fd5b5061014661079d565b3480156103ea57600080fd5b506103f36107a2565b604080519115158252519081900360200190f35b34801561041357600080fd5b506101466004803603602081101561042a57600080fd5b50356001600160a01b03166107ab565b34801561044657600080fd5b5061046d6004803603602081101561045d57600080fd5b50356001600160a01b03166107db565b6040805192835260208301919091528051918290030190f35b34801561049257600080fd5b5061016d6107f4565b3480156104a757600080fd5b50610146600480360360208110156104be57600080fd5b50356001600160a01b0316610803565b3480156104da57600080fd5b50610146600480360360208110156104f157600080fd5b50356001600160a01b031661088e565b34801561050d57600080fd5b506101466108a0565b34801561052257600080fd5b506101466108a6565b34801561053757600080fd5b506101466004803603604081101561054e57600080fd5b506001600160a01b038135169060200135610940565b6004546000906001600160a01b0316331461058d5761058683600160086109d3565b905061059a565b6105978383610a5c565b90505b92915050565b6002546001600160a01b031681565b67016345785d8a000081565b60016020526000908152604090205481565b6002546000906001600160a01b031633146105f6576105ef60006001806109d3565b9050610640565b6000805483151560ff19909116811790915560408051918252517f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b59809181900360200190a160005b90505b919050565b600061063d826107ab565b81518151600454606092919083906001600160a01b031633146106bd57604080516001808252818301909252906020808301908038833901905050905061069b6000600160086109d3565b816000815181106106a857fe5b6020908102919091010152925061059a915050565b8215806106ca5750828214155b156106fd57604080516001808252818301909252906020808301908038833901905050905061069b60006002600a6109d3565b82604051908082528060200260200182016040528015610727578160200160208202803883390190505b50905060005b838110156107845761076587828151811061074457fe5b602002602001015187838151811061075857fe5b6020026020010151610a5c565b82828151811061077157fe5b602090810291909101015260010161072d565b5095945050505050565b6003546001600160a01b031681565b60f081565b60005460ff1681565b6000805460ff16156107bf57506000610640565b506001600160a01b031660009081526001602052604090205490565b6006602052600090815260409020805460019091015482565b6004546001600160a01b031681565b6002546000906001600160a01b03163314610826576105ef6000600160026109d3565b600380546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517f6c773973d5bcf264b509f4194ceb99e891251f6aabb325523a863c282958b13e929181900390910190a160009392505050565b60076020526000908152604090205481565b60055481565b6003546000906001600160a01b031633146108d0576108c96000600160006109d3565b905061093d565b60028054600380546001600160a01b03198084166001600160a01b03838116919091179095551690556040805192909116808352336020840152815190927fbef9248fe57ae972dd47833f68c43f0b3b2d14217612dfbc804a520a23730d4692908290030190a160009150505b90565b6002546000906001600160a01b031633146109625761058683600160036109d3565b6001600160a01b0383166000818152600760209081526040918290208054908690558251338152918201939093528082018390526060810185905290517ff0aa20c29c1f8e751bfe0a78bc49a520ed14f2dab274087d90d1341d8b76af5c9181900360800190a16000949350505050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73385856002811115610a0457fe5b85600a811115610a1057fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526000608082015290519081900360a00190a1826002811115610a5457fe5b949350505050565b600080610a67611387565b60f0430460010160808201526001600160a01b0385166000908152600760209081526040918290205460e08401908152825191820190925285815282525115610b4d57600060608201526040805160208101825260e083015181529082018190528151610ad49190610db2565b602083015291506000826017811115610ae957fe5b14610b1057610b078560026004856017811115610b0257fe5b610e38565b9250505061059a565b6020808201516040805192830190526005548252610b2d91610ec2565b15610b4857610b078560026006846020015160000151610e38565b610c04565b6001600160a01b038516600081815260066020818152604080842080546060880190815282518085018452969095529290915260019091015483528301919091525115610bf257610ba681604001518260000151610ec9565b8352151560a083015291506000826017811115610bbf57fe5b14610bd857610b078560026005856017811115610b0257fe5b8060a0015115610b485760408101515160c0820152610c04565b60408051602081018252858152908201525b610c118160400151611088565b15610c2357610b0785600260076109d3565b8051610c2e90611088565b15610c4057610b0785600260096109d3565b6001600160a01b03851660009081526007602052604090205415610c78576001600160a01b0385166000908152600760205260408120555b806060015181608001511115610cc8576040805180820182526080830151815282515160208083019182526001600160a01b03891660009081526006909152929092209051815590516001909101555b6001600160a01b038516600090815260016020526040902054815151610cef90879061108d565b815151604080516001600160a01b0389168152602081018490528082018890526060810192909252517fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae79181900360800190a18160a0015115610da65760c0820151825151604080516001600160a01b038a16815260208101899052808201939093526060830191909152517f7221f7a2708437039cc63319145b6b873a40594b9782a3bee45b975e2f3b0f689181900360800190a15b60009695505050505050565b6000610dbc6113e0565b610dc46113e0565b6000610dd08686610ec2565b15610dfd57610ddf86866110b8565b925090506000816017811115610df157fe5b14610df857fe5b610e20565b610e0785876110b8565b925090506000816017811115610e1957fe5b14610e2057fe5b610e2a82876110f2565b9350935050505b9250929050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73386866002811115610e6957fe5b86600a811115610e7557fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526080810185905290519081900360a00190a1836002811115610eb957fe5b95945050505050565b5190511190565b600080610ed46113e0565b610edc6113e0565b506040805160208101909152670de0b6b3a76400008152610efb6113e0565b610f036113e0565b610f0b6113e0565b610f136113e0565b60408051602081019091526005548152600090610f31908790611115565b955090506000816017811115610f4357fe5b14610f6b57604080516020810190915260008082529199509097509550611081945050505050565b610f758b86611134565b935090506000816017811115610f8757fe5b14610faf57604080516020810190915260008082529199509097509550611081945050505050565b610fb98a84610ec2565b15610fd4576000600184985098509850505050505050611081565b60408051602081019091526005548152610fef9087906110b8565b94509050600081601781111561100157fe5b1461102957604080516020810190915260008082529199509097509550611081945050505050565b6110338b85611134565b92509050600081601781111561104557fe5b1461104c57fe5b6110568a8361121d565b156110705750600097506001965094506110819350505050565b6000808b9850985098505050505050505b9250925092565b511590565b60408051602080820183529281526001600160a01b0390931660009081526001909252902090519055565b60006110c26113e0565b6000806110d786600001518660000151611224565b60408051602081019091529081529097909650945050505050565b60006110fc6113e0565b8351835161110a9190611247565b915091509250929050565b600061111f6113e0565b6000806110d7866000015186600001516112f7565b600061113e6113e0565b6000806111538660000151866000015161131d565b9092509050600082601781111561116657fe5b1461118557506040805160208101909152600081529092509050610e31565b60008061119a6706f05b59d3b20000846112f7565b909250905060008260178111156111ad57fe5b146111cf57506040805160208101909152600081529094509250610e31915050565b6000806111e483670de0b6b3a764000061135c565b909250905060008260178111156111f757fe5b146111fe57fe5b604080516020810190915290815260009a909950975050505050505050565b5190511090565b60008083831161123b575060009050818303610e31565b50600490506000610e31565b60006112516113e0565b60008061126686670de0b6b3a764000061131d565b9092509050600082601781111561127957fe5b1461129857506040805160208101909152600081529092509050610e31565b6000806112a5838861135c565b909250905060008260178111156112b857fe5b146112da57506040805160208101909152600081529094509250610e31915050565b604080516020810190915290815260009890975095505050505050565b60008083830184811061130f57600092509050610e31565b506003915060009050610e31565b6000808361133057506000905080610e31565b8383028385828161133d57fe5b041461135157506003915060009050610e31565b600092509050610e31565b600080826113705750600590506000610e31565b600083858161137b57fe5b04915091509250929050565b60405180610100016040528061139b6113e0565b81526020016113a86113e0565b81526020016113b56113e0565b8152602001600081526020016000815260200160001515815260200160008152602001600081525090565b604051806020016040528060008152509056fea265627a7a723158200245571f8ce98bb37e8cccc024bad382162045c264e6b6a0b38e8946da8394cd64736f6c63430005110032000000000000000000000000d830a7413cb25fee57f8115cd64e565b0be466c3
Deployed Bytecode
0x6080604052600436106101085760003560e01c80635c975abb116100955780639964622c116100645780639964622c1461049b5780639e8c4d95146104ce578063c5faf1d514610501578063ccb13cbd14610516578063de9d0e851461052b57610108565b80635c975abb146103de5780635e9a523c14610407578063692374e31461043a578063809597211461048657610108565b806326617c28116100dc57806326617c28146101d157806341976e09146101fd5780634352fa9f14610230578063451b1e3a146103b4578063485feabe146103c957610108565b8062e4768b1461010d57806308f31857146101585780630c9c630114610189578063183f34441461019e575b600080fd5b34801561011957600080fd5b506101466004803603604081101561013057600080fd5b506001600160a01b038135169060200135610564565b60408051918252519081900360200190f35b34801561016457600080fd5b5061016d6105a0565b604080516001600160a01b039092168252519081900360200190f35b34801561019557600080fd5b506101466105af565b3480156101aa57600080fd5b50610146600480360360208110156101c157600080fd5b50356001600160a01b03166105bb565b3480156101dd57600080fd5b50610146600480360360208110156101f457600080fd5b503515156105cd565b34801561020957600080fd5b506101466004803603602081101561022057600080fd5b50356001600160a01b0316610645565b34801561023c57600080fd5b506103646004803603604081101561025357600080fd5b81019060208101813564010000000081111561026e57600080fd5b82018360208201111561028057600080fd5b803590602001918460208302840111640100000000831117156102a257600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156102f257600080fd5b82018360208201111561030457600080fd5b8035906020019184602083028401116401000000008311171561032657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610650945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a0578181015183820152602001610388565b505050509050019250505060405180910390f35b3480156103c057600080fd5b5061016d61078e565b3480156103d557600080fd5b5061014661079d565b3480156103ea57600080fd5b506103f36107a2565b604080519115158252519081900360200190f35b34801561041357600080fd5b506101466004803603602081101561042a57600080fd5b50356001600160a01b03166107ab565b34801561044657600080fd5b5061046d6004803603602081101561045d57600080fd5b50356001600160a01b03166107db565b6040805192835260208301919091528051918290030190f35b34801561049257600080fd5b5061016d6107f4565b3480156104a757600080fd5b50610146600480360360208110156104be57600080fd5b50356001600160a01b0316610803565b3480156104da57600080fd5b50610146600480360360208110156104f157600080fd5b50356001600160a01b031661088e565b34801561050d57600080fd5b506101466108a0565b34801561052257600080fd5b506101466108a6565b34801561053757600080fd5b506101466004803603604081101561054e57600080fd5b506001600160a01b038135169060200135610940565b6004546000906001600160a01b0316331461058d5761058683600160086109d3565b905061059a565b6105978383610a5c565b90505b92915050565b6002546001600160a01b031681565b67016345785d8a000081565b60016020526000908152604090205481565b6002546000906001600160a01b031633146105f6576105ef60006001806109d3565b9050610640565b6000805483151560ff19909116811790915560408051918252517f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b59809181900360200190a160005b90505b919050565b600061063d826107ab565b81518151600454606092919083906001600160a01b031633146106bd57604080516001808252818301909252906020808301908038833901905050905061069b6000600160086109d3565b816000815181106106a857fe5b6020908102919091010152925061059a915050565b8215806106ca5750828214155b156106fd57604080516001808252818301909252906020808301908038833901905050905061069b60006002600a6109d3565b82604051908082528060200260200182016040528015610727578160200160208202803883390190505b50905060005b838110156107845761076587828151811061074457fe5b602002602001015187838151811061075857fe5b6020026020010151610a5c565b82828151811061077157fe5b602090810291909101015260010161072d565b5095945050505050565b6003546001600160a01b031681565b60f081565b60005460ff1681565b6000805460ff16156107bf57506000610640565b506001600160a01b031660009081526001602052604090205490565b6006602052600090815260409020805460019091015482565b6004546001600160a01b031681565b6002546000906001600160a01b03163314610826576105ef6000600160026109d3565b600380546001600160a01b038481166001600160a01b0319831681179093556040805191909216808252602082019390935281517f6c773973d5bcf264b509f4194ceb99e891251f6aabb325523a863c282958b13e929181900390910190a160009392505050565b60076020526000908152604090205481565b60055481565b6003546000906001600160a01b031633146108d0576108c96000600160006109d3565b905061093d565b60028054600380546001600160a01b03198084166001600160a01b03838116919091179095551690556040805192909116808352336020840152815190927fbef9248fe57ae972dd47833f68c43f0b3b2d14217612dfbc804a520a23730d4692908290030190a160009150505b90565b6002546000906001600160a01b031633146109625761058683600160036109d3565b6001600160a01b0383166000818152600760209081526040918290208054908690558251338152918201939093528082018390526060810185905290517ff0aa20c29c1f8e751bfe0a78bc49a520ed14f2dab274087d90d1341d8b76af5c9181900360800190a16000949350505050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73385856002811115610a0457fe5b85600a811115610a1057fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526000608082015290519081900360a00190a1826002811115610a5457fe5b949350505050565b600080610a67611387565b60f0430460010160808201526001600160a01b0385166000908152600760209081526040918290205460e08401908152825191820190925285815282525115610b4d57600060608201526040805160208101825260e083015181529082018190528151610ad49190610db2565b602083015291506000826017811115610ae957fe5b14610b1057610b078560026004856017811115610b0257fe5b610e38565b9250505061059a565b6020808201516040805192830190526005548252610b2d91610ec2565b15610b4857610b078560026006846020015160000151610e38565b610c04565b6001600160a01b038516600081815260066020818152604080842080546060880190815282518085018452969095529290915260019091015483528301919091525115610bf257610ba681604001518260000151610ec9565b8352151560a083015291506000826017811115610bbf57fe5b14610bd857610b078560026005856017811115610b0257fe5b8060a0015115610b485760408101515160c0820152610c04565b60408051602081018252858152908201525b610c118160400151611088565b15610c2357610b0785600260076109d3565b8051610c2e90611088565b15610c4057610b0785600260096109d3565b6001600160a01b03851660009081526007602052604090205415610c78576001600160a01b0385166000908152600760205260408120555b806060015181608001511115610cc8576040805180820182526080830151815282515160208083019182526001600160a01b03891660009081526006909152929092209051815590516001909101555b6001600160a01b038516600090815260016020526040902054815151610cef90879061108d565b815151604080516001600160a01b0389168152602081018490528082018890526060810192909252517fdd71a1d19fcba687442a1d5c58578f1e409af71a79d10fd95a4d66efd8fa9ae79181900360800190a18160a0015115610da65760c0820151825151604080516001600160a01b038a16815260208101899052808201939093526060830191909152517f7221f7a2708437039cc63319145b6b873a40594b9782a3bee45b975e2f3b0f689181900360800190a15b60009695505050505050565b6000610dbc6113e0565b610dc46113e0565b6000610dd08686610ec2565b15610dfd57610ddf86866110b8565b925090506000816017811115610df157fe5b14610df857fe5b610e20565b610e0785876110b8565b925090506000816017811115610e1957fe5b14610e2057fe5b610e2a82876110f2565b9350935050505b9250929050565b60007f96f29b65cebbd6816352fb242b6af7180b49e8a09e19e589225d35bc8444f0b73386866002811115610e6957fe5b86600a811115610e7557fe5b604080516001600160a01b0395861681529390941660208401528284019190915260608201526080810185905290519081900360a00190a1836002811115610eb957fe5b95945050505050565b5190511190565b600080610ed46113e0565b610edc6113e0565b506040805160208101909152670de0b6b3a76400008152610efb6113e0565b610f036113e0565b610f0b6113e0565b610f136113e0565b60408051602081019091526005548152600090610f31908790611115565b955090506000816017811115610f4357fe5b14610f6b57604080516020810190915260008082529199509097509550611081945050505050565b610f758b86611134565b935090506000816017811115610f8757fe5b14610faf57604080516020810190915260008082529199509097509550611081945050505050565b610fb98a84610ec2565b15610fd4576000600184985098509850505050505050611081565b60408051602081019091526005548152610fef9087906110b8565b94509050600081601781111561100157fe5b1461102957604080516020810190915260008082529199509097509550611081945050505050565b6110338b85611134565b92509050600081601781111561104557fe5b1461104c57fe5b6110568a8361121d565b156110705750600097506001965094506110819350505050565b6000808b9850985098505050505050505b9250925092565b511590565b60408051602080820183529281526001600160a01b0390931660009081526001909252902090519055565b60006110c26113e0565b6000806110d786600001518660000151611224565b60408051602081019091529081529097909650945050505050565b60006110fc6113e0565b8351835161110a9190611247565b915091509250929050565b600061111f6113e0565b6000806110d7866000015186600001516112f7565b600061113e6113e0565b6000806111538660000151866000015161131d565b9092509050600082601781111561116657fe5b1461118557506040805160208101909152600081529092509050610e31565b60008061119a6706f05b59d3b20000846112f7565b909250905060008260178111156111ad57fe5b146111cf57506040805160208101909152600081529094509250610e31915050565b6000806111e483670de0b6b3a764000061135c565b909250905060008260178111156111f757fe5b146111fe57fe5b604080516020810190915290815260009a909950975050505050505050565b5190511090565b60008083831161123b575060009050818303610e31565b50600490506000610e31565b60006112516113e0565b60008061126686670de0b6b3a764000061131d565b9092509050600082601781111561127957fe5b1461129857506040805160208101909152600081529092509050610e31565b6000806112a5838861135c565b909250905060008260178111156112b857fe5b146112da57506040805160208101909152600081529094509250610e31915050565b604080516020810190915290815260009890975095505050505050565b60008083830184811061130f57600092509050610e31565b506003915060009050610e31565b6000808361133057506000905080610e31565b8383028385828161133d57fe5b041461135157506003915060009050610e31565b600092509050610e31565b600080826113705750600590506000610e31565b600083858161137b57fe5b04915091509250929050565b60405180610100016040528061139b6113e0565b81526020016113a86113e0565b81526020016113b56113e0565b8152602001600081526020016000815260200160001515815260200160008152602001600081525090565b604051806020016040528060008152509056fea265627a7a723158200245571f8ce98bb37e8cccc024bad382162045c264e6b6a0b38e8946da8394cd64736f6c63430005110032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d830a7413cb25fee57f8115cd64e565b0be466c3
-----Decoded View---------------
Arg [0] : _poster (address): 0xd830A7413CB25FEe57f8115CD64E565B0Be466c3
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d830a7413cb25fee57f8115cd64e565b0be466c3
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.