-
Notifications
You must be signed in to change notification settings - Fork 0
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 c4ccec5
Showing
695 changed files
with
136,276 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,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,12 @@ | ||
[submodule "lib/forge-std"] | ||
path = lib/forge-std | ||
url = https://github.com/foundry-rs/forge-std | ||
[submodule "lib/v2-core"] | ||
path = lib/v2-core | ||
url = https://github.com/Uniswap/v2-core | ||
[submodule "lib/v2-periphery"] | ||
path = lib/v2-periphery | ||
url = https://github.com/Uniswap/v2-periphery | ||
[submodule "lib/openzeppelin-contracts"] | ||
path = lib/openzeppelin-contracts | ||
url = https://github.com/OpenZeppelin/openzeppelin-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,65 @@ | ||
# System Smart Contracts for Reactive Network | ||
|
||
## Development & Deployment Instructions | ||
|
||
### Environment Setup | ||
|
||
To set up `foundry` environment, run: | ||
|
||
``` | ||
curl -L https://foundry.paradigm.xyz | bash | ||
source ~/.bashrc | ||
foundryup | ||
``` | ||
|
||
Install dependencies: | ||
|
||
``` | ||
forge install | ||
``` | ||
|
||
### Development & Testing | ||
|
||
To compile artifacts: | ||
|
||
``` | ||
forge compile | ||
``` | ||
|
||
### Additional Documentation & Demos | ||
|
||
Refer to `TECH.md` for additional information on implementing reactive contracts and callbacks. | ||
|
||
The `src/demos` directory contains several elaborate demos, accompanied by `README.md` files for each one. | ||
|
||
### Environment variable configuration for running demos | ||
|
||
The following environment variables are used in the instructions for running the demos, and should be configured beforehand. | ||
|
||
#### `SEPOLIA_RPC` | ||
|
||
The Sepolia Testnet RPC address; `https://rpc2.sepolia.org` unless you want to use your own. | ||
|
||
#### `SEPOLIA_PRIVATE_KEY` | ||
|
||
The private key to your Sepolia wallet. | ||
|
||
#### `REACTIVE_RPC` | ||
|
||
For the Reactive Testnet RPC address, refer to the [docs](https://dev.reactive.network/kopli-testnet#kopli-testnet-information). | ||
|
||
#### `REACTIVE_PRIVATE_KEY` | ||
|
||
The private key to your Reactive wallet. | ||
|
||
#### `DEPLOYER_ADDR` | ||
|
||
The address of your Reactive wallet. | ||
|
||
#### `SYSTEM_CONTRACT_ADDR` | ||
|
||
For the system contract address on the Reactive testnet, refer to the [docs](https://dev.reactive.network/kopli-testnet#kopli-testnet-information). | ||
|
||
#### `CALLBACK_PROXY_ADDR` | ||
|
||
For the callback sender address, refer to the [docs](https://dev.reactive.network/kopli-testnet#kopli-testnet-information). |
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,113 @@ | ||
# Basics Of Reactive Smart Contracts | ||
|
||
Reactive smart contracts run on a standard EVM and can be written in any EVM-compatible language, although the Application Binary Interfaces (ABIs) are particularly customized for Solidity. Their unique capabilities stem from reactive nodes and a specialized pre-deployed system contract. | ||
|
||
## Special Considerations | ||
|
||
Reactive contracts are deployed simultaneously to the main reactive network and the private ReactVM subnet. The copy deployed to the main network is accessible by Externally Owned Accounts (EOAs) and can interact with the system contract to manage subscriptions. The copy deployed to ReactVM processes incoming events from origin chain contracts but can't be interacted with by the EOA's copy. | ||
|
||
The two contract copies of the contract **DO NOT** share state and can't interact directly. Since both copies use the same bytecode, it's recommended to identify the deployment target in the constructor and guard your methods accordingly. You can determine whether the contract is being deployed to ReactVM by interacting with the system contract. Since it is not present in ReactVMs, your calls will revert. Refer to the reactive demos for examples. | ||
|
||
Reactive contracts running in the ReactVM subnet have limited capabilities for interaction with anything outside their VM. They can only: | ||
|
||
* Passively receive log records passed to them by the reactive network. | ||
* Initiate calls to destination chain contracts. | ||
|
||
## Subscription Basics | ||
|
||
Reactive contract's static subscriptions are configured by calling the `subscribe()` method of the Reactive Network's system contract upon deployment. This must happen in the `constructor()`, and the reactive contract must adeptly handle reverts. The latter requirement arises because reactive contracts are deployed both to the Reactive Network and to their deployer's private ReactVM, where the system contract is not present. The following code will accomplish this: | ||
|
||
```solidity | ||
bool private vm; | ||
constructor() { | ||
SubscriptionService service = SubscriptionService(service_address); | ||
bytes memory payload = abi.encodeWithSignature( | ||
"subscribe(uint256,address,uint256,uint256,uint256,uint256)", | ||
CHAIN_ID, | ||
CONTRACT_ADDRESS, | ||
TOPIC_0, | ||
REACTIVE_IGNORE, | ||
REACTIVE_IGNORE, | ||
REACTIVE_IGNORE | ||
); | ||
(bool subscription_result,) = address(service).call(payload); | ||
if (!subscription_result) { | ||
vm = true; | ||
} | ||
} | ||
``` | ||
|
||
Reactive contracts can change their subscriptions dynamically by using callbacks to Reactive Network instances (as opposed to ReactVM) of themselves, which can, in turn, call the system contract to effect the appropriate changes to subscriptions. | ||
|
||
The subscription system allows the Reactive Network (the event provider) to associate any number of `uint256` fields with a given event. Subscribers can then request events that match any subset of these fields exactly. During the testnet stage, the Reactive Network provides the originating contract's chain ID, address, and all four topics as filtering criteria. These criteria may be expanded or changed in the future. | ||
|
||
`REACTIVE_IGNORE` is a random value (`0xa65f96fc951c35ead38878e0f0b7a3c744a6f5ccc1476b313353ce31712313ad`) set aside to indicate that you're not interested in the given topic. `0` is used for the same purpose where chain ID and contract address are concerned. | ||
|
||
To explain the capabilities by example, **YOU CAN**: | ||
|
||
* Subscribe to all log records emitted by a specific contract, e.g., to subscribe to all events from `0x7E0987E5b3a30e3f2828572Bb659A548460a3003`, call `subscribe(CHAIN_ID, 0x7E0987E5b3a30e3f2828572Bb659A548460a3003, REACTIVE_IGNORE, REACTIVE_IGNORE, REACTIVE_IGNORE, REACTIVE_IGNORE)` in the constructor. | ||
|
||
* Subscribe to all log records with a specific topic 0, e.g., to subscribe to all Uniswap V2 `Sync` events, call `subscribe(CHAIN_ID, 0, 0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1, REACTIVE_INGORE, REACTIVE_INGORE, REACTIVE_INGORE)` in the constructor. | ||
|
||
* Subscribe to log records emitted by a specific contract with a specific topic 0. | ||
|
||
* Specify multiple independent subscriptions by calling the `subscribe()` method multiple times in the constructor. Your reactive contract will receive events matching any of its subscriptions. | ||
|
||
On the other hand, **YOU CAN'T**: | ||
|
||
* Match event parameters using less than, greater than, range, or bitwise operations. Only strict equality is supported. | ||
|
||
* Use disjunction or sets of criteria in a single subscription. You can, however, call the `subscribe()` method multiple times to achieve similar results, but this approach is somewhat vulnerable to combinatorial explosion. | ||
|
||
## Processing Events | ||
|
||
To process incoming events, a reactive smart contract must implement the `IReactive` interface. This involves implementing a single method with the following signature: | ||
|
||
```solidity | ||
function react( | ||
uint256 chain_id, | ||
address _contract, | ||
uint256 topic_0, | ||
uint256 topic_1, | ||
uint256 topic_2, | ||
uint256 topic_3, | ||
bytes calldata data, | ||
uint256 block_number, | ||
uint256 op_code | ||
) external; | ||
``` | ||
|
||
The Reactive Network will feed events matching the reactive contract's subscriptions by initiating calls to this method. | ||
|
||
Reactive smart contracts can use all the EVM capabilities normally. The only limitation is that reactive contracts are executed in the context of a private ReactVM associated with a specific deployer address, so they can't interact with contracts deployed by anyone else. | ||
|
||
## Calls to Destination Chain Contracts | ||
|
||
The key capability of reactive smart contracts is the ability to create new transactions in L1 networks. This is achieved by emitting log records of a predetermined format: | ||
|
||
```solidity | ||
event Callback( | ||
uint256 indexed chain_id, | ||
address indexed _contract, | ||
uint64 indexed gas_limit, | ||
bytes payload | ||
); | ||
``` | ||
|
||
Upon observing such a record in the traces, the Reactive Network will submit a new transaction with the desired payload to the L1 network indicated by the chain ID (as long as it's on the supported list). Note that for authorization purposes, the first 160 bits of the call arguments will be replaced with the calling reactive contract's RVM ID, which is equal to the reactive contract's deployer address. | ||
|
||
For example, the Uniswap Stop Order Demo uses this capability to initiate token sales through its destination chain contract: | ||
|
||
```solidity | ||
bytes memory payload = abi.encodeWithSignature( | ||
"stop(address,address,address,bool,uint256,uint256)", | ||
0, | ||
pair, | ||
client, | ||
token0, | ||
coefficient, | ||
threshold | ||
); | ||
emit Callback(chain_id, stop_order, CALLBACK_GAS_LIMIT, payload); | ||
``` |
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 |
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 @@ | ||
src/Vm.sol linguist-generated |
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,134 @@ | ||
name: CI | ||
|
||
on: | ||
workflow_dispatch: | ||
pull_request: | ||
push: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Install Foundry | ||
uses: onbjerg/foundry-toolchain@v1 | ||
with: | ||
version: nightly | ||
|
||
- name: Print forge version | ||
run: forge --version | ||
|
||
# Backwards compatibility checks: | ||
# - the oldest and newest version of each supported minor version | ||
# - versions with specific issues | ||
- name: Check compatibility with latest | ||
if: always() | ||
run: | | ||
output=$(forge build --skip test) | ||
if echo "$output" | grep -q "Warning"; then | ||
echo "$output" | ||
exit 1 | ||
fi | ||
- name: Check compatibility with 0.8.0 | ||
if: always() | ||
run: | | ||
output=$(forge build --skip test --use solc:0.8.0) | ||
if echo "$output" | grep -q "Warning"; then | ||
echo "$output" | ||
exit 1 | ||
fi | ||
- name: Check compatibility with 0.7.6 | ||
if: always() | ||
run: | | ||
output=$(forge build --skip test --use solc:0.7.6) | ||
if echo "$output" | grep -q "Warning"; then | ||
echo "$output" | ||
exit 1 | ||
fi | ||
- name: Check compatibility with 0.7.0 | ||
if: always() | ||
run: | | ||
output=$(forge build --skip test --use solc:0.7.0) | ||
if echo "$output" | grep -q "Warning"; then | ||
echo "$output" | ||
exit 1 | ||
fi | ||
- name: Check compatibility with 0.6.12 | ||
if: always() | ||
run: | | ||
output=$(forge build --skip test --use solc:0.6.12) | ||
if echo "$output" | grep -q "Warning"; then | ||
echo "$output" | ||
exit 1 | ||
fi | ||
- name: Check compatibility with 0.6.2 | ||
if: always() | ||
run: | | ||
output=$(forge build --skip test --use solc:0.6.2) | ||
if echo "$output" | grep -q "Warning"; then | ||
echo "$output" | ||
exit 1 | ||
fi | ||
# via-ir compilation time checks. | ||
- name: Measure compilation time of Test with 0.8.17 --via-ir | ||
if: always() | ||
run: forge build --skip test --contracts test/compilation/CompilationTest.sol --use solc:0.8.17 --via-ir | ||
|
||
- name: Measure compilation time of TestBase with 0.8.17 --via-ir | ||
if: always() | ||
run: forge build --skip test --contracts test/compilation/CompilationTestBase.sol --use solc:0.8.17 --via-ir | ||
|
||
- name: Measure compilation time of Script with 0.8.17 --via-ir | ||
if: always() | ||
run: forge build --skip test --contracts test/compilation/CompilationScript.sol --use solc:0.8.17 --via-ir | ||
|
||
- name: Measure compilation time of ScriptBase with 0.8.17 --via-ir | ||
if: always() | ||
run: forge build --skip test --contracts test/compilation/CompilationScriptBase.sol --use solc:0.8.17 --via-ir | ||
|
||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Install Foundry | ||
uses: onbjerg/foundry-toolchain@v1 | ||
with: | ||
version: nightly | ||
|
||
- name: Print forge version | ||
run: forge --version | ||
|
||
- name: Run tests | ||
run: forge test -vvv | ||
|
||
fmt: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Install Foundry | ||
uses: onbjerg/foundry-toolchain@v1 | ||
with: | ||
version: nightly | ||
|
||
- name: Print forge version | ||
run: forge --version | ||
|
||
- name: Check formatting | ||
run: forge fmt --check |
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,29 @@ | ||
name: Sync Release Branch | ||
|
||
on: | ||
release: | ||
types: | ||
- created | ||
|
||
jobs: | ||
sync-release-branch: | ||
runs-on: ubuntu-latest | ||
if: startsWith(github.event.release.tag_name, 'v1') | ||
steps: | ||
- name: Check out the repo | ||
uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 | ||
ref: v1 | ||
|
||
- name: Configure Git | ||
run: | | ||
git config user.name github-actions[bot] | ||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com | ||
- name: Sync Release Branch | ||
run: | | ||
git fetch --tags | ||
git checkout v1 | ||
git reset --hard ${GITHUB_REF} | ||
git push --force |
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 @@ | ||
cache/ | ||
out/ | ||
.vscode | ||
.idea |
Oops, something went wrong.