feat(entropy_contracts): don't call an address if it is an Eoa in reveal callback (#1395)

* don't call an address if it is an Eoa

* fix comment

* update comment
This commit is contained in:
Dev Kalra 2024-03-28 14:12:36 +05:30 committed by GitHub
parent 0e6484daca
commit 02e196e924
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 11 deletions

View File

@ -364,8 +364,9 @@ abstract contract Entropy is IEntropy, EntropyState {
}
// Fulfill a request for a random number and call back the requester. This method validates the provided userRandomness
// and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated,
// this function calls the requester's entropyCallback method with the sequence number and the random number as arguments.
// and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated
// and the requestor address is a contract address, this function calls the requester's entropyCallback method with the
// sequence number and the random number as arguments. Else if the requestor is an EOA, it won't call it.
//
// Note that this function can only be called once per in-flight request. Calling this function deletes the stored
// request information (so that the contract doesn't use a linear amount of storage in the number of requests).
@ -405,12 +406,19 @@ abstract contract Entropy is IEntropy, EntropyState {
clearRequest(provider, sequenceNumber);
// Check if the callAddress is a contract account.
uint len;
assembly {
len := extcodesize(callAddress)
}
if (len != 0) {
IEntropyConsumer(callAddress)._entropyCallback(
sequenceNumber,
provider,
randomNumber
);
}
}
function getProviderInfo(
address provider

View File

@ -799,7 +799,7 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
vm.stopPrank();
}
function testRequestWithCallbackAndRevealWithCallback() public {
function testRequestWithCallbackAndRevealWithCallbackByContract() public {
bytes32 userRandomNumber = bytes32(uint(42));
uint fee = random.getFee(provider1);
EntropyConsumer consumer = new EntropyConsumer(address(random));
@ -853,6 +853,46 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
assertEq(reqAfterReveal.sequenceNumber, 0);
}
function testRequestWithCallbackAndRevealWithCallbackByEoa() public {
bytes32 userRandomNumber = bytes32(uint(42));
uint fee = random.getFee(provider1);
vm.deal(user1, fee);
vm.prank(user1);
uint64 assignedSequenceNumber = random.requestWithCallback{value: fee}(
provider1,
userRandomNumber
);
EntropyStructs.Request memory req = random.getRequest(
provider1,
assignedSequenceNumber
);
bytes32 blockHash = bytes32(uint256(0));
vm.expectEmit(false, false, false, true, address(random));
emit RevealedWithCallback(
req,
userRandomNumber,
provider1Proofs[assignedSequenceNumber],
random.combineRandomValues(
userRandomNumber,
provider1Proofs[assignedSequenceNumber],
0
)
);
random.revealWithCallback(
provider1,
assignedSequenceNumber,
userRandomNumber,
provider1Proofs[assignedSequenceNumber]
);
EntropyStructs.Request memory reqAfterReveal = random.getRequest(
provider1,
assignedSequenceNumber
);
assertEq(reqAfterReveal.sequenceNumber, 0);
}
function testRequestAndRevealWithCallback() public {
uint64 sequenceNumber = request(user2, provider1, 42, false);
assertEq(random.getRequest(provider1, sequenceNumber).requester, user2);

View File

@ -51,9 +51,10 @@ interface IEntropy is EntropyEvents {
bytes32 userRandomNumber
) external payable returns (uint64 assignedSequenceNumber);
// Fulfill a request for a random number. This method validates the provided userRevelation and provider's proof
// against the corresponding commitments in the in-flight request. If both values are validated, this function returns
// the corresponding random number.
// Fulfill a request for a random number and call back the requester. This method validates the provided userRandomness
// and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated
// and the requestor address is a contract address, this function calls the requester's entropyCallback method with the
// sequence number and the random number as arguments. Else if the requestor is an EOA, it won't call it.
//
// Note that this function can only be called once per in-flight request. Calling this function deletes the stored
// request information (so that the contract doesn't use a linear amount of storage in the number of requests).