Skip to content

Commit e20dcd9

Browse files
fix(RNG): simplification
1 parent e1718e5 commit e20dcd9

File tree

1 file changed

+22
-45
lines changed

1 file changed

+22
-45
lines changed

contracts/standard/rng/BeaconRNG.sol

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ import "./RNG.sol";
1313
/**
1414
* @title Random Number Generator using beacon chain random opcode
1515
*/
16-
contract BeaconRNG is RNG {
16+
contract BeaconRNG {
1717

1818
uint public constant LOOKAHEAD = 132; // Number of blocks that has to pass before obtaining the random number. 4 epochs + 4 slots, according to EIP-4399.
1919
uint public constant ERROR = 32; // Number of blocks after which the lookahead gets reset, so eligible blocks after lookahead don't go long distance, to avoid a possiblity for manipulation.
2020

2121
RNG public blockhashRNG; // Address of blockhashRNG to fall back on.
22-
mapping (uint => uint) public randomNumber; // randomNumber[_requestedBlock] is the random number for this requested block, 0 otherwise.
23-
mapping (uint => uint) public startingBlock; // The starting block number for lookahead countdown. startingBlock[_requestedBlock].
22+
mapping (uint => uint) public randomNumber; // randomNumber[_block] is the random number for this requested block, 0 otherwise.
2423

2524
/** @dev Constructor.
2625
* @param _blockhashRNG The blockhash RNG deployed contract address.
@@ -30,58 +29,36 @@ contract BeaconRNG is RNG {
3029
}
3130

3231
/**
33-
* @dev Since we don't really need to incentivize requesting the beacon chain randomness,
34-
* this is a stub implementation required for backwards compatibility with the
35-
* RNG interface.
36-
* @notice All the ETH sent here will be lost forever.
37-
* @param _block Block the random number is linked to.
38-
*/
39-
function contribute(uint _block) public payable {}
40-
41-
/**
42-
* @dev Request a random number.
43-
* @dev Since the beacon chain randomness is not related to a block
44-
* we can call ahead its getRN function to check if the PoS merge has happened or not.
45-
*
46-
* @param _block Block linked to the request.
32+
* @dev Request a random number. It is not used by this contract and only exists for backward compatibility.
4733
*/
48-
function requestRN(uint _block) public payable {
49-
// Use the old RNG pre-Merge.
50-
if (block.difficulty <= 2**64) {
51-
blockhashRNG.contribute(_block);
52-
} else {
53-
if (startingBlock[_block] == 0) {
54-
startingBlock[_block] = _block; // Starting block is equal to requested by default.
55-
}
56-
contribute(_block);
57-
}
58-
}
34+
function requestRN(uint /*_block*/) public pure {}
5935

6036
/**
61-
* @dev Get the random number.
37+
* @dev Get aт uncorrelated random number.
6238
* @param _block Block the random number is linked to.
6339
* @return RN Random Number. If the number is not ready or has not been required 0 instead.
6440
*/
65-
function getRN(uint _block) public returns (uint) {
66-
// if beacon chain randomness is zero
67-
// fallback to blockhash RNG
41+
function getUncorrelatedRN(uint _block) public returns (uint) {
42+
// Pre-Merge.
6843
if (block.difficulty <= 2**64) {
69-
return blockhashRNG.getRN(_block);
70-
} else {
71-
// Reset the starting block if too many blocks passed since lookahead.
72-
if (block.number > startingBlock[_block] + LOOKAHEAD + ERROR) {
73-
startingBlock[_block] = block.number;
74-
}
75-
if (block.number < startingBlock[_block] + LOOKAHEAD) {
76-
// Beacon chain returns the random number, but sufficient number of blocks hasn't been mined yet.
77-
// In this case signal to the court that RN isn't ready.
44+
uint baseRN = blockhashRNG.getRN(_block);
45+
if (baseRN == 0) {
7846
return 0;
47+
} else {
48+
return uint(keccak256(abi.encodePacked(msg.sender, baseRN)));
7949
}
80-
81-
if (randomNumber[_block] == 0) {
82-
randomNumber[_block] = block.difficulty;
50+
// Post-Merge.
51+
} else {
52+
if (block.number > _block && (block.number - _block) % (LOOKAHEAD + ERROR) > LOOKAHEAD) {
53+
// Eligible block number should exceed LOOKAHEAD but shouldn't be higher than LOOKAHEAD + ERROR.
54+
// In case of the latter LOOKAHEAD gets reset.
55+
if (randomNumber[_block] == 0) {
56+
randomNumber[_block] = block.difficulty;
57+
}
58+
return uint(keccak256(abi.encodePacked(msg.sender, randomNumber[_block])));
59+
} else {
60+
return 0;
8361
}
84-
return randomNumber[_block];
8562
}
8663
}
8764
}

0 commit comments

Comments
 (0)