-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathRandomizerRNG.sol
115 lines (94 loc) · 4.29 KB
/
RandomizerRNG.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
import "./RNG.sol";
import "./IRandomizer.sol";
import "../proxy/UUPSProxiable.sol";
import "../proxy/Initializable.sol";
/// @title Random Number Generator that uses Randomizer.ai
/// https://randomizer.ai/
contract RandomizerRNG is RNG, UUPSProxiable, Initializable {
// ************************************* //
// * Storage * //
// ************************************* //
address public governor; // The address that can withdraw funds.
uint256 public callbackGasLimit; // Gas limit for the randomizer callback
IRandomizer public randomizer; // Randomizer address.
mapping(uint256 => uint256) public randomNumbers; // randomNumbers[requestID] is the random number for this request id, 0 otherwise.
mapping(address => uint256) public requesterToID; // Maps the requester to his latest request ID.
// ************************************* //
// * Function Modifiers * //
// ************************************* //
modifier onlyByGovernor() {
require(governor == msg.sender, "Governor only");
_;
}
// ************************************* //
// * Constructor * //
// ************************************* //
/// @dev Constructor, initializing the implementation to reduce attack surface.
constructor() {
_disableInitializers();
}
/// @dev Initializer
/// @param _randomizer Randomizer contract.
/// @param _governor Governor of the contract.
function initialize(IRandomizer _randomizer, address _governor) external reinitializer(1) {
randomizer = _randomizer;
governor = _governor;
callbackGasLimit = 50000;
}
// ************************ //
// * Governance * //
// ************************ //
/**
* @dev Access Control to perform implementation upgrades (UUPS Proxiable)
* @dev Only the governor can perform upgrades (`onlyByGovernor`)
*/
function _authorizeUpgrade(address) internal view override onlyByGovernor {
// NOP
}
/// @dev Changes the governor of the contract.
/// @param _governor The new governor.
function changeGovernor(address _governor) external onlyByGovernor {
governor = _governor;
}
/// @dev Change the Randomizer callback gas limit.
/// @param _callbackGasLimit the new limit.
function setCallbackGasLimit(uint256 _callbackGasLimit) external onlyByGovernor {
callbackGasLimit = _callbackGasLimit;
}
/// @dev Change the Randomizer address.
/// @param _randomizer the new Randomizer address.
function setRandomizer(address _randomizer) external onlyByGovernor {
randomizer = IRandomizer(_randomizer);
}
/// @dev Allows the governor to withdraw randomizer funds.
/// @param _amount Amount to withdraw in wei.
function randomizerWithdraw(uint256 _amount) external onlyByGovernor {
randomizer.clientWithdrawTo(msg.sender, _amount);
}
// ************************************* //
// * State Modifiers * //
// ************************************* //
/// @dev Request a random number. The id of the request is tied to the sender.
function requestRandomness(uint256 /*_block*/) external override {
uint256 id = randomizer.request(callbackGasLimit);
requesterToID[msg.sender] = id;
}
/// @dev Callback function called by the randomizer contract when the random value is generated.
function randomizerCallback(uint256 _id, bytes32 _value) external {
require(msg.sender == address(randomizer), "Randomizer only");
randomNumbers[_id] = uint256(_value);
}
function receiveRandomnessFallback(uint256 _block) external {}
// ************************************* //
// * Public Views * //
// ************************************* //
/// @dev Return the random number.
/// @return randomNumber The random number or 0 if it is not ready or has not been requested.
function receiveRandomness(uint256 /*_block*/) external view override returns (uint256 randomNumber) {
// Get the latest request ID for this requester.
uint256 id = requesterToID[msg.sender];
randomNumber = randomNumbers[id];
}
}