Skip to content

Commit 02e196e

Browse files
author
Dev Kalra
authored
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
1 parent 0e6484d commit 02e196e

File tree

3 files changed

+60
-11
lines changed

3 files changed

+60
-11
lines changed

target_chains/ethereum/contracts/contracts/entropy/Entropy.sol

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,9 @@ abstract contract Entropy is IEntropy, EntropyState {
364364
}
365365

366366
// Fulfill a request for a random number and call back the requester. This method validates the provided userRandomness
367-
// and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated,
368-
// this function calls the requester's entropyCallback method with the sequence number and the random number as arguments.
367+
// and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated
368+
// and the requestor address is a contract address, this function calls the requester's entropyCallback method with the
369+
// sequence number and the random number as arguments. Else if the requestor is an EOA, it won't call it.
369370
//
370371
// Note that this function can only be called once per in-flight request. Calling this function deletes the stored
371372
// request information (so that the contract doesn't use a linear amount of storage in the number of requests).
@@ -405,11 +406,18 @@ abstract contract Entropy is IEntropy, EntropyState {
405406

406407
clearRequest(provider, sequenceNumber);
407408

408-
IEntropyConsumer(callAddress)._entropyCallback(
409-
sequenceNumber,
410-
provider,
411-
randomNumber
412-
);
409+
// Check if the callAddress is a contract account.
410+
uint len;
411+
assembly {
412+
len := extcodesize(callAddress)
413+
}
414+
if (len != 0) {
415+
IEntropyConsumer(callAddress)._entropyCallback(
416+
sequenceNumber,
417+
provider,
418+
randomNumber
419+
);
420+
}
413421
}
414422

415423
function getProviderInfo(

target_chains/ethereum/contracts/forge-test/Entropy.t.sol

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
799799
vm.stopPrank();
800800
}
801801

802-
function testRequestWithCallbackAndRevealWithCallback() public {
802+
function testRequestWithCallbackAndRevealWithCallbackByContract() public {
803803
bytes32 userRandomNumber = bytes32(uint(42));
804804
uint fee = random.getFee(provider1);
805805
EntropyConsumer consumer = new EntropyConsumer(address(random));
@@ -853,6 +853,46 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
853853
assertEq(reqAfterReveal.sequenceNumber, 0);
854854
}
855855

856+
function testRequestWithCallbackAndRevealWithCallbackByEoa() public {
857+
bytes32 userRandomNumber = bytes32(uint(42));
858+
uint fee = random.getFee(provider1);
859+
vm.deal(user1, fee);
860+
vm.prank(user1);
861+
uint64 assignedSequenceNumber = random.requestWithCallback{value: fee}(
862+
provider1,
863+
userRandomNumber
864+
);
865+
EntropyStructs.Request memory req = random.getRequest(
866+
provider1,
867+
assignedSequenceNumber
868+
);
869+
bytes32 blockHash = bytes32(uint256(0));
870+
871+
vm.expectEmit(false, false, false, true, address(random));
872+
emit RevealedWithCallback(
873+
req,
874+
userRandomNumber,
875+
provider1Proofs[assignedSequenceNumber],
876+
random.combineRandomValues(
877+
userRandomNumber,
878+
provider1Proofs[assignedSequenceNumber],
879+
0
880+
)
881+
);
882+
random.revealWithCallback(
883+
provider1,
884+
assignedSequenceNumber,
885+
userRandomNumber,
886+
provider1Proofs[assignedSequenceNumber]
887+
);
888+
889+
EntropyStructs.Request memory reqAfterReveal = random.getRequest(
890+
provider1,
891+
assignedSequenceNumber
892+
);
893+
assertEq(reqAfterReveal.sequenceNumber, 0);
894+
}
895+
856896
function testRequestAndRevealWithCallback() public {
857897
uint64 sequenceNumber = request(user2, provider1, 42, false);
858898
assertEq(random.getRequest(provider1, sequenceNumber).requester, user2);

target_chains/ethereum/entropy_sdk/solidity/IEntropy.sol

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ interface IEntropy is EntropyEvents {
5151
bytes32 userRandomNumber
5252
) external payable returns (uint64 assignedSequenceNumber);
5353

54-
// Fulfill a request for a random number. This method validates the provided userRevelation and provider's proof
55-
// against the corresponding commitments in the in-flight request. If both values are validated, this function returns
56-
// the corresponding random number.
54+
// Fulfill a request for a random number and call back the requester. This method validates the provided userRandomness
55+
// and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated
56+
// and the requestor address is a contract address, this function calls the requester's entropyCallback method with the
57+
// sequence number and the random number as arguments. Else if the requestor is an EOA, it won't call it.
5758
//
5859
// Note that this function can only be called once per in-flight request. Calling this function deletes the stored
5960
// request information (so that the contract doesn't use a linear amount of storage in the number of requests).

0 commit comments

Comments
 (0)