[entropy] audit 4. users can influence the Entropy revealed result (#1179)

* add a check for blockhash

* add comment

* update test name

* comment update

* change block number

* change order for assertions

* pre commit run

* names and comments
This commit is contained in:
Dev Kalra 2023-12-14 17:57:45 +05:30 committed by GitHub
parent d420786166
commit 5d951ee755
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 2 deletions

View File

@ -259,7 +259,18 @@ abstract contract Entropy is IEntropy, EntropyState {
bytes32 blockHash = bytes32(uint256(0)); bytes32 blockHash = bytes32(uint256(0));
if (req.useBlockhash) { if (req.useBlockhash) {
blockHash = blockhash(req.blockNumber); bytes32 _blockHash = blockhash(req.blockNumber);
// The `blockhash` function will return zero if the req.blockNumber is equal to the current
// block number, or if it is not within the 256 most recent blocks. This allows the user to
// select between two random numbers by executing the reveal function in the same block as the
// request, or after 256 blocks. This gives each user two chances to get a favorable result on
// each request.
// Revert this transaction for when the blockHash is 0;
if (_blockHash == bytes32(uint256(0)))
revert EntropyErrors.BlockhashUnavailable();
blockHash = _blockHash;
} }
randomNumber = combineRandomValues( randomNumber = combineRandomValues(

View File

@ -405,6 +405,81 @@ contract EntropyTest is Test, EntropyTestUtils {
true true
); );
vm.roll(1235);
assertRevealSucceeds(
user2,
provider1,
sequenceNumber,
42,
provider1Proofs[sequenceNumber],
blockhash(1234)
);
}
function testNoCheckOnBlockNumberWhenNoBlockHashUsed() public {
vm.roll(1234);
uint64 sequenceNumber = request(user2, provider1, 42, false);
vm.roll(1236);
assertRevealSucceeds(
user2,
provider1,
sequenceNumber,
42,
provider1Proofs[sequenceNumber],
ALL_ZEROS
);
vm.roll(1234);
sequenceNumber = request(user2, provider1, 42, false);
vm.roll(1234);
assertRevealSucceeds(
user2,
provider1,
sequenceNumber,
42,
provider1Proofs[sequenceNumber],
ALL_ZEROS
);
vm.roll(1234);
sequenceNumber = request(user2, provider1, 42, false);
vm.roll(1234 + 257);
assertRevealSucceeds(
user2,
provider1,
sequenceNumber,
42,
provider1Proofs[sequenceNumber],
ALL_ZEROS
);
}
function testCheckOnBlockNumberWhenBlockHashUsed() public {
vm.roll(1234);
uint64 sequenceNumber = request(user2, provider1, 42, true);
vm.roll(1234);
assertRevealReverts(
user2,
provider1,
sequenceNumber,
42,
provider1Proofs[sequenceNumber]
);
vm.roll(1234 + 257);
assertRevealReverts(
user2,
provider1,
sequenceNumber,
42,
provider1Proofs[sequenceNumber]
);
vm.roll(1235);
assertRevealSucceeds( assertRevealSucceeds(
user2, user2,
provider1, provider1,

View File

@ -107,8 +107,9 @@ contract EntropyGasBenchmark is Test, EntropyTestUtils {
function testBasicFlow() public { function testBasicFlow() public {
uint userRandom = 42; uint userRandom = 42;
vm.roll(10);
uint64 sequenceNumber = requestHelper(user1, userRandom, true); uint64 sequenceNumber = requestHelper(user1, userRandom, true);
vm.roll(12);
revealHelper(sequenceNumber, userRandom); revealHelper(sequenceNumber, userRandom);
} }
} }

View File

@ -22,4 +22,6 @@ library EntropyErrors {
error InvalidUpgradeMagic(); error InvalidUpgradeMagic();
// The msg.sender is not allowed to invoke this call. // The msg.sender is not allowed to invoke this call.
error Unauthorized(); error Unauthorized();
// The blockhash is 0.
error BlockhashUnavailable();
} }