Skip to content

Commit d570e96

Browse files
Merge pull request #348 from MerlinEgalite/feat/chainlink-rng
feat(ChainlinkRNG): Add Chainlink RNG contract
2 parents 54df464 + 8b33dae commit d570e96

File tree

4 files changed

+1532
-12
lines changed

4 files changed

+1532
-12
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/**
2+
* @authors: [@MerlinEgalite]
3+
* @reviewers: []
4+
* @auditors: []
5+
* @bounties: []
6+
* @deployments: []
7+
*/
8+
pragma solidity ^0.6.6;
9+
10+
import "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol";
11+
import "./RNG.sol";
12+
13+
14+
interface IKlerosLiquid {
15+
function passPhase() external;
16+
}
17+
18+
19+
/**
20+
* @title Random Number Generator using Chainlink Verifiable Randomness Mechanism on Polygon
21+
* @author Merlin Egalite - <egalite.merlin@gmail.com>
22+
*
23+
* @dev This contract implements the RNG standard and inherits from VRFConsumerBase to use Chainlink Verifiable Randomness Mechanism.
24+
* @dev It allows to store the random number associated to the requests made.
25+
* @dev Note that to make requests to Chainlink, the contract needs to be funded with some LINK.
26+
* @dev Chainlink documentation: https://docs.chain.link/docs/chainlink-vrf/
27+
* @dev For SECURITY CONSIDERATIONS, you might also have look to: https://github.com/smartcontractkit/chainlink/blob/master/evm-contracts/src/v0.6/VRFConsumerBase.sol
28+
*/
29+
contract ChainlinkRNG is RNG, VRFConsumerBase {
30+
31+
/* Storage */
32+
33+
IKlerosLiquid public kleros; // The address of Kleros Liquid.
34+
bytes32 internal keyHash; // The key hash for the VRF Coordinator.
35+
uint256 internal fee; // The amount of LINK to send with a request.
36+
mapping(bytes32 => uint256) public randomNumber; // randomNumber[requestId] is the random number for the requestId, 0 otherwise.
37+
38+
/* Modifier */
39+
40+
modifier onlyByKleros() {
41+
require(msg.sender == address(kleros), "ChainlinkRNG: not called by Kleros");
42+
_;
43+
}
44+
45+
/* Constructor */
46+
47+
/**
48+
* @dev Constructs the ChainlinkRNG contract.
49+
* @param _vrfCoordinator The address of VRFCoordinator contract.
50+
* @param _link The address of LINK token contract.
51+
* @param _kleros The address of Kleros Liquid's contract.
52+
* @param _keyHash The key hash for the VRF Coordinator.
53+
* @param _fee The amount of LINK to send with a request.
54+
*
55+
* @dev https://docs.chain.link/docs/link-token-contracts
56+
*/
57+
constructor(
58+
address _vrfCoordinator,
59+
address _link,
60+
IKlerosLiquid _kleros,
61+
bytes32 _keyHash,
62+
uint256 _fee
63+
)
64+
VRFConsumerBase(_vrfCoordinator, _link)
65+
public
66+
{
67+
keyHash = _keyHash;
68+
kleros = _kleros;
69+
fee = _fee;
70+
}
71+
72+
/* External */
73+
74+
/**
75+
* @dev Withdraws all LINK tokens locked in this contract.
76+
*/
77+
function withdrawLink() external onlyByKleros {
78+
require(LINK.transfer(msg.sender, LINK.balanceOf(address(this))), "ChainlinkRNG: unable to transfer LINK tokens");
79+
}
80+
81+
/**
82+
* @dev Changes the `fee` storage variable.
83+
* @param _newFee The new value for the `fee` storage variable.
84+
*/
85+
function changeFee(uint256 _newFee) external onlyByKleros {
86+
fee = _newFee;
87+
}
88+
89+
/**
90+
* @dev Changes the `kleros` storage variable.
91+
* @param _newKleros The new value for the `kleros` storage variable.
92+
*/
93+
function changeKleros(IKlerosLiquid _newKleros) external onlyByKleros {
94+
kleros = _newKleros;
95+
}
96+
97+
/**
98+
* @dev Requests a random number.
99+
* @dev The _seed parameter is vestigial, and is kept only for API
100+
* @dev compatibility with older versions. It can't *hurt* to mix in some of
101+
* @dev your own randomness, here, but it's not necessary because the VRF
102+
* @dev oracle will mix the hash of the block containing your request into the
103+
* @dev VRF seed it ultimately uses.
104+
* @param _seed seed mixed into the input of the VRF.
105+
* @return requestId unique ID for this request.
106+
*/
107+
function requestRN(uint _seed) external onlyByKleros returns (bytes32 requestId) {
108+
require(LINK.balanceOf(address(this)) >= fee, "ChainlinkRNG: not enough LINK to pay the fee");
109+
return requestRandomness(keyHash, fee, _seed);
110+
}
111+
112+
/**
113+
* @dev Gets the random number associated to a `_requestId`.
114+
* @param _requestId The request Id initially returned by requestRN.
115+
* @return RN Random Number. If the number is not ready or has not been required it returns 0.
116+
*/
117+
function getRN(bytes32 _requestId) external view returns (uint256 RN) {
118+
return randomNumber[_requestId];
119+
}
120+
121+
/* Internal */
122+
123+
/**
124+
* @dev Stores the random number given by the VRF Coordinator and calls passPhase function on Kleros Liquid.
125+
* @dev This is the callback function used by the VRF Coordinator.
126+
* @param _requestId The request Id initially returned by requestRN.
127+
* @param _randomness the VRF output.
128+
*/
129+
function fulfillRandomness(bytes32 _requestId, uint256 _randomness) internal override {
130+
randomNumber[_requestId] = _randomness;
131+
IKlerosLiquid(kleros).passPhase();
132+
}
133+
}

contracts/standard/rng/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ BlockhashRNGFallback.sol does the same as the previous contract but fallback to
88

99
TrustedRNG.sol implements a random number generator based on a trusted third party.
1010

11-
ConstantNG.sol implements a contracts always returning a specified number to ease testing.
11+
ConstantNG.sol implements a contract always returning a specified number to ease testing.
12+
13+
Chainlink.sol implements the RNG standard using Chainlink's Verifiable Randomness Mechanism

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"dependencies": {
5656
"@kleros/kleros": "^0.1.2",
5757
"@realitio/realitio-contracts": "^2.0.5",
58+
"@chainlink/contracts": "^0.1.7",
5859
"minimetoken": "^0.2.0",
5960
"openzeppelin-solidity": "^1.12.0",
6061
"web3-utils": "^1.2.1"

0 commit comments

Comments
 (0)