diff --git a/contracts/MedianOracle.sol b/contracts/MedianOracle.sol index 00ab8609..538a3cfc 100644 --- a/contracts/MedianOracle.sol +++ b/contracts/MedianOracle.sol @@ -108,13 +108,21 @@ 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); + // unless past one is already expired + require( + timestamps[index_past] < minValidTimestamp || + timestamps[index_recent] <= maxValidTimestamp + ); reports[index_past].timestamp = now; reports[index_past].payload = payload; @@ -127,6 +135,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/MedianOracle.ts b/test/unit/MedianOracle.ts index 19636f6b..d1f42e04 100644 --- a/test/unit/MedianOracle.ts +++ b/test/unit/MedianOracle.ts @@ -91,11 +91,55 @@ describe('MedianOracle:pushReport', async function () { it('should only push from authorized source', async function () { await expect(oracle.connect(A).pushReport(payload)).to.be.reverted }) - it('should fail if reportDelaySec did not pass since the previous push', async function () { + + it('should pass if reportDelaySec did not pass since the previous push, but previous report non-existent', async function () { + await oracle.addProvider(await A.getAddress()) + await oracle.connect(A).pushReport(payload) + await oracle.connect(A).pushReport(payload) + }) + + it('should pass if reportDelaySec did pass since the previous push, and previous report non-existent', async function () { await oracle.addProvider(await A.getAddress()) await oracle.connect(A).pushReport(payload) + await increaseTime(20) + await oracle.connect(A).pushReport(payload) + }) + + it('should pass if reportDelaySec did pass since the previous push, but previous report expired', async function () { + await oracle.addProvider(await A.getAddress()) + await oracle.connect(A).pushReport(payload) + await increaseTime(70) + await oracle.connect(A).pushReport(payload) + await oracle.connect(A).pushReport(payload) + }) + + it('should pass if reportDelaySec did pass since the previous push, and previous report expired', async function () { + await oracle.addProvider(await A.getAddress()) + await oracle.connect(A).pushReport(payload) + await increaseTime(70) + await oracle.connect(A).pushReport(payload) + await increaseTime(20) + await oracle.connect(A).pushReport(payload) + }) + + it('should fail if reportDelaySec did not pass since the previous push, and previous report not expired', async function () { + await oracle.addProvider(await A.getAddress()) + await oracle.connect(A).pushReport(payload) + await increaseTime(20) + await oracle.connect(A).pushReport(payload) + await expect(oracle.connect(A).pushReport(payload)).to.be.reverted + }) + + it('should pass if reportDelaySec did pass since the previous push, and previous report not expired', async function () { + await oracle.addProvider(await A.getAddress()) + await oracle.connect(A).pushReport(payload) + await increaseTime(20) + await oracle.connect(A).pushReport(payload) + await increaseTime(20) + await oracle.connect(A).pushReport(payload) await expect(oracle.connect(A).pushReport(payload)).to.be.reverted }) + it('should emit ProviderReportPushed message', async function () { oracle.addProvider(await A.getAddress()) const tx = await oracle.connect(A).pushReport(payload)