-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feature: ethereum vrf * fix: compilation * chore: remove fee tiers * feat: generalize * fix: tests * fix: prettier * chore: more prettier * chore: bump migration version * chore: fix compilation * fix: tests * fix: validation tests * chore: use new task to differentiate v2 versions * feat: refactor to support native * fix: lint * chore: rename V2.5 => V2Plus * chore: more renames * add gethwrapper for subscription api * Revert "add gethwrapper for subscription api" This reverts commit 9fd32de. * chore: revert pnpm lock change * fix: review comments * chore: fix comments * Wrapper contracts * fix: name clash * fix: lint and foundry build * fix: nit comments * fix: mistake * Remove redundant interface * Fix LINK and LINK_ETH_FEED naming * Readability * VRF-508 foundry tests * Update contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol Co-authored-by: Makram <makramkd@users.noreply.github.com> * Fix foundry profile discrepencies, test typos, and remove bloated initcode * Delete unnecessary chainspecificutil * Revert "Readability" This reverts commit a834f35. * Add wrapper foundry tests * Test cleanup * Remove unnecessary getters * Add wrappers * Undo consumer changes * Remove redundancy * Prettier * Add link setter * Fix merge conflicts * Update contracts/src/v0.8/vrf/VRFV2PlusWrapperConsumerBase.sol Co-authored-by: Makram <makramkd@users.noreply.github.com> * Revert "Update contracts/src/v0.8/vrf/VRFV2PlusWrapperConsumerBase.sol" This reverts commit 1391939. * Fix merge conflicts (2) --------- Co-authored-by: Makram Kamaleddine <makramkd@users.noreply.github.com> Co-authored-by: jinhoonbang <jin.bang@smartcontract.com>
- Loading branch information
1 parent
40a6d21
commit 2139327
Showing
17 changed files
with
3,816 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.6; | ||
|
||
import "../ChainSpecificUtil.sol"; | ||
|
||
/** | ||
* @title BlockhashStore | ||
* @notice This contract provides a way to access blockhashes older than | ||
* the 256 block limit imposed by the BLOCKHASH opcode. | ||
* You may assume that any blockhash stored by the contract is correct. | ||
* Note that the contract depends on the format of serialized Ethereum | ||
* blocks. If a future hardfork of Ethereum changes that format, the | ||
* logic in this contract may become incorrect and an updated version | ||
* would have to be deployed. | ||
*/ | ||
contract BlockhashStore { | ||
mapping(uint => bytes32) internal s_blockhashes; | ||
|
||
/** | ||
* @notice stores blockhash of a given block, assuming it is available through BLOCKHASH | ||
* @param n the number of the block whose blockhash should be stored | ||
*/ | ||
function store(uint256 n) public { | ||
bytes32 h = ChainSpecificUtil.getBlockhash(uint64(n)); | ||
require(h != 0x0, "blockhash(n) failed"); | ||
s_blockhashes[n] = h; | ||
} | ||
|
||
/** | ||
* @notice stores blockhash of the earliest block still available through BLOCKHASH. | ||
*/ | ||
function storeEarliest() external { | ||
store(ChainSpecificUtil.getBlockNumber() - 256); | ||
} | ||
|
||
/** | ||
* @notice stores blockhash after verifying blockheader of child/subsequent block | ||
* @param n the number of the block whose blockhash should be stored | ||
* @param header the rlp-encoded blockheader of block n+1. We verify its correctness by checking | ||
* that it hashes to a stored blockhash, and then extract parentHash to get the n-th blockhash. | ||
*/ | ||
function storeVerifyHeader(uint256 n, bytes memory header) public { | ||
require(keccak256(header) == s_blockhashes[n + 1], "header has unknown blockhash"); | ||
|
||
// At this point, we know that header is the correct blockheader for block n+1. | ||
|
||
// The header is an rlp-encoded list. The head item of that list is the 32-byte blockhash of the parent block. | ||
// Based on how rlp works, we know that blockheaders always have the following form: | ||
// 0xf9____a0PARENTHASH... | ||
// ^ ^ ^ | ||
// | | | | ||
// | | +--- PARENTHASH is 32 bytes. rlpenc(PARENTHASH) is 0xa || PARENTHASH. | ||
// | | | ||
// | +--- 2 bytes containing the sum of the lengths of the encoded list items | ||
// | | ||
// +--- 0xf9 because we have a list and (sum of lengths of encoded list items) fits exactly into two bytes. | ||
// | ||
// As a consequence, the PARENTHASH is always at offset 4 of the rlp-encoded block header. | ||
|
||
bytes32 parentHash; | ||
assembly { | ||
parentHash := mload(add(header, 36)) // 36 = 32 byte offset for length prefix of ABI-encoded array | ||
// + 4 byte offset of PARENTHASH (see above) | ||
} | ||
|
||
s_blockhashes[n] = parentHash; | ||
} | ||
|
||
/** | ||
* @notice gets a blockhash from the store. If no hash is known, this function reverts. | ||
* @param n the number of the block whose blockhash should be returned | ||
*/ | ||
function getBlockhash(uint256 n) external view returns (bytes32) { | ||
bytes32 h = s_blockhashes[n]; | ||
require(h != 0x0, "blockhash not found in store"); | ||
return h; | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
contracts/src/v0.8/interfaces/VRFV2PlusWrapperInterface.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
interface VRFV2PlusWrapperInterface { | ||
/** | ||
* @return the request ID of the most recent VRF V2 request made by this wrapper. This should only | ||
* be relied option within the same transaction that the request was made. | ||
*/ | ||
function lastRequestId() external view returns (uint256); | ||
|
||
/** | ||
* @notice Calculates the price of a VRF request with the given callbackGasLimit at the current | ||
* @notice block. | ||
* | ||
* @dev This function relies on the transaction gas price which is not automatically set during | ||
* @dev simulation. To estimate the price at a specific gas price, use the estimatePrice function. | ||
* | ||
* @param _callbackGasLimit is the gas limit used to estimate the price. | ||
*/ | ||
function calculateRequestPrice(uint32 _callbackGasLimit) external view returns (uint256); | ||
|
||
/** | ||
* @notice Calculates the price of a VRF request in native with the given callbackGasLimit at the current | ||
* @notice block. | ||
* | ||
* @dev This function relies on the transaction gas price which is not automatically set during | ||
* @dev simulation. To estimate the price at a specific gas price, use the estimatePrice function. | ||
* | ||
* @param _callbackGasLimit is the gas limit used to estimate the price. | ||
*/ | ||
function calculateRequestPriceNative(uint32 _callbackGasLimit) external view returns (uint256); | ||
|
||
/** | ||
* @notice Estimates the price of a VRF request with a specific gas limit and gas price. | ||
* | ||
* @dev This is a convenience function that can be called in simulation to better understand | ||
* @dev pricing. | ||
* | ||
* @param _callbackGasLimit is the gas limit used to estimate the price. | ||
* @param _requestGasPriceWei is the gas price in wei used for the estimation. | ||
*/ | ||
function estimateRequestPrice(uint32 _callbackGasLimit, uint256 _requestGasPriceWei) external view returns (uint256); | ||
|
||
/** | ||
* @notice Estimates the price of a VRF request in native with a specific gas limit and gas price. | ||
* | ||
* @dev This is a convenience function that can be called in simulation to better understand | ||
* @dev pricing. | ||
* | ||
* @param _callbackGasLimit is the gas limit used to estimate the price. | ||
* @param _requestGasPriceWei is the gas price in wei used for the estimation. | ||
*/ | ||
function estimateRequestPriceNative( | ||
uint32 _callbackGasLimit, | ||
uint256 _requestGasPriceWei | ||
) external view returns (uint256); | ||
|
||
/** | ||
* @notice Requests randomness from the VRF V2 wrapper, paying in native token. | ||
* | ||
* @param _callbackGasLimit is the gas limit for the request. | ||
* @param _requestConfirmations number of request confirmations to wait before serving a request. | ||
* @param _numWords is the number of words to request. | ||
*/ | ||
function requestRandomWordsInNative( | ||
uint32 _callbackGasLimit, | ||
uint16 _requestConfirmations, | ||
uint32 _numWords | ||
) external payable returns (uint256 requestId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.