diff --git a/contracts/deploy/00-home-chain-arbitration.ts b/contracts/deploy/00-home-chain-arbitration.ts index e0a847ff3..4a81f916b 100644 --- a/contracts/deploy/00-home-chain-arbitration.ts +++ b/contracts/deploy/00-home-chain-arbitration.ts @@ -15,7 +15,7 @@ const pnkByChain = new Map([ const randomizerByChain = new Map([ [HomeChains.ARBITRUM_ONE, "0x00"], - [HomeChains.ARBITRUM_GOERLI, "0xE1B6CcAc0BB0355C01A049e78909231Bfa13620B"], + [HomeChains.ARBITRUM_GOERLI, "0x57F7a8aA8291A04B325F3f0d2c4d03353d3Ef25f"], ]); const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { diff --git a/contracts/deploy/00-rng.ts b/contracts/deploy/00-rng.ts new file mode 100644 index 000000000..afd5045b6 --- /dev/null +++ b/contracts/deploy/00-rng.ts @@ -0,0 +1,72 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { BigNumber } from "ethers"; +import { DisputeKitClassic, RandomizerRNG } from "../typechain-types"; + +enum HomeChains { + ARBITRUM_ONE = 42161, + ARBITRUM_GOERLI = 421613, + HARDHAT = 31337, +} + +const pnkByChain = new Map([ + [HomeChains.ARBITRUM_ONE, "0x330bD769382cFc6d50175903434CCC8D206DCAE5"], + [HomeChains.ARBITRUM_GOERLI, "0x4DEeeFD054434bf6721eF39Aa18EfB3fd0D12610"], +]); + +const randomizerByChain = new Map([ + [HomeChains.ARBITRUM_ONE, "0x00"], + [HomeChains.ARBITRUM_GOERLI, "0x57F7a8aA8291A04B325F3f0d2c4d03353d3Ef25f"], +]); + +const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { deployments, getNamedAccounts, getChainId } = hre; + const { deploy, execute } = deployments; + const { AddressZero } = hre.ethers.constants; + const RNG_LOOKAHEAD = 20; + + // fallback to hardhat node signers on local network + const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address; + const chainId = Number(await getChainId()); + console.log("deploying to %s with deployer %s", HomeChains[chainId], deployer); + + if (chainId === HomeChains.HARDHAT) { + pnkByChain.set( + HomeChains.HARDHAT, + ( + await deploy("PNK", { + from: deployer, + log: true, + }) + ).address + ); + randomizerByChain.set( + HomeChains.HARDHAT, + ( + await deploy("RandomizerMock", { + from: deployer, + args: [], + log: true, + }) + ).address + ); + } + + const randomizer = randomizerByChain.get(Number(await getChainId())) ?? AddressZero; + const rng = await deploy("RandomizerRNG", { + from: deployer, + args: [randomizer, deployer], + log: true, + }); + + const disputeKit = (await hre.ethers.getContract("DisputeKitClassic")) as DisputeKitClassic; + await disputeKit.changeRandomNumberGenerator(rng.address, RNG_LOOKAHEAD); +}; + +deployArbitration.tags = ["HomeChain", "RNG"]; +deployArbitration.skip = async ({ getChainId }) => { + const chainId = Number(await getChainId()); + return !HomeChains[chainId]; +}; + +export default deployArbitration; diff --git a/contracts/deployments/arbitrumGoerli/RandomizerRNG.json b/contracts/deployments/arbitrumGoerli/RandomizerRNG.json index 3bf93097b..b1486402d 100644 --- a/contracts/deployments/arbitrumGoerli/RandomizerRNG.json +++ b/contracts/deployments/arbitrumGoerli/RandomizerRNG.json @@ -1,5 +1,5 @@ { - "address": "0xb82D1eAD813C3a2E729F288276cc402343423Bad", + "address": "0x4699A8f70A90b427623B10Cf3de917F8F7239de4", "abi": [ { "inputs": [ @@ -19,7 +19,7 @@ }, { "inputs": [], - "name": "CALLBACK_GAS_LIMIT", + "name": "callbackGasLimit", "outputs": [ { "internalType": "uint256", @@ -59,9 +59,9 @@ { "inputs": [ { - "internalType": "uint128", + "internalType": "uint256", "name": "", - "type": "uint128" + "type": "uint256" } ], "name": "randomNumbers", @@ -91,9 +91,9 @@ { "inputs": [ { - "internalType": "uint128", + "internalType": "uint256", "name": "_id", - "type": "uint128" + "type": "uint256" }, { "internalType": "bytes32", @@ -162,40 +162,66 @@ "name": "requesterToID", "outputs": [ { - "internalType": "uint128", + "internalType": "uint256", "name": "", - "type": "uint128" + "type": "uint256" } ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_callbackGasLimit", + "type": "uint256" + } + ], + "name": "setCallbackGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_randomizer", + "type": "address" + } + ], + "name": "setRandomizer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ], - "transactionHash": "0xa181a21cd4a0f43618c9bafd33f75eb5081a899621653772493c8f43b55736d0", + "transactionHash": "0x1bef1f9a4296474d80e5101c7fadb40689d8d98619966ab8b374a8bce986fd96", "receipt": { "to": null, "from": "0xF50E77f2A2B6138D16c6c7511562E5C33c4B15A3", - "contractAddress": "0xb82D1eAD813C3a2E729F288276cc402343423Bad", + "contractAddress": "0x4699A8f70A90b427623B10Cf3de917F8F7239de4", "transactionIndex": 1, - "gasUsed": "2513664", + "gasUsed": "409376", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x28d1d380c32cb02551206f07079570881cbbb82e68917bff0bc78868ff15dc5c", - "transactionHash": "0xa181a21cd4a0f43618c9bafd33f75eb5081a899621653772493c8f43b55736d0", + "blockHash": "0xad8a7cfd25cf57ff569bd1edceb0566cb6c3b231ac67347b26eb3f067b137d4d", + "transactionHash": "0x1bef1f9a4296474d80e5101c7fadb40689d8d98619966ab8b374a8bce986fd96", "logs": [], - "blockNumber": 4027975, - "cumulativeGasUsed": "2513664", + "blockNumber": 5667234, + "cumulativeGasUsed": "409376", "status": 1, "byzantium": true }, "args": [ - "0xE1B6CcAc0BB0355C01A049e78909231Bfa13620B", + "0x57F7a8aA8291A04B325F3f0d2c4d03353d3Ef25f", "0xF50E77f2A2B6138D16c6c7511562E5C33c4B15A3" ], - "numDeployments": 2, - "solcInputHash": "8e4e08d76a7f02df476a9f91ae4ef934", - "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IRandomizer\",\"name\":\"_randomizer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CALLBACK_GAS_LIMIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"name\":\"randomNumbers\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"randomizer\",\"outputs\":[{\"internalType\":\"contract IRandomizer\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_id\",\"type\":\"uint128\"},{\"internalType\":\"bytes32\",\"name\":\"_value\",\"type\":\"bytes32\"}],\"name\":\"randomizerCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"randomizerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"receiveRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"randomNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"requestRandomness\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"requesterToID\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"changeGovernor(address)\":{\"details\":\"Changes the governor of the contract.\",\"params\":{\"_governor\":\"The new governor.\"}},\"constructor\":{\"details\":\"Constructor.\",\"params\":{\"_governor\":\"Governor of the contract.\",\"_randomizer\":\"Randomizer contract.\"}},\"randomizerCallback(uint128,bytes32)\":{\"details\":\"Callback function called by the randomizer contract when the random value is generated.\"},\"randomizerWithdraw(uint256)\":{\"details\":\"Allows the governor to withdraw randomizer funds.\",\"params\":{\"_amount\":\"Amount to withdraw in wei.\"}},\"receiveRandomness(uint256)\":{\"details\":\"Return the random number.\",\"returns\":{\"randomNumber\":\"The random number or 0 if it is not ready or has not been requested.\"}},\"requestRandomness(uint256)\":{\"details\":\"Request a random number. The id of the request is tied to the sender.\"}},\"title\":\"Random Number Generator that uses Randomizer.ai https://randomizer.ai/\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/rng/RandomizerRNG.sol\":\"RandomizerRNG\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/rng/IRandomizer.sol\":{\"content\":\"// Randomizer protocol interface\\ninterface IRandomizer {\\n function request(uint256 callbackGasLimit) external returns (uint256);\\n\\n function clientWithdrawTo(address _to, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0x4bf30691fbfcf344ea0dabfdfe60841ba9982c5f81ee7b8f4313de005df456f9\"},\"src/rng/RNG.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8;\\n\\ninterface RNG {\\n /**\\n * @dev Request a random number.\\n * @param _block Block linked to the request.\\n */\\n function requestRandomness(uint256 _block) external;\\n\\n /**\\n * @dev Receive the random number.\\n * @param _block Block the random number is linked to.\\n * @return randomNumber Random Number. If the number is not ready or has not been required 0 instead.\\n */\\n function receiveRandomness(uint256 _block) external returns (uint256 randomNumber);\\n}\\n\",\"keccak256\":\"0x0075973344648673365c5a895e4315101e6ce896208a71eb7767f5a61bbf0fe1\",\"license\":\"MIT\"},\"src/rng/RandomizerRNG.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8;\\n\\nimport \\\"./RNG.sol\\\";\\nimport \\\"./IRandomizer.sol\\\";\\n\\n/**\\n * @title Random Number Generator that uses Randomizer.ai\\n * https://randomizer.ai/\\n */\\ncontract RandomizerRNG is RNG {\\n uint256 public constant CALLBACK_GAS_LIMIT = 50000;\\n address public governor; // The address that can withdraw funds.\\n\\n IRandomizer public randomizer; // Randomizer address.\\n mapping(uint128 => uint256) public randomNumbers; // randomNumbers[requestID] is the random number for this request id, 0 otherwise.\\n mapping(address => uint128) public requesterToID; // Maps the requester to his latest request ID.\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Governor only\\\");\\n _;\\n }\\n\\n /** @dev Constructor.\\n * @param _randomizer Randomizer contract.\\n * @param _governor Governor of the contract.\\n */\\n constructor(IRandomizer _randomizer, address _governor) {\\n randomizer = _randomizer;\\n governor = _governor;\\n }\\n\\n /** @dev Changes the governor of the contract.\\n * @param _governor The new governor.\\n */\\n function changeGovernor(address _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /**\\n * @dev Request a random number. The id of the request is tied to the sender.\\n */\\n function requestRandomness(uint256 /*_block*/) external override {\\n uint128 id = uint128(randomizer.request(CALLBACK_GAS_LIMIT));\\n requesterToID[msg.sender] = id;\\n }\\n\\n /**\\n * @dev Return the random number.\\n * @return randomNumber The random number or 0 if it is not ready or has not been requested.\\n */\\n function receiveRandomness(uint256 /*_block*/) external view override returns (uint256 randomNumber) {\\n // Get the latest request ID for this requester.\\n uint128 id = requesterToID[msg.sender];\\n randomNumber = randomNumbers[id];\\n }\\n\\n /**\\n * @dev Callback function called by the randomizer contract when the random value is generated.\\n */\\n function randomizerCallback(uint128 _id, bytes32 _value) external {\\n require(msg.sender == address(randomizer), \\\"Caller not Randomizer\\\");\\n randomNumbers[_id] = uint256(_value);\\n }\\n\\n /**\\n * @dev Allows the governor to withdraw randomizer funds.\\n * @param _amount Amount to withdraw in wei.\\n */\\n function randomizerWithdraw(uint256 _amount) external onlyByGovernor {\\n randomizer.clientWithdrawTo(msg.sender, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xfce1c19809663a056cdf5c7082e8ba8d808fb40103bfdb0c1a3b1b9047a5108e\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b506040516105c63803806105c683398101604081905261002f91610078565b600180546001600160a01b039384166001600160a01b031991821617909155600080549290931691161790556100b2565b6001600160a01b038116811461007557600080fd5b50565b6000806040838503121561008b57600080fd5b825161009681610060565b60208401519092506100a781610060565b809150509250929050565b610505806100c16000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c80634e07c939116100665780634e07c9391461015757806371d4b00b1461016a5780637363ae1f146101ab578063e4c0aaf4146101be578063f10fb584146101d157600080fd5b80630c340a24146100a357806313cf9054146100d35780631dfcc23f1461011957806321e46a1a1461012e57806333d608f11461014e575b600080fd5b6000546100b6906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61010b6100e13660046103e5565b50336000908152600360209081526040808320546001600160801b03168352600290915290205490565b6040519081526020016100ca565b61012c61012736600461041a565b6101e4565b005b61010b61013c366004610444565b60026020526000908152604090205481565b61010b61c35081565b61012c6101653660046103e5565b610257565b610193610178366004610466565b6003602052600090815260409020546001600160801b031681565b6040516001600160801b0390911681526020016100ca565b61012c6101b93660046103e5565b6102e8565b61012c6101cc366004610466565b610399565b6001546100b6906001600160a01b031681565b6001546001600160a01b0316331461023b5760405162461bcd60e51b815260206004820152601560248201527421b0b63632b9103737ba102930b73237b6b4bd32b960591b60448201526064015b60405180910390fd5b6001600160801b03909116600090815260026020526040902055565b6000546001600160a01b031633146102815760405162461bcd60e51b81526004016102329061048f565b600154604051632465f8f560e01b8152336004820152602481018390526001600160a01b0390911690632465f8f590604401600060405180830381600087803b1580156102cd57600080fd5b505af11580156102e1573d6000803e3d6000fd5b5050505050565b60015460405163d845a4b360e01b815261c35060048201526000916001600160a01b03169063d845a4b390602401602060405180830381600087803b15801561033057600080fd5b505af1158015610344573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061036891906104b6565b33600090815260036020526040902080546001600160801b0319166001600160801b03929092169190911790555050565b6000546001600160a01b031633146103c35760405162461bcd60e51b81526004016102329061048f565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000602082840312156103f757600080fd5b5035919050565b80356001600160801b038116811461041557600080fd5b919050565b6000806040838503121561042d57600080fd5b610436836103fe565b946020939093013593505050565b60006020828403121561045657600080fd5b61045f826103fe565b9392505050565b60006020828403121561047857600080fd5b81356001600160a01b038116811461045f57600080fd5b6020808252600d908201526c476f7665726e6f72206f6e6c7960981b604082015260600190565b6000602082840312156104c857600080fd5b505191905056fea2646970667358221220dcda61f0eb0832fc83fecdd1784ace5a85912df421259d09350ee75d641047b964736f6c63430008090033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061009e5760003560e01c80634e07c939116100665780634e07c9391461015757806371d4b00b1461016a5780637363ae1f146101ab578063e4c0aaf4146101be578063f10fb584146101d157600080fd5b80630c340a24146100a357806313cf9054146100d35780631dfcc23f1461011957806321e46a1a1461012e57806333d608f11461014e575b600080fd5b6000546100b6906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61010b6100e13660046103e5565b50336000908152600360209081526040808320546001600160801b03168352600290915290205490565b6040519081526020016100ca565b61012c61012736600461041a565b6101e4565b005b61010b61013c366004610444565b60026020526000908152604090205481565b61010b61c35081565b61012c6101653660046103e5565b610257565b610193610178366004610466565b6003602052600090815260409020546001600160801b031681565b6040516001600160801b0390911681526020016100ca565b61012c6101b93660046103e5565b6102e8565b61012c6101cc366004610466565b610399565b6001546100b6906001600160a01b031681565b6001546001600160a01b0316331461023b5760405162461bcd60e51b815260206004820152601560248201527421b0b63632b9103737ba102930b73237b6b4bd32b960591b60448201526064015b60405180910390fd5b6001600160801b03909116600090815260026020526040902055565b6000546001600160a01b031633146102815760405162461bcd60e51b81526004016102329061048f565b600154604051632465f8f560e01b8152336004820152602481018390526001600160a01b0390911690632465f8f590604401600060405180830381600087803b1580156102cd57600080fd5b505af11580156102e1573d6000803e3d6000fd5b5050505050565b60015460405163d845a4b360e01b815261c35060048201526000916001600160a01b03169063d845a4b390602401602060405180830381600087803b15801561033057600080fd5b505af1158015610344573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061036891906104b6565b33600090815260036020526040902080546001600160801b0319166001600160801b03929092169190911790555050565b6000546001600160a01b031633146103c35760405162461bcd60e51b81526004016102329061048f565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000602082840312156103f757600080fd5b5035919050565b80356001600160801b038116811461041557600080fd5b919050565b6000806040838503121561042d57600080fd5b610436836103fe565b946020939093013593505050565b60006020828403121561045657600080fd5b61045f826103fe565b9392505050565b60006020828403121561047857600080fd5b81356001600160a01b038116811461045f57600080fd5b6020808252600d908201526c476f7665726e6f72206f6e6c7960981b604082015260600190565b6000602082840312156104c857600080fd5b505191905056fea2646970667358221220dcda61f0eb0832fc83fecdd1784ace5a85912df421259d09350ee75d641047b964736f6c63430008090033", + "numDeployments": 4, + "solcInputHash": "1c6c6453da39455c29c10ffc5c8fc7ea", + "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IRandomizer\",\"name\":\"_randomizer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"callbackGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"randomNumbers\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"randomizer\",\"outputs\":[{\"internalType\":\"contract IRandomizer\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_value\",\"type\":\"bytes32\"}],\"name\":\"randomizerCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"randomizerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"receiveRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"randomNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"requestRandomness\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"requesterToID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_callbackGasLimit\",\"type\":\"uint256\"}],\"name\":\"setCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_randomizer\",\"type\":\"address\"}],\"name\":\"setRandomizer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"changeGovernor(address)\":{\"details\":\"Changes the governor of the contract.\",\"params\":{\"_governor\":\"The new governor.\"}},\"constructor\":{\"details\":\"Constructor.\",\"params\":{\"_governor\":\"Governor of the contract.\",\"_randomizer\":\"Randomizer contract.\"}},\"randomizerCallback(uint256,bytes32)\":{\"details\":\"Callback function called by the randomizer contract when the random value is generated.\"},\"randomizerWithdraw(uint256)\":{\"details\":\"Allows the governor to withdraw randomizer funds.\",\"params\":{\"_amount\":\"Amount to withdraw in wei.\"}},\"receiveRandomness(uint256)\":{\"details\":\"Return the random number.\",\"returns\":{\"randomNumber\":\"The random number or 0 if it is not ready or has not been requested.\"}},\"requestRandomness(uint256)\":{\"details\":\"Request a random number. The id of the request is tied to the sender.\"}},\"title\":\"Random Number Generator that uses Randomizer.ai https://randomizer.ai/\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/rng/RandomizerRNG.sol\":\"RandomizerRNG\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/rng/IRandomizer.sol\":{\"content\":\"// Randomizer protocol interface\\ninterface IRandomizer {\\n function request(uint256 callbackGasLimit) external returns (uint256);\\n\\n function clientWithdrawTo(address _to, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0x4bf30691fbfcf344ea0dabfdfe60841ba9982c5f81ee7b8f4313de005df456f9\"},\"src/rng/RNG.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8;\\n\\ninterface RNG {\\n /**\\n * @dev Request a random number.\\n * @param _block Block linked to the request.\\n */\\n function requestRandomness(uint256 _block) external;\\n\\n /**\\n * @dev Receive the random number.\\n * @param _block Block the random number is linked to.\\n * @return randomNumber Random Number. If the number is not ready or has not been required 0 instead.\\n */\\n function receiveRandomness(uint256 _block) external returns (uint256 randomNumber);\\n}\\n\",\"keccak256\":\"0x0075973344648673365c5a895e4315101e6ce896208a71eb7767f5a61bbf0fe1\",\"license\":\"MIT\"},\"src/rng/RandomizerRNG.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8;\\n\\nimport \\\"./RNG.sol\\\";\\nimport \\\"./IRandomizer.sol\\\";\\n\\n/**\\n * @title Random Number Generator that uses Randomizer.ai\\n * https://randomizer.ai/\\n */\\ncontract RandomizerRNG is RNG {\\n address public governor; // The address that can withdraw funds.\\n uint256 public callbackGasLimit = 50000; // Gas limit for the randomizer callback\\n\\n IRandomizer public randomizer; // Randomizer address.\\n mapping(uint256 => uint256) public randomNumbers; // randomNumbers[requestID] is the random number for this request id, 0 otherwise.\\n mapping(address => uint256) public requesterToID; // Maps the requester to his latest request ID.\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Governor only\\\");\\n _;\\n }\\n\\n /** @dev Constructor.\\n * @param _randomizer Randomizer contract.\\n * @param _governor Governor of the contract.\\n */\\n constructor(IRandomizer _randomizer, address _governor) {\\n randomizer = _randomizer;\\n governor = _governor;\\n }\\n\\n /** @dev Changes the governor of the contract.\\n * @param _governor The new governor.\\n */\\n function changeGovernor(address _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n function setCallbackGasLimit(uint256 _callbackGasLimit) external onlyByGovernor {\\n callbackGasLimit = _callbackGasLimit;\\n }\\n\\n function setRandomizer(address _randomizer) external onlyByGovernor {\\n randomizer = IRandomizer(_randomizer);\\n }\\n\\n /**\\n * @dev Request a random number. The id of the request is tied to the sender.\\n */\\n function requestRandomness(uint256 /*_block*/) external override {\\n uint256 id = uint256(randomizer.request(callbackGasLimit));\\n requesterToID[msg.sender] = id;\\n }\\n\\n /**\\n * @dev Return the random number.\\n * @return randomNumber The random number or 0 if it is not ready or has not been requested.\\n */\\n function receiveRandomness(uint256 /*_block*/) external view override returns (uint256 randomNumber) {\\n // Get the latest request ID for this requester.\\n uint256 id = requesterToID[msg.sender];\\n randomNumber = randomNumbers[id];\\n }\\n\\n /**\\n * @dev Callback function called by the randomizer contract when the random value is generated.\\n */\\n function randomizerCallback(uint256 _id, bytes32 _value) external {\\n require(msg.sender == address(randomizer), \\\"Randomizer only\\\");\\n randomNumbers[_id] = uint256(_value);\\n }\\n\\n /**\\n * @dev Allows the governor to withdraw randomizer funds.\\n * @param _amount Amount to withdraw in wei.\\n */\\n function randomizerWithdraw(uint256 _amount) external onlyByGovernor {\\n randomizer.clientWithdrawTo(msg.sender, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x49b6344b31bcb0416c67f05999b54c5e0ca7c94f579a91215ba57f22a57905e9\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405261c35060015534801561001657600080fd5b506040516105f43803806105f48339810160408190526100359161007e565b600280546001600160a01b039384166001600160a01b031991821617909155600080549290931691161790556100b8565b6001600160a01b038116811461007b57600080fd5b50565b6000806040838503121561009157600080fd5b825161009c81610066565b60208401519092506100ad81610066565b809150509250929050565b61052d806100c76000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80637363ae1f116100715780637363ae1f14610184578063767bcab5146101975780638a54942f146101aa578063e4c0aaf4146101bd578063ebe93caf146101d0578063f10fb584146101e357600080fd5b80630c340a24146100b957806313cf9054146100e957806324f74697146101265780634e07c9391461012f5780635257cd901461014457806371d4b00b14610164575b600080fd5b6000546100cc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101186100f736600461044c565b50336000908152600460209081526040808320548352600390915290205490565b6040519081526020016100e0565b61011860015481565b61014261013d36600461044c565b6101f6565b005b61011861015236600461044c565b60036020526000908152604090205481565b610118610172366004610465565b60046020526000908152604090205481565b61014261019236600461044c565b610290565b6101426101a5366004610465565b610327565b6101426101b836600461044c565b610373565b6101426101cb366004610465565b6103a2565b6101426101de366004610495565b6103ee565b6002546100cc906001600160a01b031681565b6000546001600160a01b031633146102295760405162461bcd60e51b8152600401610220906104b7565b60405180910390fd5b600254604051632465f8f560e01b8152336004820152602481018390526001600160a01b0390911690632465f8f590604401600060405180830381600087803b15801561027557600080fd5b505af1158015610289573d6000803e3d6000fd5b5050505050565b60025460015460405163d845a4b360e01b815260048101919091526000916001600160a01b03169063d845a4b390602401602060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031391906104de565b336000908152600460205260409020555050565b6000546001600160a01b031633146103515760405162461bcd60e51b8152600401610220906104b7565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331461039d5760405162461bcd60e51b8152600401610220906104b7565b600155565b6000546001600160a01b031633146103cc5760405162461bcd60e51b8152600401610220906104b7565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b0316331461043a5760405162461bcd60e51b815260206004820152600f60248201526e52616e646f6d697a6572206f6e6c7960881b6044820152606401610220565b60009182526003602052604090912055565b60006020828403121561045e57600080fd5b5035919050565b60006020828403121561047757600080fd5b81356001600160a01b038116811461048e57600080fd5b9392505050565b600080604083850312156104a857600080fd5b50508035926020909101359150565b6020808252600d908201526c476f7665726e6f72206f6e6c7960981b604082015260600190565b6000602082840312156104f057600080fd5b505191905056fea26469706673582212204f0b1f47131cf6e7a694f64cddb3e7ea077af27f24772b7abca23527c78e4e6e64736f6c63430008090033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80637363ae1f116100715780637363ae1f14610184578063767bcab5146101975780638a54942f146101aa578063e4c0aaf4146101bd578063ebe93caf146101d0578063f10fb584146101e357600080fd5b80630c340a24146100b957806313cf9054146100e957806324f74697146101265780634e07c9391461012f5780635257cd901461014457806371d4b00b14610164575b600080fd5b6000546100cc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101186100f736600461044c565b50336000908152600460209081526040808320548352600390915290205490565b6040519081526020016100e0565b61011860015481565b61014261013d36600461044c565b6101f6565b005b61011861015236600461044c565b60036020526000908152604090205481565b610118610172366004610465565b60046020526000908152604090205481565b61014261019236600461044c565b610290565b6101426101a5366004610465565b610327565b6101426101b836600461044c565b610373565b6101426101cb366004610465565b6103a2565b6101426101de366004610495565b6103ee565b6002546100cc906001600160a01b031681565b6000546001600160a01b031633146102295760405162461bcd60e51b8152600401610220906104b7565b60405180910390fd5b600254604051632465f8f560e01b8152336004820152602481018390526001600160a01b0390911690632465f8f590604401600060405180830381600087803b15801561027557600080fd5b505af1158015610289573d6000803e3d6000fd5b5050505050565b60025460015460405163d845a4b360e01b815260048101919091526000916001600160a01b03169063d845a4b390602401602060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031391906104de565b336000908152600460205260409020555050565b6000546001600160a01b031633146103515760405162461bcd60e51b8152600401610220906104b7565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331461039d5760405162461bcd60e51b8152600401610220906104b7565b600155565b6000546001600160a01b031633146103cc5760405162461bcd60e51b8152600401610220906104b7565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b0316331461043a5760405162461bcd60e51b815260206004820152600f60248201526e52616e646f6d697a6572206f6e6c7960881b6044820152606401610220565b60009182526003602052604090912055565b60006020828403121561045e57600080fd5b5035919050565b60006020828403121561047757600080fd5b81356001600160a01b038116811461048e57600080fd5b9392505050565b600080604083850312156104a857600080fd5b50508035926020909101359150565b6020808252600d908201526c476f7665726e6f72206f6e6c7960981b604082015260600190565b6000602082840312156104f057600080fd5b505191905056fea26469706673582212204f0b1f47131cf6e7a694f64cddb3e7ea077af27f24772b7abca23527c78e4e6e64736f6c63430008090033", "devdoc": { "kind": "dev", "methods": { @@ -212,7 +238,7 @@ "_randomizer": "Randomizer contract." } }, - "randomizerCallback(uint128,bytes32)": { + "randomizerCallback(uint256,bytes32)": { "details": "Callback function called by the randomizer contract when the random value is generated." }, "randomizerWithdraw(uint256)": { @@ -242,7 +268,7 @@ "storageLayout": { "storage": [ { - "astId": 17220, + "astId": 41, "contract": "src/rng/RandomizerRNG.sol:RandomizerRNG", "label": "governor", "offset": 0, @@ -250,28 +276,36 @@ "type": "t_address" }, { - "astId": 17223, + "astId": 44, "contract": "src/rng/RandomizerRNG.sol:RandomizerRNG", - "label": "randomizer", + "label": "callbackGasLimit", "offset": 0, "slot": "1", - "type": "t_contract(IRandomizer)17151" + "type": "t_uint256" }, { - "astId": 17227, + "astId": 47, "contract": "src/rng/RandomizerRNG.sol:RandomizerRNG", - "label": "randomNumbers", + "label": "randomizer", "offset": 0, "slot": "2", - "type": "t_mapping(t_uint128,t_uint256)" + "type": "t_contract(IRandomizer)15" }, { - "astId": 17231, + "astId": 51, "contract": "src/rng/RandomizerRNG.sol:RandomizerRNG", - "label": "requesterToID", + "label": "randomNumbers", "offset": 0, "slot": "3", - "type": "t_mapping(t_address,t_uint128)" + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 55, + "contract": "src/rng/RandomizerRNG.sol:RandomizerRNG", + "label": "requesterToID", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_address,t_uint256)" } ], "types": { @@ -280,30 +314,25 @@ "label": "address", "numberOfBytes": "20" }, - "t_contract(IRandomizer)17151": { + "t_contract(IRandomizer)15": { "encoding": "inplace", "label": "contract IRandomizer", "numberOfBytes": "20" }, - "t_mapping(t_address,t_uint128)": { + "t_mapping(t_address,t_uint256)": { "encoding": "mapping", "key": "t_address", - "label": "mapping(address => uint128)", + "label": "mapping(address => uint256)", "numberOfBytes": "32", - "value": "t_uint128" + "value": "t_uint256" }, - "t_mapping(t_uint128,t_uint256)": { + "t_mapping(t_uint256,t_uint256)": { "encoding": "mapping", - "key": "t_uint128", - "label": "mapping(uint128 => uint256)", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", "numberOfBytes": "32", "value": "t_uint256" }, - "t_uint128": { - "encoding": "inplace", - "label": "uint128", - "numberOfBytes": "16" - }, "t_uint256": { "encoding": "inplace", "label": "uint256", diff --git a/contracts/src/rng/IRandomizer.sol b/contracts/src/rng/IRandomizer.sol index f72bf3588..63fe3123a 100644 --- a/contracts/src/rng/IRandomizer.sol +++ b/contracts/src/rng/IRandomizer.sol @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8; + // Randomizer protocol interface interface IRandomizer { function request(uint256 callbackGasLimit) external returns (uint256); diff --git a/contracts/src/rng/RandomizerRNG.sol b/contracts/src/rng/RandomizerRNG.sol index 985e4d0b9..b0fd3ea35 100644 --- a/contracts/src/rng/RandomizerRNG.sol +++ b/contracts/src/rng/RandomizerRNG.sol @@ -10,12 +10,16 @@ import "./IRandomizer.sol"; * https://randomizer.ai/ */ contract RandomizerRNG is RNG { - uint256 public constant CALLBACK_GAS_LIMIT = 50000; address public governor; // The address that can withdraw funds. + uint256 public callbackGasLimit = 50000; // Gas limit for the randomizer callback IRandomizer public randomizer; // Randomizer address. - mapping(uint128 => uint256) public randomNumbers; // randomNumbers[requestID] is the random number for this request id, 0 otherwise. - mapping(address => uint128) public requesterToID; // Maps the requester to his latest request ID. + 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"); @@ -31,6 +35,10 @@ contract RandomizerRNG is RNG { governor = _governor; } + // ************************ // + // * Governance * // + // ************************ // + /** @dev Changes the governor of the contract. * @param _governor The new governor. */ @@ -38,37 +46,59 @@ contract RandomizerRNG is RNG { 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 Request a random number. The id of the request is tied to the sender. + * @dev Allows the governor to withdraw randomizer funds. + * @param _amount Amount to withdraw in wei. */ - function requestRandomness(uint256 /*_block*/) external override { - uint128 id = uint128(randomizer.request(CALLBACK_GAS_LIMIT)); - requesterToID[msg.sender] = id; + function randomizerWithdraw(uint256 _amount) external onlyByGovernor { + randomizer.clientWithdrawTo(msg.sender, _amount); } + // ************************************* // + // * State Modifiers * // + // ************************************* // + /** - * @dev Return the random number. - * @return randomNumber The random number or 0 if it is not ready or has not been requested. + * @dev Request a random number. The id of the request is tied to the sender. */ - function receiveRandomness(uint256 /*_block*/) external view override returns (uint256 randomNumber) { - // Get the latest request ID for this requester. - uint128 id = requesterToID[msg.sender]; - randomNumber = randomNumbers[id]; + 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(uint128 _id, bytes32 _value) external { - require(msg.sender == address(randomizer), "Caller not Randomizer"); + function randomizerCallback(uint256 _id, bytes32 _value) external { + require(msg.sender == address(randomizer), "Randomizer only"); randomNumbers[_id] = uint256(_value); } + // ************************************* // + // * Public Views * // + // ************************************* // + /** - * @dev Allows the governor to withdraw randomizer funds. - * @param _amount Amount to withdraw in wei. + * @dev Return the random number. + * @return randomNumber The random number or 0 if it is not ready or has not been requested. */ - function randomizerWithdraw(uint256 _amount) external onlyByGovernor { - randomizer.clientWithdrawTo(msg.sender, _amount); + 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]; } } diff --git a/contracts/src/rng/mock/RandomizerMock.sol b/contracts/src/rng/mock/RandomizerMock.sol index d89dcd66c..2e1692af9 100644 --- a/contracts/src/rng/mock/RandomizerMock.sol +++ b/contracts/src/rng/mock/RandomizerMock.sol @@ -15,7 +15,7 @@ contract RandomizerMock is IRandomizer { revert("Not Implemented"); } - function relay(RandomizerRNG _rng, uint128 _id, bytes32 _value) external { + function relay(RandomizerRNG _rng, uint256 _id, bytes32 _value) external { _rng.randomizerCallback(_id, _value); } }