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:
parent
0e6484daca
commit
02e196e924
|
@ -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
|
// 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 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 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
|
// 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).
|
// 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 {
|
||||||
|
|
||||||
clearRequest(provider, sequenceNumber);
|
clearRequest(provider, sequenceNumber);
|
||||||
|
|
||||||
IEntropyConsumer(callAddress)._entropyCallback(
|
// Check if the callAddress is a contract account.
|
||||||
sequenceNumber,
|
uint len;
|
||||||
provider,
|
assembly {
|
||||||
randomNumber
|
len := extcodesize(callAddress)
|
||||||
);
|
}
|
||||||
|
if (len != 0) {
|
||||||
|
IEntropyConsumer(callAddress)._entropyCallback(
|
||||||
|
sequenceNumber,
|
||||||
|
provider,
|
||||||
|
randomNumber
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProviderInfo(
|
function getProviderInfo(
|
||||||
|
|
|
@ -799,7 +799,7 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
|
||||||
vm.stopPrank();
|
vm.stopPrank();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testRequestWithCallbackAndRevealWithCallback() public {
|
function testRequestWithCallbackAndRevealWithCallbackByContract() public {
|
||||||
bytes32 userRandomNumber = bytes32(uint(42));
|
bytes32 userRandomNumber = bytes32(uint(42));
|
||||||
uint fee = random.getFee(provider1);
|
uint fee = random.getFee(provider1);
|
||||||
EntropyConsumer consumer = new EntropyConsumer(address(random));
|
EntropyConsumer consumer = new EntropyConsumer(address(random));
|
||||||
|
@ -853,6 +853,46 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents {
|
||||||
assertEq(reqAfterReveal.sequenceNumber, 0);
|
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 {
|
function testRequestAndRevealWithCallback() public {
|
||||||
uint64 sequenceNumber = request(user2, provider1, 42, false);
|
uint64 sequenceNumber = request(user2, provider1, 42, false);
|
||||||
assertEq(random.getRequest(provider1, sequenceNumber).requester, user2);
|
assertEq(random.getRequest(provider1, sequenceNumber).requester, user2);
|
||||||
|
|
|
@ -51,9 +51,10 @@ interface IEntropy is EntropyEvents {
|
||||||
bytes32 userRandomNumber
|
bytes32 userRandomNumber
|
||||||
) external payable returns (uint64 assignedSequenceNumber);
|
) external payable returns (uint64 assignedSequenceNumber);
|
||||||
|
|
||||||
// Fulfill a request for a random number. This method validates the provided userRevelation and provider's proof
|
// Fulfill a request for a random number and call back the requester. This method validates the provided userRandomness
|
||||||
// against the corresponding commitments in the in-flight request. If both values are validated, this function returns
|
// and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated
|
||||||
// the corresponding random number.
|
// 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
|
// 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).
|
// request information (so that the contract doesn't use a linear amount of storage in the number of requests).
|
||||||
|
|
Loading…
Reference in New Issue