-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 37dd3f8
Showing
26 changed files
with
1,985 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
c_chain_url="https://api.avax-test.network/ext/bc/C/rpc" | ||
c_chain_blockchain_id="7fc93d85c6d62c5b2ac0b519c87010ea5294012d1e407030d6acd0021cac10d5" | ||
c_chain_teleporter_registry_address="0xb35f163b70AbABeE69cDF40bCDA94df2c37d9df8" | ||
c_chain_vrf_coordinator_address="0x2eD832Ba664535e5886b75D64C46EB9a228C2610" | ||
c_chain_vrf_subscription_id="1" | ||
c_chain_vrf_key_hash="354d2f95da55398f44b7cff77da56283d9c6c829a4bdf1bbcaf2ad6a4d081f61" | ||
|
||
subnet_url="https://subnets.avax.network/dispatch/testnet/rpc" | ||
subnet_blockchain_id="9f3be606497285d0ffbb5ac9ba24aa60346a9b1812479ed66cb329f394a4b1c7" | ||
subnet_teleporter_registry_address="0xb35f163b70AbABeE69cDF40bCDA94df2c37d9df8" | ||
|
||
user_private_key="" |
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,14 @@ | ||
# Compiler files | ||
cache/ | ||
out/ | ||
|
||
# Ignores development broadcast logs | ||
!/broadcast | ||
/broadcast/*/31337/ | ||
/broadcast/**/dry-run/ | ||
|
||
# Docs | ||
docs/ | ||
|
||
# Dotenv file | ||
.env |
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,13 @@ | ||
[submodule "contracts/lib/forge-std"] | ||
path = contracts/lib/forge-std | ||
url = https://github.com/foundry-rs/forge-std | ||
[submodule "contracts/lib/openzeppelin-contracts"] | ||
path = contracts/lib/openzeppelin-contracts | ||
url = https://github.com/openzeppelin/openzeppelin-contracts | ||
branch = v4.8.1 | ||
[submodule "contracts/lib/chainlink"] | ||
path = contracts/lib/chainlink | ||
url = https://github.com/smartcontractkit/chainlink | ||
[submodule "contracts/lib/teleporter"] | ||
path = contracts/lib/teleporter | ||
url = https://github.com/ava-labs/teleporter |
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,66 @@ | ||
Copyright (C) 2024, Ava Labs, Inc. All rights reserved. | ||
|
||
Ecosystem License | ||
Version: 1.1 | ||
|
||
Subject to the terms herein, Ava Labs, Inc. (**“Ava Labs”**) hereby grants you | ||
a limited, royalty-free, worldwide, non-sublicensable, non-transferable, | ||
non-exclusive license to use, copy, modify, create derivative works based on, | ||
and redistribute the Software, in source code, binary, or any other form, | ||
including any modifications or derivative works of the Software (collectively, | ||
**“Licensed Software”**), in each case subject to this Ecosystem License | ||
(**“License”**). | ||
|
||
This License applies to all copies, modifications, derivative works, and any | ||
other form or usage of the Licensed Software. You will include and display | ||
this License, without modification, with all uses of the Licensed Software, | ||
regardless of form. | ||
|
||
You will use the Licensed Software solely (i) in connection with the Avalanche | ||
Public Blockchain platform, having a NetworkID of 1 (Mainnet) or 5 (Fuji), and | ||
associated blockchains, comprised exclusively of the Avalanche X-Chain, | ||
C-Chain, P-Chain and any subnets linked to the P-Chain (“Avalanche Authorized | ||
Platform”) or (ii) for non-production, testing or research purposes within the | ||
Avalanche ecosystem, in each case, without any commercial application | ||
(“Non-Commercial Use”); provided that this License does not permit use of the | ||
Licensed Software in connection with (a) any forks of the Avalanche Authorized | ||
Platform or (b) in any manner not operationally connected to the Avalanche | ||
Authorized Platform other than, for the avoidance of doubt, the limited | ||
exception for Non-Commercial Use. Ava Labs may publicly announce changes or | ||
additions to the Avalanche Authorized Platform, which may expand or modify | ||
usage of the Licensed Software. Upon such announcement, the Avalanche | ||
Authorized Platform will be deemed to be the then-current iteration of such | ||
platform. | ||
|
||
You hereby acknowledge and agree to the terms set forth at | ||
www.avalabs.org/important-notice. | ||
|
||
If you use the Licensed Software in violation of this License, this License | ||
will automatically terminate and Ava Labs reserves all rights to seek any | ||
remedy for such violation. | ||
|
||
Except for uses explicitly permitted in this License, Ava Labs retains all | ||
rights in the Licensed Software, including without limitation the ability to | ||
modify it. | ||
|
||
Except as required or explicitly permitted by this License, you will not use | ||
any Ava Labs names, logos, or trademarks without Ava Labs’ prior written | ||
consent. | ||
|
||
You may use this License for software other than the “Licensed Software” | ||
specified above, as long as the only change to this License is the definition | ||
of the term “Licensed Software.” | ||
|
||
The Licensed Software may reference third party components. You acknowledge | ||
and agree that these third party components may be governed by a separate | ||
license or terms and that you will comply with them. | ||
|
||
**TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE LICENSED SOFTWARE IS PROVIDED | ||
ON AN “AS IS” BASIS, AND AVA LABS EXPRESSLY DISCLAIMS AND EXCLUDES ALL | ||
REPRESENTATIONS, WARRANTIES AND OTHER TERMS AND CONDITIONS, WHETHER EXPRESS OR | ||
IMPLIED, INCLUDING WITHOUT LIMITATION BY OPERATION OF LAW OR BY CUSTOM, | ||
STATUTE OR OTHERWISE, AND INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTY, | ||
TERM, OR CONDITION OF NON-INFRINGEMENT, MERCHANTABILITY, TITLE, OR FITNESS FOR | ||
PARTICULAR PURPOSE. YOU USE THE LICENSED SOFTWARE AT YOUR OWN RISK. AVA LABS | ||
EXPRESSLY DISCLAIMS ALL LIABILITY (INCLUDING FOR ALL DIRECT, CONSEQUENTIAL OR | ||
OTHER DAMAGES OR LOSSES) RELATED TO ANY USE OF THE LICENSED SOFTWARE.** |
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,59 @@ | ||
# Subnet VRF Contracts | ||
|
||
This repository provides **example** contracts for how an Avalanche Subnet could leverage [Chainlink VRF](https://docs.chain.link/vrf) functionality (available on the C-chain) using [Teleporter](https://github.com/ava-labs/teleporter). This allows newly launched Subnets to immediately utilize VRF without any trusted intermediaries or third-party integration requirements. | ||
|
||
**The contracts in this repository are not audited and are not suitable for production use.** | ||
|
||
## Contracts | ||
|
||
### VRFProvider | ||
The `VRFProvider` contract is intended to be deployed on the same chain that Chainlink VRF is available on (i.e. the C-chain). It is configured to receive randomness requests from a specific `VRFProxy`, and passes those requests on to the Chainlink VRF coordinator. When the random values are provided by the Chainlink VRF coordinator, the `VRFProvider` in turn sends those values back to the `VRFProxy` that requested them via Teleporter. | ||
|
||
In order be able to successfully request random values from the configured Chainlink VRF coordinator, the `VRFProvider` must be added to a [VRF subscription as an allowed consumer](https://docs.chain.link/vrf/v2/subscription/ui). The specific subsciption ID to be used is set by each randomness request. | ||
|
||
### VRFProxy | ||
The `VRFProxy` contract is intended to be deployed on any Subnet chain that would like to leverage Chainlink VRF but does not have a direct VRF integration. It is configured to request values from a specific `VRFProvider` that is deployed on another chain via Teleporter. It provides the same `requestRandomWords` interface as Chainlink VRF coordinators, and returns random values to fulfill requests via the same `fulfillRandomWords` method used by Chainlink VRF consumers. | ||
|
||
In order to be able to request random values from a `VRFProxy`, accounts must be added as allowed consumers via `addConsumer`. | ||
|
||
### SimpleBettingGame | ||
A sample contract demostrating the use of VRF. Implements a simple betting game that leverages a `VRFProxy` to fulfill random values. | ||
|
||
## Dependencies | ||
In order to build and deploy the contracts using the scripts in this repository, [Foundry](https://book.getfoundry.sh/getting-started/installation) is required. | ||
|
||
## Building and Testing | ||
The contracts in this repository can be built and tested using the following scripts. | ||
```bash | ||
./scripts/build.sh | ||
./scripts/test.sh | ||
``` | ||
Included in the unit test script is a test coverage report. | ||
``` | ||
| File | % Lines | % Statements | % Branches | % Funcs | | ||
|---------------------------|-----------------|-----------------|-----------------|-----------------| | ||
| src/GasUtils.sol | 100.00% (7/7) | 100.00% (4/4) | 100.00% (3/3) | 100.00% (1/1) | | ||
| src/SimpleBettingGame.sol | 100.00% (38/38) | 100.00% (42/42) | 100.00% (22/22) | 100.00% (6/6) | | ||
| src/VRFProvider.sol | 100.00% (12/12) | 100.00% (15/15) | 100.00% (8/8) | 100.00% (2/2) | | ||
| src/VRFProxy.sol | 100.00% (25/25) | 100.00% (29/29) | 100.00% (14/14) | 100.00% (4/4) | | ||
| Total | 100.00% (82/82) | 100.00% (90/90) | 100.00% (47/47) | 100.00% (13/13) | | ||
``` | ||
|
||
## Deploying | ||
The example contracts can be deployed by setting proper environment variable values as follows. | ||
```bash | ||
cp .env.example .env | ||
``` | ||
The `user_private_key` value then must be set in the `.env` file. The full list of configurable environment variables includes: | ||
| Environment Variable | Description | | ||
|--------|--------| | ||
| c_chain_url | RPC endpoint for the C-chain (where Chainlink VRF is available) | | ||
| c_chain_blockchain_id | Blockchain ID of the C-chain (hexadecimal encoded) | | ||
| c_chain_teleporter_registry_address | Teleporter registry contract used by the `VRFProvider` on the C-chain | | ||
| c_chain_vrf_coordinator_address | Address of the Chainlink VRF Coordinator to be used by the `VRFProvider` | | ||
| c_chain_vrf_subscription_id | The Chainlink VRF subscription ID to be used by the `VRFProxy` | | ||
| c_chain_vrf_key_hash | The Chainlink VRF key hash to be used by the `VRFProxy` | | ||
| subnet_url | RPC endpoint for the Subnet chain to be used| | ||
| subnet_blockchain_id | Blockchain ID of the Subnet chain to be used (hexadecimal encoded) | | ||
| subnet_teleporter_registry_address | Teleporter registry contract used by the `VRFProvider` on the Subnet chain | | ||
| user_private_key | Private key for a funded account on both the C-chain and Subnet chain. Used to deploy contracts | |
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,6 @@ | ||
[profile.default] | ||
src = "src" | ||
out = "out" | ||
libs = ["lib"] | ||
|
||
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options |
Submodule openzeppelin-contracts
added at
045704
Submodule teleporter
added at
bedf79
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,4 @@ | ||
@chainlink/=lib/chainlink/ | ||
@openzeppelin/=lib/openzeppelin-contracts/ | ||
@teleporter/=lib/teleporter/ | ||
@subnet-evm-contracts/=lib/teleporter/contracts/lib/subnet-evm/contracts/contracts/ |
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,35 @@ | ||
{ | ||
"extends": "solhint:recommended", | ||
"rules": { | ||
"compiler-version": ["error", "0.8.18"], | ||
"no-unused-vars": "error", | ||
"func-visibility": [ | ||
"error", | ||
{ | ||
"ignoreConstructors": true | ||
} | ||
], | ||
"private-vars-leading-underscore": [ | ||
"warn", | ||
{ | ||
"strict": true | ||
} | ||
], | ||
"reason-string": [ | ||
"warn", | ||
{ | ||
"maxLength": 75 | ||
} | ||
], | ||
"custom-errors": "off", | ||
"ordering": "error", | ||
"immutable-vars-naming": [ | ||
"warn", | ||
{ | ||
"immutablesAsConstants": false | ||
} | ||
], | ||
"func-named-parameters": ["error", 5], | ||
"one-contract-per-file": "off" | ||
} | ||
} |
Empty file.
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,44 @@ | ||
// (c) 2024, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
// SPDX-License-Identifier: Ecosystem | ||
pragma solidity 0.8.18; | ||
|
||
library GasUtils { | ||
/** | ||
* @dev Amount of gas needed as a buffer for delivering random values to the requesters and handling the result. | ||
* The amount of gas used by the requester itself when receiving the values is specified per request by | ||
* callbackGasLimit. | ||
*/ | ||
uint256 public constant GAS_FOR_CALL_EXACT_CHECK = 5_000; | ||
|
||
/** | ||
* Implementation taken from VRFCoordinatorV2.sol. | ||
* @dev calls target address with exactly gasAmount gas and data as calldata | ||
* or reverts if at least gasAmount gas is not available. | ||
*/ | ||
function _callWithExactGas(uint256 gasAmount, address target, bytes memory data) internal returns (bool) { | ||
bool success; | ||
// solhint-disable-next-line | ||
assembly { | ||
let g := gas() | ||
// Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow | ||
// The gas actually passed to the callee is min(gasAmount, 63//64*gas available). | ||
// We want to ensure that we revert if gasAmount > 63//64*gas available | ||
// as we do not want to provide them with less, however that check itself costs | ||
// gas. GAS_FOR_CALL_EXACT_CHECK ensures we have at least enough gas to be able | ||
// to revert if gasAmount > 63//64*gas available. | ||
if lt(g, GAS_FOR_CALL_EXACT_CHECK) { revert(0, 0) } | ||
g := sub(g, GAS_FOR_CALL_EXACT_CHECK) | ||
// if g - g//64 <= gasAmount, revert | ||
// (we subtract g//64 because of EIP-150) | ||
if iszero(gt(sub(g, div(g, 64)), gasAmount)) { revert(0, 0) } | ||
// solidity calls check that a contract actually exists at the destination, so we do the same | ||
if iszero(extcodesize(target)) { revert(0, 0) } | ||
// call and return whether we succeeded. ignore return data | ||
// call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) | ||
success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0) | ||
} | ||
return success; | ||
} | ||
} |
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,80 @@ | ||
// (c) 2024, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
// SPDX-License-Identifier: Ecosystem | ||
pragma solidity 0.8.18; | ||
|
||
/** | ||
* THIS IS AN EXAMPLE CONTRACT INTERFACE THAT USES UNAUDITED CODE. | ||
* DO NOT USE THIS CODE IN PRODUCTION. | ||
*/ | ||
|
||
/** | ||
* @notice Represents all of the relevant information for a given | ||
* VRF request message to the VRF partner on a partner chain. This | ||
* struct is ABI encoded/decoded in the Teleporter message passing. | ||
*/ | ||
struct VRFRequestInfo { | ||
uint256 requestID; | ||
bytes32 keyHash; | ||
uint64 subID; | ||
uint16 minimumRequestConfirmations; | ||
uint32 callbackGasLimit; | ||
uint32 numWords; | ||
} | ||
|
||
/** | ||
* @notice Represents all of the relevant information for a given VRF | ||
* response message received back from the VRF provided on a partner chain. | ||
* This struct is ABI encoded/decoded in the Teleporter message passing. | ||
*/ | ||
struct VRFResponseInfo { | ||
uint256 requestID; | ||
uint256[] randomWords; | ||
uint32 callbackGasLimit; | ||
} | ||
|
||
/** | ||
* @dev IVRFProxy defines the interface for a contract deployed on a subnet that is meant to act as a proxy to a | ||
* VRFCoordinator deployed on another chain. Approved dApps deployed on the same chain as the VRFProxy can request values | ||
* from it in the same way that dApps could request random values from a VRFCoordinator contract. | ||
*/ | ||
interface IVRFProxy { | ||
/** | ||
* @notice Adds the provided consumer to be allowed to request random values | ||
* via this contract. Allowed consumers can use any VRF subscriptions that | ||
* the corresponding VRFProvider contract instance has access to on the VRF | ||
* provider chain. | ||
* @param consumer the address that should be allowed to call requestRandomWords | ||
*/ | ||
function addConsumer(address consumer) external; | ||
|
||
/** | ||
* @notice Removes the provided consumer such that it is no longer allowed to | ||
* request random values via this contract. | ||
* @param consumer the address that should no longer be allowed to call requestRandomWords | ||
*/ | ||
function removeConsumer(address consumer) external; | ||
|
||
/** | ||
* @notice Request a set of random words. | ||
* The request is passed on to the partner chain where the VRFProvider is deployed via Teleporter message. | ||
* See https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol#L13 | ||
* for further documentation of how each value is used within Chainlink VRF reuests. | ||
* @param keyHash - Corresponds to the VRF keyHash to be used on the partner chain that provides the VRF functionality. | ||
* @param subId - The ID of the VRF subscription to be used by the VRF provider on the partner chain. | ||
* @param minimumRequestConfirmations - How many blocks you'd like the VRF service on the partner chain to wait prior | ||
* to fulfilling the request once the VRF provider submits the request on the partner chain. | ||
* @param callbackGasLimit - How much gas needs to be provided to the fulfillRandomWords call to complete this randomness request. | ||
* @param numWords - The number of uint256 values requested. | ||
* @return requestID - A unique identifier of the request. Can be used to match a request to a reponse in fulfillRandomWords. This | ||
* request ID is separate from any VRF request ID assigned on the partner chain by the VRFProdiver. | ||
*/ | ||
function requestRandomWords( | ||
bytes32 keyHash, | ||
uint64 subId, | ||
uint16 minimumRequestConfirmations, | ||
uint32 callbackGasLimit, | ||
uint32 numWords | ||
) external returns (uint256 requestID); | ||
} |
Oops, something went wrong.