Skip to content

Commit

Permalink
Prevented users from front-running the Draw timestamp on Ethereum (#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
asselstine committed Sep 30, 2021
1 parent cdaa546 commit 42cc633
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
12 changes: 9 additions & 3 deletions contracts/DrawBeacon.sol
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ contract DrawBeacon is IDrawBeacon,
return isRngRequested() && isRngCompleted();
}

/// @notice Calculates the next beacon start time, assuming all beacon periods have occurred between the last and now.
/// @return The next beacon period start time
function calculateNextBeaconPeriodStartTimeFromCurrentTime() external view returns (uint64) {
return _calculateNextBeaconPeriodStartTime(beaconPeriodStartedAt, beaconPeriodSeconds, _currentTime());
}

/// @inheritdoc IDrawBeacon
function calculateNextBeaconPeriodStartTime(uint256 currentTime) external view override returns (uint64) {
return _calculateNextBeaconPeriodStartTime(beaconPeriodStartedAt, beaconPeriodSeconds, uint64(currentTime));
Expand Down Expand Up @@ -230,7 +236,8 @@ contract DrawBeacon is IDrawBeacon,
DrawLib.Draw memory _draw = DrawLib.Draw({
winningRandomNumber: randomNumber,
drawId: _nextDrawId,
timestamp: _time,
// must use the startAward() timestamp to prevent front-running
timestamp: rngRequest.requestedAt,
beaconPeriodStartedAt: _beaconPeriodStartedAt,
beaconPeriodSeconds: _beaconPeriodSeconds
});
Expand All @@ -239,13 +246,12 @@ contract DrawBeacon is IDrawBeacon,
* The DrawBeacon (deployed on L1) will have a Manager role authorized to push history onto DrawHistory.
*/
drawHistory.pushDraw(_draw);

// to avoid clock drift, we should calculate the start time based on the previous period start time.
_beaconPeriodStartedAt = _calculateNextBeaconPeriodStartTime(_beaconPeriodStartedAt, _beaconPeriodSeconds, _time);
beaconPeriodStartedAt = _beaconPeriodStartedAt;
nextDrawId = _nextDrawId + 1;


// Reset the rngReqeust state so Beacon period can start again.
delete rngRequest;

Expand Down
8 changes: 6 additions & 2 deletions test/DrawBeacon.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Signer } from '@ethersproject/abstract-signer';
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
import { constants, Contract, ContractFactory, utils } from 'ethers';
import { expect } from 'chai';
import { increaseTime } from './helpers/increaseTime';

const debug = require('debug')('pt:DrawBeacon.test.ts');

Expand Down Expand Up @@ -319,6 +320,9 @@ describe('DrawBeacon', () => {
beaconPeriodSeconds
]).returns(1)

await drawBeacon.setCurrentTime((await drawBeacon.beaconPeriodEndAt()).add(1000))
const nextStartTime = await drawBeacon.calculateNextBeaconPeriodStartTimeFromCurrentTime()

expect(await drawBeacon.completeDraw())
.to.emit(drawBeacon, 'DrawCompleted')
.withArgs(
Expand All @@ -328,10 +332,10 @@ describe('DrawBeacon', () => {
.and.to.emit(drawBeacon, 'BeaconPeriodStarted')
.withArgs(
wallet.address,
beaconPeriodEndAt
nextStartTime
)

expect(await drawBeacon.beaconPeriodStartedAt()).to.equal(beaconPeriodEndAt);
expect(await drawBeacon.getBeaconPeriodStartedAt()).to.equal(nextStartTime)
});
});
})
Expand Down

0 comments on commit 42cc633

Please sign in to comment.