diff --git a/target_chains/ethereum/contracts/contracts/entropy/Entropy.sol b/target_chains/ethereum/contracts/contracts/entropy/Entropy.sol index 222fef8648..e84892e70f 100644 --- a/target_chains/ethereum/contracts/contracts/entropy/Entropy.sol +++ b/target_chains/ethereum/contracts/contracts/entropy/Entropy.sol @@ -16,14 +16,16 @@ import "./EntropyStructConverter.sol"; // Entropy implements a secure 2-party random number generation procedure. The protocol // is an extension of a simple commit/reveal protocol. The original version has the following steps: // -// 1. Two parties A and B each draw a random number x_{A,B} -// 2. A and B then share h_{A,B} = hash(x_{A,B}) -// 3. A and B reveal x_{A,B} -// 4. Both parties verify that hash(x_{A, B}) == h_{A,B} -// 5. The random number r = hash(x_A, x_B) +// 1. Two parties A and B each randomly sample a contribution x_{A,B} to the random number +// 2. A commits to their number by sharing h_A = hash(x_A) +// 3. B reveals x_B +// 4. A reveals x_A +// 5. B verifies that hash(x_{A}) == h_A +// 6. The random number r = hash(x_A, x_B) // // This protocol has the property that the result is random as long as either A or B are honest. -// Thus, neither party needs to trust the other -- as long as they are themselves honest, they can +// Honesty means that (1) they draw their value at random, and (2) for A, they keep x_A a secret until +// step 4. Thus, neither party needs to trust the other -- as long as they are themselves honest, they can // ensure that the result r is random. // // Entropy implements a version of this protocol that is optimized for on-chain usage. The @@ -37,26 +39,19 @@ import "./EntropyStructConverter.sol"; // verified against the previous one in the sequence by hashing it, i.e., hash(x_i) == x_{i - 1} // // Request: To produce a random number, the following steps occur. -// 1. The user draws a random number x_U, and submits h_U = hash(x_U) to this contract -// 2. The contract remembers h_U and assigns it an incrementing sequence number i, representing which +// 1. The user randomly samples their contribution x_U and submits it to the contract +// 2. The contract remembers x_U and assigns it an incrementing sequence number i, representing which // of the provider's random numbers the user will receive. -// 3. The user submits an off-chain request (e.g. via HTTP) to the provider to reveal the i'th random number. -// 4. The provider checks the on-chain sequence number and ensures it is > i. If it is not, the provider -// refuses to reveal the ith random number. The provider should wait for a sufficient number of block confirmations -// to ensure that the request does not get re-orged out of the blockchain. -// 5. The provider reveals x_i to the user. -// 6. The user submits both the provider's revealed number x_i and their own x_U to the contract. -// 7. The contract verifies hash(x_i) == x_{i-1} to prove that x_i is the i'th random number. The contract also checks that hash(x_U) == h_U. +// 3. The provider submits a transaction to the contract revealing their contribution x_i to the contract. +// 4. The contract verifies hash(x_i) == x_{i-1} to prove that x_i is the i'th random number. // The contract stores x_i as the i'th random number to reuse for future verifications. -// 8. If both of the above conditions are satisfied, the random number r = hash(x_i, x_U). -// (Optional) as an added security mechanism, this step can further incorporate the blockhash of the block that the -// request transaction landed in: r = hash(x_i, x_U, blockhash). +// 5. If the condition above is satisfied, the random number r = hash(x_i, x_U). +// 6. The contract submits a callback to the calling contract with the random number `r`. // // This protocol has the same security properties as the 2-party randomness protocol above: as long as either -// the provider or user is honest, the number r is random. Honesty here means that the participant keeps their -// random number x a secret until the revelation phase (step 5) of the protocol. Note that providers need to -// be careful to ensure their off-chain service isn't compromised to reveal the random numbers -- if this occurs, -// then users will be able to influence the random number r. +// the provider or user is honest, the number r is random. Note that this analysis assumes that +// providers cannot frontrun user transactions -- a dishonest provider who frontruns user transaction can +// manipulate the result. // // The Entropy implementation of the above protocol allows anyone to permissionlessly register to be a // randomness provider. Users then choose which provider to request randomness from. Each provider can set @@ -71,13 +66,6 @@ import "./EntropyStructConverter.sol"; // a compromised sequence. On rotation, any in-flight requests continue to use the pre-rotation commitment. // Providers can use the sequence number of the request along with the event log of their registrations to determine // which hash chain contains the requested random number. -// -// Warning to integrators: -// An important caveat of this protocol is that the user can compute the random number r before -// revealing their own number to the contract. This property means that the user can choose to halt the -// protocol prior to the random number being revealed (i.e., prior to step (6) above). Integrators should ensure that -// the user is always incentivized to reveal their random number, and that the protocol has an escape hatch for -// cases where the user chooses not to reveal. abstract contract Entropy is IEntropy, EntropyState { using ExcessivelySafeCall for address; @@ -357,24 +345,24 @@ abstract contract Entropy is IEntropy, EntropyState { // Note that excess value is *not* refunded to the caller. function requestWithCallback( address provider, - bytes32 userRandomNumber + bytes32 userContribution ) public payable override returns (uint64) { return requestV2( provider, - userRandomNumber, + userContribution, 0 // Passing 0 will assign the request the provider's default gas limit ); } function requestV2( address provider, - bytes32 userRandomNumber, + bytes32 userContribution, uint32 gasLimit ) public payable override returns (uint64) { EntropyStructsV2.Request storage req = requestHelper( provider, - constructUserCommitment(userRandomNumber), + constructUserCommitment(userContribution), // If useBlockHash is set to true, it allows a scenario in which the provider and miner can collude. // If we remove the blockHash from this, the provider would have no choice but to provide its committed // random number. Hence, useBlockHash is set to false. @@ -387,14 +375,14 @@ abstract contract Entropy is IEntropy, EntropyState { provider, req.requester, req.sequenceNumber, - userRandomNumber, + userContribution, EntropyStructConverter.toV1Request(req) ); emit EntropyEventsV2.Requested( provider, req.requester, req.sequenceNumber, - userRandomNumber, + userContribution, uint32(req.gasLimit10k) * TEN_THOUSAND, bytes("") ); @@ -406,14 +394,14 @@ abstract contract Entropy is IEntropy, EntropyState { // current commitment and returns the generated random number. function revealHelper( EntropyStructsV2.Request storage req, - bytes32 userRevelation, - bytes32 providerRevelation + bytes32 userContribution, + bytes32 providerContribution ) internal returns (bytes32 randomNumber, bytes32 blockHash) { bytes32 providerCommitment = constructProviderCommitment( req.numHashes, - providerRevelation + providerContribution ); - bytes32 userCommitment = constructUserCommitment(userRevelation); + bytes32 userCommitment = constructUserCommitment(userContribution); if ( keccak256(bytes.concat(userCommitment, providerCommitment)) != req.commitment @@ -436,8 +424,8 @@ abstract contract Entropy is IEntropy, EntropyState { } randomNumber = combineRandomValues( - userRevelation, - providerRevelation, + userContribution, + providerContribution, blockHash ); @@ -446,7 +434,7 @@ abstract contract Entropy is IEntropy, EntropyState { ]; if (providerInfo.currentCommitmentSequenceNumber < req.sequenceNumber) { providerInfo.currentCommitmentSequenceNumber = req.sequenceNumber; - providerInfo.currentCommitment = providerRevelation; + providerInfo.currentCommitment = providerContribution; } } @@ -455,7 +443,7 @@ abstract contract Entropy is IEntropy, EntropyState { function advanceProviderCommitment( address provider, uint64 advancedSequenceNumber, - bytes32 providerRevelation + bytes32 providerContribution ) public override { EntropyStructsV2.ProviderInfo storage providerInfo = _state.providers[ provider @@ -473,14 +461,14 @@ abstract contract Entropy is IEntropy, EntropyState { ); bytes32 providerCommitment = constructProviderCommitment( numHashes, - providerRevelation + providerContribution ); if (providerCommitment != providerInfo.currentCommitment) revert EntropyErrors.IncorrectRevelation(); providerInfo.currentCommitmentSequenceNumber = advancedSequenceNumber; - providerInfo.currentCommitment = providerRevelation; + providerInfo.currentCommitment = providerContribution; if ( providerInfo.currentCommitmentSequenceNumber >= providerInfo.sequenceNumber @@ -508,8 +496,8 @@ abstract contract Entropy is IEntropy, EntropyState { function reveal( address provider, uint64 sequenceNumber, - bytes32 userRevelation, - bytes32 providerRevelation + bytes32 userContribution, + bytes32 providerContribution ) public override returns (bytes32 randomNumber) { EntropyStructsV2.Request storage req = findActiveRequest( provider, @@ -528,13 +516,13 @@ abstract contract Entropy is IEntropy, EntropyState { bytes32 blockHash; (randomNumber, blockHash) = revealHelper( req, - userRevelation, - providerRevelation + userContribution, + providerContribution ); emit Revealed( EntropyStructConverter.toV1Request(req), - userRevelation, - providerRevelation, + userContribution, + providerContribution, blockHash, randomNumber ); @@ -554,8 +542,8 @@ abstract contract Entropy is IEntropy, EntropyState { function revealWithCallback( address provider, uint64 sequenceNumber, - bytes32 userRandomNumber, - bytes32 providerRevelation + bytes32 userContribution, + bytes32 providerContribution ) public override { EntropyStructsV2.Request storage req = findActiveRequest( provider, @@ -573,8 +561,8 @@ abstract contract Entropy is IEntropy, EntropyState { bytes32 randomNumber; (randomNumber, ) = revealHelper( req, - userRandomNumber, - providerRevelation + userContribution, + providerContribution ); // If the request has an explicit gas limit, then run the new callback failure state flow. @@ -613,8 +601,8 @@ abstract contract Entropy is IEntropy, EntropyState { if (success) { emit RevealedWithCallback( EntropyStructConverter.toV1Request(req), - userRandomNumber, - providerRevelation, + userContribution, + providerContribution, randomNumber ); emit EntropyEventsV2.Revealed( @@ -622,6 +610,8 @@ abstract contract Entropy is IEntropy, EntropyState { req.requester, req.sequenceNumber, randomNumber, + userContribution, + providerContribution, false, ret, SafeCast.toUint32(gasUsed), @@ -642,8 +632,8 @@ abstract contract Entropy is IEntropy, EntropyState { provider, req.requester, sequenceNumber, - userRandomNumber, - providerRevelation, + userContribution, + providerContribution, randomNumber, ret ); @@ -652,6 +642,8 @@ abstract contract Entropy is IEntropy, EntropyState { req.requester, sequenceNumber, randomNumber, + userContribution, + providerContribution, true, ret, SafeCast.toUint32(gasUsed), @@ -692,8 +684,8 @@ abstract contract Entropy is IEntropy, EntropyState { emit RevealedWithCallback( reqV1, - userRandomNumber, - providerRevelation, + userContribution, + providerContribution, randomNumber ); emit EntropyEventsV2.Revealed( @@ -701,6 +693,8 @@ abstract contract Entropy is IEntropy, EntropyState { callAddress, sequenceNumber, randomNumber, + userContribution, + providerContribution, false, bytes(""), gasUsed, diff --git a/target_chains/ethereum/contracts/forge-test/Entropy.t.sol b/target_chains/ethereum/contracts/forge-test/Entropy.t.sol index b9732f5b2c..62c53639bf 100644 --- a/target_chains/ethereum/contracts/forge-test/Entropy.t.sol +++ b/target_chains/ethereum/contracts/forge-test/Entropy.t.sol @@ -888,6 +888,8 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { provider1Proofs[assignedSequenceNumber], 0 ), + userRandomNumber, + provider1Proofs[assignedSequenceNumber], false, bytes(""), 0, @@ -956,6 +958,8 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { provider1Proofs[assignedSequenceNumber], 0 ), + userRandomNumber, + provider1Proofs[assignedSequenceNumber], false, bytes(""), 0, @@ -1063,6 +1067,8 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { provider1Proofs[assignedSequenceNumber], 0 ), + userRandomNumber, + provider1Proofs[assignedSequenceNumber], false, bytes(""), 0, @@ -1136,6 +1142,8 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { provider1Proofs[assignedSequenceNumber], 0 ), + userRandomNumber, + provider1Proofs[assignedSequenceNumber], true, revertReason, 0, @@ -1202,6 +1210,8 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { provider1Proofs[assignedSequenceNumber], 0 ), + userRandomNumber, + provider1Proofs[assignedSequenceNumber], false, bytes(""), 0, @@ -1283,6 +1293,8 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { provider1Proofs[assignedSequenceNumber], 0 ), + userRandomNumber, + provider1Proofs[assignedSequenceNumber], true, "", 0, @@ -1348,6 +1360,8 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { provider1Proofs[assignedSequenceNumber], 0 ), + userRandomNumber, + provider1Proofs[assignedSequenceNumber], false, "", 0, @@ -1822,57 +1836,14 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { assertEq(entries.length, 2); // first entry is CallbackFailed which we aren't going to check. - // Unfortunately event.selector was added in Solidity 0.8.15 and we're on 0.8.4 so we have to copy this spec here. - assertEq( - entries[1].topics[0], - keccak256( - "Revealed(address,address,uint64,bytes32,bool,bytes,uint32,bytes)" - ) - ); - // Verify the topics match the expected values - assertEq( - entries[1].topics[1], - bytes32(uint256(uint160(provider1))) - ); - assertEq( - entries[1].topics[2], - bytes32(uint256(uint160(address(consumer)))) - ); - assertEq(entries[1].topics[3], bytes32(uint256(sequenceNumber))); - - // Verify the data field contains the expected values (per event ABI) - ( - bytes32 randomNumber, - bool callbackFailed, - bytes memory callbackErrorCode, - uint32 callbackGasUsed, - bytes memory extraArgs - ) = abi.decode( - entries[1].data, - (bytes32, bool, bytes, uint32, bytes) - ); - - assertEq( - randomNumber, - random.combineRandomValues( - userRandomNumber, - provider1Proofs[sequenceNumber], - 0 - ) - ); - assertEq(callbackFailed, true); - assertEq(callbackErrorCode, bytes("")); - - // callback gas usage is approximate - assertTrue( - random.getProviderInfoV2(provider1).defaultGasLimit == 0 || - ((callbackGasUsage * 90) / 100 < callbackGasUsed) - ); - assertTrue( - random.getProviderInfoV2(provider1).defaultGasLimit == 0 || - (callbackGasUsed < (callbackGasUsage * 110) / 100) + assertRevealedEvent( + entries[1], + address(consumer), + sequenceNumber, + userRandomNumber, + true, + callbackGasUsage ); - assertEq(extraArgs, bytes("")); // Verify request is still active after failure EntropyStructsV2.Request memory reqAfterFailure = random @@ -1894,55 +1865,14 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { Vm.Log[] memory entries = vm.getRecordedLogs(); assertEq(entries.length, 2); - // first entry is CallbackFailed which we aren't going to check. - // Unfortunately event.selector was added in Solidity 0.8.15 and we're on 0.8.4 so we have to copy this spec here. - assertEq( - entries[1].topics[0], - keccak256( - "Revealed(address,address,uint64,bytes32,bool,bytes,uint32,bytes)" - ) - ); - - // Verify the topics match the expected values - assertEq( - entries[1].topics[1], - bytes32(uint256(uint160(provider1))) - ); - assertEq( - entries[1].topics[2], - bytes32(uint256(uint160(req.requester))) - ); - assertEq( - entries[1].topics[3], - bytes32(uint256(req.sequenceNumber)) - ); - - // Verify the data field contains the expected values (per event ABI) - ( - bytes32 randomNumber, - bool callbackFailed, - bytes memory callbackErrorCode, - uint32 callbackGasUsed, - bytes memory extraArgs - ) = abi.decode( - entries[1].data, - (bytes32, bool, bytes, uint32, bytes) - ); - - assertEq( - randomNumber, - random.combineRandomValues( - userRandomNumber, - provider1Proofs[sequenceNumber], - 0 - ) + assertRevealedEvent( + entries[1], + req.requester, + req.sequenceNumber, + userRandomNumber, + false, + callbackGasUsage ); - assertEq(callbackFailed, false); - assertEq(callbackErrorCode, bytes("")); - // callback gas usage is approximate - assertTrue((callbackGasUsage * 90) / 100 < callbackGasUsed); - assertTrue(callbackGasUsed < (callbackGasUsage * 110) / 100); - assertEq(extraArgs, bytes("")); // Verify request is cleared after successful callback EntropyStructsV2.Request memory reqAfterSuccess = random @@ -1950,6 +1880,59 @@ contract EntropyTest is Test, EntropyTestUtils, EntropyEvents, EntropyEventsV2 { assertEq(reqAfterSuccess.sequenceNumber, 0); } } + + // Helper method to check the Revealed event + function assertRevealedEvent( + Vm.Log memory entry, + address expectedRequester, + uint64 expectedSequenceNumber, + bytes32 expectedUserContribution, + bool expectedCallbackFailed, + uint32 expectedCallbackGasUsage + ) internal { + // Check event topic + assertEq( + entry.topics[0], + keccak256( + "Revealed(address,address,uint64,bytes32,bytes32,bytes32,bool,bytes,uint32,bytes)" + ) + ); + + // Check event topics + assertEq(entry.topics[1], bytes32(uint256(uint160(provider1)))); + assertEq(entry.topics[2], bytes32(uint256(uint160(expectedRequester)))); + assertEq(entry.topics[3], bytes32(uint256(expectedSequenceNumber))); + + bytes32 expectedRandomNumber = random.combineRandomValues( + expectedUserContribution, + provider1Proofs[expectedSequenceNumber], + 0 + ); + + // Decode and check event data + ( + bytes32 randomNumber, + bytes32 userContribution, + bytes32 providerContribution, + bool callbackFailed, + bytes memory callbackErrorCode, + uint32 callbackGasUsed, + bytes memory extraArgs + ) = abi.decode( + entry.data, + (bytes32, bytes32, bytes32, bool, bytes, uint32, bytes) + ); + + assertEq(randomNumber, expectedRandomNumber); + assertEq(userContribution, expectedUserContribution); + assertEq(providerContribution, provider1Proofs[expectedSequenceNumber]); + assertEq(callbackFailed, expectedCallbackFailed); + assertEq(callbackErrorCode, bytes("")); + // callback gas usage is approximate + assertTrue((expectedCallbackGasUsage * 90) / 100 < callbackGasUsed); + assertTrue(callbackGasUsed < (expectedCallbackGasUsage * 110) / 100); + assertEq(extraArgs, bytes("")); + } } contract EntropyConsumer is IEntropyConsumer { diff --git a/target_chains/ethereum/entropy_sdk/solidity/EntropyEventsV2.sol b/target_chains/ethereum/entropy_sdk/solidity/EntropyEventsV2.sol index bc413061d5..1ecab19cab 100644 --- a/target_chains/ethereum/entropy_sdk/solidity/EntropyEventsV2.sol +++ b/target_chains/ethereum/entropy_sdk/solidity/EntropyEventsV2.sol @@ -23,7 +23,7 @@ interface EntropyEventsV2 { * @param provider The address of the provider handling the request * @param caller The address of the user requesting the random number * @param sequenceNumber A unique identifier for this request - * @param userRandomNumber A random number provided by the user for additional entropy + * @param userContribution The user's contribution to the random number * @param gasLimit The gas limit for the callback. * @param extraArgs A field for extra data for forward compatibility. */ @@ -31,7 +31,7 @@ interface EntropyEventsV2 { address indexed provider, address indexed caller, uint64 indexed sequenceNumber, - bytes32 userRandomNumber, + bytes32 userContribution, uint32 gasLimit, bytes extraArgs ); @@ -42,6 +42,8 @@ interface EntropyEventsV2 { * @param caller The address of the user who requested the random number (and who receives a callback) * @param sequenceNumber The unique identifier of the request * @param randomNumber The generated random number + * @param userContribution The user's contribution to the random number + * @param providerContribution The provider's contribution to the random number * @param callbackFailed Whether the callback to the caller failed * @param callbackReturnValue Return value from the callback. If the callback failed, this field contains * the error code and any additional returned data. Note that "" often indicates an out-of-gas error. @@ -54,6 +56,8 @@ interface EntropyEventsV2 { address indexed caller, uint64 indexed sequenceNumber, bytes32 randomNumber, + bytes32 userContribution, + bytes32 providerContribution, bool callbackFailed, bytes callbackReturnValue, uint32 callbackGasUsed, diff --git a/target_chains/ethereum/entropy_sdk/solidity/IEntropyV2.sol b/target_chains/ethereum/entropy_sdk/solidity/IEntropyV2.sol index 9001d06b12..b31c0bacfa 100644 --- a/target_chains/ethereum/entropy_sdk/solidity/IEntropyV2.sol +++ b/target_chains/ethereum/entropy_sdk/solidity/IEntropyV2.sol @@ -20,8 +20,10 @@ interface IEntropyV2 is EntropyEventsV2 { /// Note that the fee can change over time. Callers of this method should explicitly compute `getFeeV2()` /// prior to each invocation (as opposed to hardcoding a value). Further note that excess value is *not* refunded to the caller. /// - /// Note that this method uses an in-contract PRNG to generate the user's portion of the random number. - /// Users must trust this PRNG in order to prove the result is random. If you wish to avoid this trust assumption, + /// Note that this method uses an in-contract PRNG to generate the user's contribution to the random number. + /// This approach modifies the security guarantees such that a dishonest validator and provider can + /// collude to manipulate the result (as opposed to a malicious user and provider). That is, the user + /// now trusts the validator honestly draw a random number. If you wish to avoid this trust assumption, /// call a variant of `requestV2` that accepts a `userRandomNumber` parameter. function requestV2() external @@ -43,8 +45,10 @@ interface IEntropyV2 is EntropyEventsV2 { /// Note that the fee can change over time. Callers of this method should explicitly compute `getFeeV2(gasLimit)` /// prior to each invocation (as opposed to hardcoding a value). Further note that excess value is *not* refunded to the caller. /// - /// Note that this method uses an in-contract PRNG to generate the user's portion of the random number. - /// Users must trust this PRNG in order to prove the result is random. If you wish to avoid this trust assumption, + /// Note that this method uses an in-contract PRNG to generate the user's contribution to the random number. + /// This approach modifies the security guarantees such that a dishonest validator and provider can + /// collude to manipulate the result (as opposed to a malicious user and provider). That is, the user + /// now trusts the validator honestly draw a random number. If you wish to avoid this trust assumption, /// call a variant of `requestV2` that accepts a `userRandomNumber` parameter. function requestV2( uint32 gasLimit @@ -66,8 +70,10 @@ interface IEntropyV2 is EntropyEventsV2 { /// Note that provider fees can change over time. Callers of this method should explicitly compute `getFeeV2(provider, gasLimit)` /// prior to each invocation (as opposed to hardcoding a value). Further note that excess value is *not* refunded to the caller. /// - /// Note that this method uses an in-contract PRNG to generate the user's portion of the random number. - /// Users must trust this PRNG in order to prove the result is random. If you wish to avoid this trust assumption, + /// Note that this method uses an in-contract PRNG to generate the user's contribution to the random number. + /// This approach modifies the security guarantees such that a dishonest validator and provider can + /// collude to manipulate the result (as opposed to a malicious user and provider). That is, the user + /// now trusts the validator honestly draw a random number. If you wish to avoid this trust assumption, /// call a variant of `requestV2` that accepts a `userRandomNumber` parameter. function requestV2( address provider, diff --git a/target_chains/ethereum/entropy_sdk/solidity/abis/EntropyEventsV2.json b/target_chains/ethereum/entropy_sdk/solidity/abis/EntropyEventsV2.json index 95c6a7db6c..ceeb86f095 100644 --- a/target_chains/ethereum/entropy_sdk/solidity/abis/EntropyEventsV2.json +++ b/target_chains/ethereum/entropy_sdk/solidity/abis/EntropyEventsV2.json @@ -197,7 +197,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "userRandomNumber", + "name": "userContribution", "type": "bytes32" }, { @@ -243,6 +243,18 @@ "name": "randomNumber", "type": "bytes32" }, + { + "indexed": false, + "internalType": "bytes32", + "name": "userContribution", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "providerContribution", + "type": "bytes32" + }, { "indexed": false, "internalType": "bool", diff --git a/target_chains/ethereum/entropy_sdk/solidity/abis/IEntropy.json b/target_chains/ethereum/entropy_sdk/solidity/abis/IEntropy.json index eff161293f..64eaa06e69 100644 --- a/target_chains/ethereum/entropy_sdk/solidity/abis/IEntropy.json +++ b/target_chains/ethereum/entropy_sdk/solidity/abis/IEntropy.json @@ -501,7 +501,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "userRandomNumber", + "name": "userContribution", "type": "bytes32" }, { @@ -705,6 +705,18 @@ "name": "randomNumber", "type": "bytes32" }, + { + "indexed": false, + "internalType": "bytes32", + "name": "userContribution", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "providerContribution", + "type": "bytes32" + }, { "indexed": false, "internalType": "bool", diff --git a/target_chains/ethereum/entropy_sdk/solidity/abis/IEntropyV2.json b/target_chains/ethereum/entropy_sdk/solidity/abis/IEntropyV2.json index d6ccffa069..dbf49601b2 100644 --- a/target_chains/ethereum/entropy_sdk/solidity/abis/IEntropyV2.json +++ b/target_chains/ethereum/entropy_sdk/solidity/abis/IEntropyV2.json @@ -197,7 +197,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "userRandomNumber", + "name": "userContribution", "type": "bytes32" }, { @@ -243,6 +243,18 @@ "name": "randomNumber", "type": "bytes32" }, + { + "indexed": false, + "internalType": "bytes32", + "name": "userContribution", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "providerContribution", + "type": "bytes32" + }, { "indexed": false, "internalType": "bool",