Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 35 additions & 34 deletions target_chains/ethereum/contracts/contracts/entropy/Entropy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pragma solidity ^0.8.0;

import "@pythnetwork/entropy-sdk-solidity/EntropyStructs.sol";
import "@pythnetwork/entropy-sdk-solidity/EntropyStructsV2.sol";
import "@pythnetwork/entropy-sdk-solidity/EntropyErrors.sol";
import "@pythnetwork/entropy-sdk-solidity/EntropyEvents.sol";
import "@pythnetwork/entropy-sdk-solidity/IEntropy.sol";
Expand All @@ -11,6 +11,7 @@ import "@openzeppelin/contracts/utils/math/SafeCast.sol";
import "@nomad-xyz/excessively-safe-call/src/ExcessivelySafeCall.sol";
import "./EntropyState.sol";
import "@pythnetwork/entropy-sdk-solidity/EntropyStatusConstants.sol";
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:
Expand Down Expand Up @@ -106,7 +107,7 @@ abstract contract Entropy is IEntropy, EntropyState {
// use a more consistent amount of gas.
// Note that these requests are not live because their sequenceNumber is 0.
for (uint8 i = 0; i < NUM_REQUESTS; i++) {
EntropyStructs.Request storage req = _state.requests[i];
EntropyStructsV2.Request storage req = _state.requests[i];
req.provider = address(1);
req.blockNumber = 1234;
req.commitment = hex"0123";
Expand All @@ -128,7 +129,7 @@ abstract contract Entropy is IEntropy, EntropyState {
) public override {
if (chainLength == 0) revert EntropyErrors.AssertionFailure();

EntropyStructs.ProviderInfo storage provider = _state.providers[
EntropyStructsV2.ProviderInfo storage provider = _state.providers[
msg.sender
];

Expand All @@ -149,14 +150,14 @@ abstract contract Entropy is IEntropy, EntropyState {

provider.sequenceNumber += 1;

emit Registered(provider);
emit Registered(EntropyStructConverter.toV1ProviderInfo(provider));
}

// Withdraw a portion of the accumulated fees for the provider msg.sender.
// Calling this function will transfer `amount` wei to the caller (provided that they have accrued a sufficient
// balance of fees in the contract).
function withdraw(uint128 amount) public override {
EntropyStructs.ProviderInfo storage providerInfo = _state.providers[
EntropyStructsV2.ProviderInfo storage providerInfo = _state.providers[
msg.sender
];

Expand All @@ -178,7 +179,7 @@ abstract contract Entropy is IEntropy, EntropyState {
address provider,
uint128 amount
) external override {
EntropyStructs.ProviderInfo storage providerInfo = _state.providers[
EntropyStructsV2.ProviderInfo storage providerInfo = _state.providers[
provider
];

Expand Down Expand Up @@ -213,8 +214,8 @@ abstract contract Entropy is IEntropy, EntropyState {
bool useBlockhash,
bool isRequestWithCallback,
uint32 callbackGasLimit
) internal returns (EntropyStructs.Request storage req) {
EntropyStructs.ProviderInfo storage providerInfo = _state.providers[
) internal returns (EntropyStructsV2.Request storage req) {
EntropyStructsV2.ProviderInfo storage providerInfo = _state.providers[
provider
];
if (_state.providers[provider].sequenceNumber == 0)
Expand Down Expand Up @@ -294,15 +295,15 @@ abstract contract Entropy is IEntropy, EntropyState {
bytes32 userCommitment,
bool useBlockHash
) public payable override returns (uint64 assignedSequenceNumber) {
EntropyStructs.Request storage req = requestHelper(
EntropyStructsV2.Request storage req = requestHelper(
provider,
userCommitment,
useBlockHash,
false,
0
);
assignedSequenceNumber = req.sequenceNumber;
emit Requested(req);
emit Requested(EntropyStructConverter.toV1Request(req));
}

// Request a random number. The method expects the provider address and a secret random number
Expand Down Expand Up @@ -330,7 +331,7 @@ abstract contract Entropy is IEntropy, EntropyState {
bytes32 userRandomNumber,
uint32 gasLimit
) public payable override returns (uint64) {
EntropyStructs.Request storage req = requestHelper(
EntropyStructsV2.Request storage req = requestHelper(
provider,
constructUserCommitment(userRandomNumber),
// If useBlockHash is set to true, it allows a scenario in which the provider and miner can collude.
Expand All @@ -346,7 +347,7 @@ abstract contract Entropy is IEntropy, EntropyState {
req.requester,
req.sequenceNumber,
userRandomNumber,
req
EntropyStructConverter.toV1Request(req)
);
return req.sequenceNumber;
}
Expand All @@ -355,7 +356,7 @@ abstract contract Entropy is IEntropy, EntropyState {
// commitment in the in-flight request. If both values are validated, this method will update the provider
// current commitment and returns the generated random number.
function revealHelper(
EntropyStructs.Request storage req,
EntropyStructsV2.Request storage req,
bytes32 userRevelation,
bytes32 providerRevelation
) internal returns (bytes32 randomNumber, bytes32 blockHash) {
Expand Down Expand Up @@ -391,7 +392,7 @@ abstract contract Entropy is IEntropy, EntropyState {
blockHash
);

EntropyStructs.ProviderInfo storage providerInfo = _state.providers[
EntropyStructsV2.ProviderInfo storage providerInfo = _state.providers[
req.provider
];
if (providerInfo.currentCommitmentSequenceNumber < req.sequenceNumber) {
Expand All @@ -407,7 +408,7 @@ abstract contract Entropy is IEntropy, EntropyState {
uint64 advancedSequenceNumber,
bytes32 providerRevelation
) public override {
EntropyStructs.ProviderInfo storage providerInfo = _state.providers[
EntropyStructsV2.ProviderInfo storage providerInfo = _state.providers[
provider
];
if (
Expand Down Expand Up @@ -461,7 +462,7 @@ abstract contract Entropy is IEntropy, EntropyState {
bytes32 userRevelation,
bytes32 providerRevelation
) public override returns (bytes32 randomNumber) {
EntropyStructs.Request storage req = findActiveRequest(
EntropyStructsV2.Request storage req = findActiveRequest(
provider,
sequenceNumber
);
Expand All @@ -482,7 +483,7 @@ abstract contract Entropy is IEntropy, EntropyState {
providerRevelation
);
emit Revealed(
req,
EntropyStructConverter.toV1Request(req),
userRevelation,
providerRevelation,
blockHash,
Expand All @@ -507,7 +508,7 @@ abstract contract Entropy is IEntropy, EntropyState {
bytes32 userRandomNumber,
bytes32 providerRevelation
) public override {
EntropyStructs.Request storage req = findActiveRequest(
EntropyStructsV2.Request storage req = findActiveRequest(
provider,
sequenceNumber
);
Expand Down Expand Up @@ -564,7 +565,7 @@ abstract contract Entropy is IEntropy, EntropyState {

if (success) {
emit RevealedWithCallback(
req,
EntropyStructConverter.toV1Request(req),
userRandomNumber,
providerRevelation,
randomNumber
Expand Down Expand Up @@ -602,7 +603,7 @@ abstract contract Entropy is IEntropy, EntropyState {
} else {
// This case uses the checks-effects-interactions pattern to avoid reentry attacks
emit RevealedWithCallback(
req,
EntropyStructConverter.toV1Request(req),
userRandomNumber,
providerRevelation,
randomNumber
Expand All @@ -627,7 +628,7 @@ abstract contract Entropy is IEntropy, EntropyState {

function getProviderInfo(
address provider
) public view override returns (EntropyStructs.ProviderInfo memory info) {
) public view override returns (EntropyStructsV2.ProviderInfo memory info) {
info = _state.providers[provider];
}

Expand All @@ -643,7 +644,7 @@ abstract contract Entropy is IEntropy, EntropyState {
function getRequest(
address provider,
uint64 sequenceNumber
) public view override returns (EntropyStructs.Request memory req) {
) public view override returns (EntropyStructsV2.Request memory req) {
req = findRequest(provider, sequenceNumber);
}

Expand All @@ -664,7 +665,7 @@ abstract contract Entropy is IEntropy, EntropyState {
address providerAddr,
uint32 gasLimit
) internal view returns (uint128 feeAmount) {
EntropyStructs.ProviderInfo memory provider = _state.providers[
EntropyStructsV2.ProviderInfo memory provider = _state.providers[
providerAddr
];

Expand Down Expand Up @@ -704,7 +705,7 @@ abstract contract Entropy is IEntropy, EntropyState {

// Set provider fee. It will revert if provider is not registered.
function setProviderFee(uint128 newFeeInWei) external override {
EntropyStructs.ProviderInfo storage provider = _state.providers[
EntropyStructsV2.ProviderInfo storage provider = _state.providers[
msg.sender
];

Expand All @@ -720,7 +721,7 @@ abstract contract Entropy is IEntropy, EntropyState {
address provider,
uint128 newFeeInWei
) external override {
EntropyStructs.ProviderInfo storage providerInfo = _state.providers[
EntropyStructsV2.ProviderInfo storage providerInfo = _state.providers[
provider
];

Expand All @@ -740,7 +741,7 @@ abstract contract Entropy is IEntropy, EntropyState {

// Set provider uri. It will revert if provider is not registered.
function setProviderUri(bytes calldata newUri) external override {
EntropyStructs.ProviderInfo storage provider = _state.providers[
EntropyStructsV2.ProviderInfo storage provider = _state.providers[
msg.sender
];
if (provider.sequenceNumber == 0) {
Expand All @@ -752,7 +753,7 @@ abstract contract Entropy is IEntropy, EntropyState {
}

function setFeeManager(address manager) external override {
EntropyStructs.ProviderInfo storage provider = _state.providers[
EntropyStructsV2.ProviderInfo storage provider = _state.providers[
msg.sender
];
if (provider.sequenceNumber == 0) {
Expand All @@ -767,7 +768,7 @@ abstract contract Entropy is IEntropy, EntropyState {
// Set the maximum number of hashes to record in a request. This should be set according to the maximum gas limit
// the provider supports for callbacks.
function setMaxNumHashes(uint32 maxNumHashes) external override {
EntropyStructs.ProviderInfo storage provider = _state.providers[
EntropyStructsV2.ProviderInfo storage provider = _state.providers[
msg.sender
];
if (provider.sequenceNumber == 0) {
Expand All @@ -785,7 +786,7 @@ abstract contract Entropy is IEntropy, EntropyState {

// Set the default gas limit for a request.
function setDefaultGasLimit(uint32 gasLimit) external override {
EntropyStructs.ProviderInfo storage provider = _state.providers[
EntropyStructsV2.ProviderInfo storage provider = _state.providers[
msg.sender
];
if (provider.sequenceNumber == 0) {
Expand Down Expand Up @@ -861,7 +862,7 @@ abstract contract Entropy is IEntropy, EntropyState {
function findActiveRequest(
address provider,
uint64 sequenceNumber
) internal view returns (EntropyStructs.Request storage req) {
) internal view returns (EntropyStructsV2.Request storage req) {
req = findRequest(provider, sequenceNumber);

// Check there is an active request for the given provider and sequence number.
Expand All @@ -878,7 +879,7 @@ abstract contract Entropy is IEntropy, EntropyState {
function findRequest(
address provider,
uint64 sequenceNumber
) internal view returns (EntropyStructs.Request storage req) {
) internal view returns (EntropyStructsV2.Request storage req) {
(bytes32 key, uint8 shortKey) = requestKey(provider, sequenceNumber);

req = _state.requests[shortKey];
Expand All @@ -893,7 +894,7 @@ abstract contract Entropy is IEntropy, EntropyState {
function clearRequest(address provider, uint64 sequenceNumber) internal {
(bytes32 key, uint8 shortKey) = requestKey(provider, sequenceNumber);

EntropyStructs.Request storage req = _state.requests[shortKey];
EntropyStructsV2.Request storage req = _state.requests[shortKey];
if (req.provider == provider && req.sequenceNumber == sequenceNumber) {
req.sequenceNumber = 0;
} else {
Expand All @@ -908,7 +909,7 @@ abstract contract Entropy is IEntropy, EntropyState {
function allocRequest(
address provider,
uint64 sequenceNumber
) internal returns (EntropyStructs.Request storage req) {
) internal returns (EntropyStructsV2.Request storage req) {
(, uint8 shortKey) = requestKey(provider, sequenceNumber);

req = _state.requests[shortKey];
Expand All @@ -929,7 +930,7 @@ abstract contract Entropy is IEntropy, EntropyState {

// Returns true if a request is active, i.e., its corresponding random value has not yet been revealed.
function isActive(
EntropyStructs.Request storage req
EntropyStructsV2.Request storage req
) internal view returns (bool) {
// Note that a provider's initial registration occupies sequence number 0, so there is no way to construct
// a randomness request with sequence number 0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pragma solidity ^0.8.0;

import "@pythnetwork/entropy-sdk-solidity/EntropyStructs.sol";
import "@pythnetwork/entropy-sdk-solidity/EntropyStructsV2.sol";

contract EntropyInternalStructs {
struct State {
Expand Down Expand Up @@ -30,10 +30,10 @@ contract EntropyInternalStructs {
// considered active if their sequenceNumber is > 0.
//
// WARNING: the number of requests must be kept in sync with the constants below
EntropyStructs.Request[32] requests;
mapping(bytes32 => EntropyStructs.Request) requestsOverflow;
EntropyStructsV2.Request[32] requests;
mapping(bytes32 => EntropyStructsV2.Request) requestsOverflow;
// Mapping from randomness providers to information about each them.
mapping(address => EntropyStructs.ProviderInfo) providers;
mapping(address => EntropyStructsV2.ProviderInfo) providers;
// proposedAdmin is the new admin's account address proposed by either the owner or the current admin.
// If there is no pending transfer request, this value will hold `address(0)`.
address proposedAdmin;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;

import "@pythnetwork/entropy-sdk-solidity/EntropyStructs.sol";
import "@pythnetwork/entropy-sdk-solidity/EntropyStructsV2.sol";

// Conversions from V2 structs to their V1 equivalents
library EntropyStructConverter {
function toV1Request(
EntropyStructsV2.Request memory v2Request
) internal pure returns (EntropyStructs.Request memory v1Request) {
v1Request = EntropyStructs.Request({
provider: v2Request.provider,
sequenceNumber: v2Request.sequenceNumber,
numHashes: v2Request.numHashes,
commitment: v2Request.commitment,
blockNumber: v2Request.blockNumber,
requester: v2Request.requester,
useBlockhash: v2Request.useBlockhash,
isRequestWithCallback: v2Request.callbackStatus > 0
});
}

function toV1ProviderInfo(
EntropyStructsV2.ProviderInfo memory v2ProviderInfo
)
internal
pure
returns (EntropyStructs.ProviderInfo memory v1ProviderInfo)
{
v1ProviderInfo = EntropyStructs.ProviderInfo({
feeInWei: v2ProviderInfo.feeInWei,
accruedFeesInWei: v2ProviderInfo.accruedFeesInWei,
originalCommitment: v2ProviderInfo.originalCommitment,
originalCommitmentSequenceNumber: v2ProviderInfo
.originalCommitmentSequenceNumber,
commitmentMetadata: v2ProviderInfo.commitmentMetadata,
uri: v2ProviderInfo.uri,
endSequenceNumber: v2ProviderInfo.endSequenceNumber,
sequenceNumber: v2ProviderInfo.sequenceNumber,
currentCommitment: v2ProviderInfo.currentCommitment,
currentCommitmentSequenceNumber: v2ProviderInfo
.currentCommitmentSequenceNumber,
feeManager: v2ProviderInfo.feeManager,
maxNumHashes: v2ProviderInfo.maxNumHashes
});
}
}
Loading
Loading