diff --git a/contracts/MedianOracle.sol b/contracts/MedianOracle.sol index bce5046..98c00a6 100644 --- a/contracts/MedianOracle.sol +++ b/contracts/MedianOracle.sol @@ -120,13 +120,18 @@ contract MedianOracle is Ownable, IOracle { Report[2] storage reports = providerReports[providerAddress]; uint256[2] memory timestamps = [reports[0].timestamp, reports[1].timestamp]; + // Checks that this providerAddress is already whitelisted require(timestamps[0] > 0); uint8 index_recent = timestamps[0] >= timestamps[1] ? 0 : 1; uint8 index_past = 1 - index_recent; + uint256 minValidTimestamp = now.sub(reportExpirationTimeSec); + uint256 maxValidTimestamp = now.sub(reportDelaySec); + // Check that the push is not too soon after the last one. - require(timestamps[index_recent].add(reportDelaySec) <= now); + require(timestamps[index_past] < minValidTimestamp || + timestamps[index_recent] <= maxValidTimestamp); reports[index_past].timestamp = now; reports[index_past].payload = payload; @@ -140,6 +145,7 @@ contract MedianOracle is Ownable, IOracle { function purgeReports() external { address providerAddress = msg.sender; + // Check that this providerAddress is already whitelisted require (providerReports[providerAddress][0].timestamp > 0); providerReports[providerAddress][0].timestamp=1; providerReports[providerAddress][1].timestamp=1; diff --git a/test/unit/median_oracle.js b/test/unit/median_oracle.js index c51fcc0..500c97e 100644 --- a/test/unit/median_oracle.js +++ b/test/unit/median_oracle.js @@ -69,6 +69,15 @@ contract('MedianOracle:addProvider', async function (accounts) { }); }); +// TODO(naguib): Add test scenarios for: +// Reported rates (ordered by time) are r1, r2. The new rate is r. +// r2 < minValidTimestamp +// r1 < minValidTimestamp < r2 < maxValidTimestamp +// minValidTimestamp < r1 < r2 < maxValidTimestamp +// r1 < minValidTimestamp < maxValidTimestamp < r2 +// minValidTimestamp < r1 < maxValidTimestamp < r2 +// maxValidTimestamp < r1 + contract('MedianOracle:pushReport', async function (accounts) { before(async function () { await setupContractsAndAccounts(accounts); @@ -77,7 +86,8 @@ contract('MedianOracle:pushReport', async function (accounts) { expect(await chain.isEthException(oracle.pushReport(1000000000000000000, { from: A }))).to.be.true; oracle.addProvider(A, { from: deployer }); r = await oracle.pushReport(1000000000000000000, { from: A }); - // should fail if reportDelaySec did not pass since the previous push + r = await oracle.pushReport(1000000000000000000, { from: A }); + // should fail if push is too early expect(await chain.isEthException(oracle.pushReport(1000000000000000000, { from: A }))).to.be.true; }); it('should emit ProviderReportPushed message', async function () {