Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support sequencer liveness #46

Open
wants to merge 1 commit into
base: op
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 34 additions & 14 deletions contracts/PriceOracle/PriceOracleProxyUSD.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import "../Exponential.sol";
import "../EIP20Interface.sol";

contract PriceOracleProxyUSD is PriceOracle, Exponential {
uint256 private constant GRACE_PERIOD_TIME = 3600;

/// @notice ChainLink aggregator base, currently support USD and ETH
enum AggregatorBase {
USD,
Expand Down Expand Up @@ -37,18 +39,22 @@ contract PriceOracleProxyUSD is PriceOracle, Exponential {
/// @notice The ETH-USD aggregator address
AggregatorV3Interface public ethUsdAggregator;

/// @notice The sequencer uptime feed address
AggregatorV3Interface public sequencerUptimeFeed;

/**
* @param admin_ The address of admin to set aggregators
* @param v1PriceOracle_ The v1 price oracle
* @param ethUsdAggregator_ The ETH-USD aggregator address
* @param sequencerUptimeFeed_ The sequencer uptime feed address
*/
constructor(
address admin_,
address v1PriceOracle_,
address ethUsdAggregator_
) public {
constructor(address admin_, address v1PriceOracle_, address ethUsdAggregator_, address sequencerUptimeFeed_)
public
{
admin = admin_;
v1PriceOracle = V1PriceOracleInterface(v1PriceOracle_);
ethUsdAggregator = AggregatorV3Interface(ethUsdAggregator_);
sequencerUptimeFeed = AggregatorV3Interface(sequencerUptimeFeed_);
}

/**
Expand All @@ -67,25 +73,39 @@ contract PriceOracleProxyUSD is PriceOracle, Exponential {
price = mul_(price, Exp({mantissa: getPriceFromChainlink(ethUsdAggregator)}));
}
uint256 underlyingDecimals = EIP20Interface(CErc20(cTokenAddress).underlying()).decimals();
return mul_(price, 10**(18 - underlyingDecimals));
return mul_(price, 10 ** (18 - underlyingDecimals));
}

return getPriceFromV1(cTokenAddress);
}

/*** Internal fucntions ***/
/**
* Internal fucntions
*/

/**
* @notice Get price from ChainLink
* @param aggregator The ChainLink aggregator to get the price of
* @return The price
*/
function getPriceFromChainlink(AggregatorV3Interface aggregator) internal view returns (uint256) {
(, int256 price, , , ) = aggregator.latestRoundData();
(, int256 answer, uint256 startedAt,,) = sequencerUptimeFeed.latestRoundData();

// Answer == 0: Sequencer is up
// Answer == 1: Sequencer is down
bool isSequencerUp = answer == 0;
require(isSequencerUp, "sequencer down");

// Make sure the grace period has passed after the
// sequencer is back up.
uint256 timeSinceUp = sub_(block.timestamp, startedAt);
require(timeSinceUp > GRACE_PERIOD_TIME, "grace period not over");

(, int256 price,,,) = aggregator.latestRoundData();
require(price > 0, "invalid price");

// Extend the decimals to 1e18.
return mul_(uint256(price), 10**(18 - uint256(aggregator.decimals())));
return mul_(uint256(price), 10 ** (18 - uint256(aggregator.decimals())));
}

/**
Expand All @@ -98,7 +118,9 @@ contract PriceOracleProxyUSD is PriceOracle, Exponential {
return v1PriceOracle.assetPrices(underlying);
}

/*** Admin or guardian functions ***/
/**
* Admin or guardian functions
*/

event AggregatorUpdated(address cTokenAddress, address source, AggregatorBase base);
event SetGuardian(address guardian);
Expand Down Expand Up @@ -141,10 +163,8 @@ contract PriceOracleProxyUSD is PriceOracle, Exponential {
if (sources[i] != address(0)) {
require(msg.sender == admin, "guardian may only clear the aggregator");
}
aggregators[cTokenAddresses[i]] = AggregatorInfo({
source: AggregatorV3Interface(sources[i]),
base: bases[i]
});
aggregators[cTokenAddresses[i]] =
AggregatorInfo({source: AggregatorV3Interface(sources[i]), base: bases[i]});
emit AggregatorUpdated(cTokenAddresses[i], sources[i], bases[i]);
}
}
Expand Down