Skip to content

Instantly share code, notes, and snippets.

@ChiTimesChi
Created June 1, 2023 15:50
Show Gist options
  • Save ChiTimesChi/b4cb0c6b7eaa4ad3268210a8b614f91d to your computer and use it in GitHub Desktop.
Save ChiTimesChi/b4cb0c6b7eaa4ad3268210a8b614f91d to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
struct Random {
bytes32 seed;
}
using RandomLib for Random global;
// solhint-disable no-empty-blocks
// solhint-disable ordering
library RandomLib {
/// @notice Prevents this contract from being included in the coverage report
function testRandomLib() external {}
// @notice Returns next "random" bytes32 value and updates the Random's seed.
function next(Random memory r) internal pure returns (bytes32 value) {
value = r.seed;
r.seed = keccak256(bytes.concat(value));
}
// @notice Returns next "random" bytes value of given length and updates the Random's seed.
function nextBytes(Random memory r, uint256 length) internal pure returns (bytes memory value) {
value = new bytes(length);
uint256 words = length / 32;
for (uint256 i = 0; i < words; ++i) {
bytes32 word = r.next();
// TODO: This is probably not the best way to do this - rewrite in assembly
for (uint256 j = 0; j < 32; ++j) {
value[32 * i + j] = word[j];
}
}
uint256 remainder = length % 32;
if (remainder != 0) {
bytes32 word = r.next();
for (uint256 j = 0; j < remainder; ++j) {
value[32 * words + j] = word[j];
}
}
}
// @notice Returns next "random" bytes value having N memory words and updates the Random's seed.
function nextBytesWords(Random memory r, uint256 words) internal pure returns (bytes memory value) {
bytes32[] memory args = new bytes32[](words);
for (uint256 i = 0; i < words; ++i) {
args[i] = r.next();
}
return abi.encodePacked(args);
}
// @notice Returns next "random" uint256 value and updates the Random's seed.
function nextUint256(Random memory r) internal pure returns (uint256 value) {
return uint256(r.next());
}
// @notice Returns next "random" uint192 value and updates the Random's seed.
function nextUint192(Random memory r) internal pure returns (uint192 value) {
return uint192(r.nextUint256());
}
// @notice Returns next "random" uint160 value and updates the Random's seed.
function nextUint160(Random memory r) internal pure returns (uint160 value) {
return uint160(r.nextUint256());
}
// @notice Returns next "random" uint96 value and updates the Random's seed.
function nextUint96(Random memory r) internal pure returns (uint96 value) {
return uint96(r.nextUint256());
}
// @notice Returns next "random" uint64 value and updates the Random's seed.
function nextUint64(Random memory r) internal pure returns (uint64 value) {
return uint64(r.nextUint256());
}
// @notice Returns next "random" uint40 value and updates the Random's seed.
function nextUint40(Random memory r) internal pure returns (uint40 value) {
return uint40(r.nextUint256());
}
// @notice Returns next "random" uint32 value and updates the Random's seed.
function nextUint32(Random memory r) internal pure returns (uint32 value) {
return uint32(r.nextUint256());
}
// @notice Returns next "random" uint16 value and updates the Random's seed.
function nextUint16(Random memory r) internal pure returns (uint16 value) {
return uint16(r.nextUint256());
}
// @notice Returns next "random" uint8 value and updates the Random's seed.
function nextUint8(Random memory r) internal pure returns (uint8 value) {
return uint8(r.nextUint256());
}
// @notice Returns next "random" address value and updates the Random's seed.
function nextAddress(Random memory r) internal pure returns (address value) {
return address(r.nextUint160());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment