Skip to content

Fix: Randomizer.ai contract upgrade and callback signature change #519

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 26, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion contracts/deploy/00-home-chain-arbitration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const pnkByChain = new Map<HomeChains, string>([

const randomizerByChain = new Map<HomeChains, string>([
[HomeChains.ARBITRUM_ONE, "0x00"],
[HomeChains.ARBITRUM_GOERLI, "0xE1B6CcAc0BB0355C01A049e78909231Bfa13620B"],
[HomeChains.ARBITRUM_GOERLI, "0x57F7a8aA8291A04B325F3f0d2c4d03353d3Ef25f"],
]);

const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
Expand Down
72 changes: 72 additions & 0 deletions contracts/deploy/00-rng.ts
Original file line number Diff line number Diff line change
@@ -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, string>([
[HomeChains.ARBITRUM_ONE, "0x330bD769382cFc6d50175903434CCC8D206DCAE5"],
[HomeChains.ARBITRUM_GOERLI, "0x4DEeeFD054434bf6721eF39Aa18EfB3fd0D12610"],
]);

const randomizerByChain = new Map<HomeChains, string>([
[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;
117 changes: 73 additions & 44 deletions contracts/deployments/arbitrumGoerli/RandomizerRNG.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions contracts/src/rng/IRandomizer.sol
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8;

// Randomizer protocol interface
interface IRandomizer {
function request(uint256 callbackGasLimit) external returns (uint256);
Expand Down
68 changes: 49 additions & 19 deletions contracts/src/rng/RandomizerRNG.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -31,44 +35,70 @@ contract RandomizerRNG is RNG {
governor = _governor;
}

// ************************ //
// * Governance * //
// ************************ //

/** @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 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];
}
}
2 changes: 1 addition & 1 deletion contracts/src/rng/mock/RandomizerMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}