Skip to content
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

chore: add DataEdge contracts #963

Merged
merged 4 commits into from
Mar 25, 2024
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
26 changes: 26 additions & 0 deletions .github/workflows/ci-data-edge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: CI - packages/data-edge

env:
CI: true

on:
push:
branches: "*"
paths:
- packages/data-edge/**
pull_request:
branches: "*"
paths:
- packages/data-edge/**
workflow_dispatch:

jobs:
test-ci:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up environment
uses: ./.github/actions/setup
- name: Run tests
run: yarn test
8 changes: 7 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@
. "$(dirname -- "$0")/_/husky.sh"

# contracts
cd packages/contracts
pushd packages/contracts
npx --no-install lint-staged
popd

# data-edge
pushd packages/data-edge
npx --no-install lint-staged
popd
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"packageManager": "[email protected]",
"workspaces": [
"packages/contracts",
"packages/data-edge",
"packages/eslint-graph-config",
"packages/sdk",
"packages/solhint-graph-config",
Expand Down
4 changes: 4 additions & 0 deletions packages/data-edge/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
MNEMONIC=
INFURA_KEY=
ETHERSCAN_API_KEY=
ARBISCAN_API_KEY=
Empty file.
10 changes: 10 additions & 0 deletions packages/data-edge/.solcover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const skipFiles = ['']

module.exports = {
providerOptions: {
mnemonic: 'myth like bonus scare over problem client lizard pioneer submit female collect',
network_id: 1337,
},
skipFiles,
istanbulFolder: './reports/coverage',
}
342 changes: 342 additions & 0 deletions packages/data-edge/LICENSE

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions packages/data-edge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Data Edge

A DataEdge contract is used to store arbitrary data on-chain on any EVM compatible blockchain. A subgraph can then read all the calldata sent to a particular contract, decode it and update the subgraph state accordingly.

The DataEdge accepts any function call by using a fallback function that will not revert. It is up to the implementor to define the calldata format as well as how to decode it.

### Additional Considerations

- Fallback is not payable to avoid anyone sending ETH by mistake as the main purpose is to store calldata.

# Deploying

Setup a `.env` file with the keys you want to use for deployments. You can use `.env.sample` as a guide.
Deploy a `DataEdge` contract by running `yarn deploy -- --network <network-name>`

# Copyright

Copyright &copy; 2022 The Graph Foundation

Licensed under [GPL license](LICENSE).
10 changes: 10 additions & 0 deletions packages/data-edge/addresses.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"421614": {
"DataEdge": "0x17f1fcD16E2A9fF2a55c63C97a778D96Fa473548",
"EventfulDataEdge": "0x9b9402939133F27c6eba81a321dfBFa1feE6714E"
},
"11155111": {
"DataEdge": "0x00C602A72363917Bc30a793593731F93352eB85d",
"EventfulDataEdge": "0xEFC8D47673777b899f2FB597C6FC0E87ecce98Cb"
}
}
13 changes: 13 additions & 0 deletions packages/data-edge/contracts/DataEdge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.12;

/// @title Data Edge contract is only used to store on-chain data, it does not
/// perform execution. On-chain client services can read the data
/// and decode the payload for different purposes.
contract DataEdge {
/// @dev Fallback function, accepts any payload
fallback() external payable {
// no-op
}
}
16 changes: 16 additions & 0 deletions packages/data-edge/contracts/EventfulDataEdge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.12;

/// @title Data Edge contract is only used to store on-chain data, it does not
/// perform execution. On-chain client services can read the data
/// and decode the payload for different purposes.
/// NOTE: This version emits an event with the calldata.
contract EventfulDataEdge {
event Log(bytes data);

/// @dev Fallback function, accepts any payload
fallback() external payable {
emit Log(msg.data);
}
}
17 changes: 17 additions & 0 deletions packages/data-edge/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const config = require('eslint-graph-config')

module.exports = [
...config.default,
{
rules: {
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
},
},
{
ignores: ['**/reports/*'],
},
]
182 changes: 182 additions & 0 deletions packages/data-edge/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import * as dotenv from 'dotenv'
dotenv.config()

import { HardhatUserConfig } from 'hardhat/types'
import { task } from 'hardhat/config'

// Plugins

import '@nomiclabs/hardhat-ethers'
import '@nomiclabs/hardhat-etherscan'
import '@nomiclabs/hardhat-waffle'
import 'hardhat-abi-exporter'
import 'hardhat-gas-reporter'
import 'hardhat-contract-sizer'
import '@tenderly/hardhat-tenderly'
import '@openzeppelin/hardhat-upgrades'
import '@typechain/hardhat'

// Tasks

import './tasks/craft-calldata'
import './tasks/post-calldata'

// Networks

interface NetworkConfig {
network: string
chainId: number
gas?: number | 'auto'
gasPrice?: number | 'auto'
url?: string
}

const networkConfigs: NetworkConfig[] = [
{ network: 'mainnet', chainId: 1 },
{ network: 'ropsten', chainId: 3 },
{ network: 'rinkeby', chainId: 4 },
{ network: 'kovan', chainId: 42 },
{ network: 'sepolia', chainId: 11155111 },
{
network: 'arbitrum-one',
chainId: 42161,
url: 'https://arb1.arbitrum.io/rpc',
},
{
network: 'arbitrum-goerli',
chainId: 421613,
url: 'https://goerli-rollup.arbitrum.io/rpc',
},
{
network: 'arbitrum-sepolia',
chainId: 421614,
url: 'https://sepolia-rollup.arbitrum.io/rpcblock',
},
]

function getAccountMnemonic() {
return process.env.MNEMONIC || ''
}

function getDefaultProviderURL(network: string) {
return `https://${network}.infura.io/v3/${process.env.INFURA_KEY}`
}

function setupDefaultNetworkProviders(buidlerConfig) {
for (const netConfig of networkConfigs) {
buidlerConfig.networks[netConfig.network] = {
chainId: netConfig.chainId,
url: netConfig.url ? netConfig.url : getDefaultProviderURL(netConfig.network),
gas: netConfig.gasPrice || 'auto',
gasPrice: netConfig.gasPrice || 'auto',
accounts: {
mnemonic: getAccountMnemonic(),
},
}
}
}

// Tasks

task('accounts', 'Prints the list of accounts', async (_, bre) => {
const accounts = await bre.ethers.getSigners()
for (const account of accounts) {
console.log(await account.getAddress())
}
})

// Config
const config: HardhatUserConfig = {
paths: {
sources: './contracts',
tests: './test',
artifacts: './build/contracts',
},
solidity: {
compilers: [
{
version: '0.8.12',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
outputSelection: {
'*': {
'*': ['storageLayout'],
},
},
},
},
],
},
defaultNetwork: 'hardhat',
networks: {
hardhat: {
chainId: 1337,
loggingEnabled: false,
gas: 1200000,
gasPrice: 'auto',
blockGasLimit: 12000000,
accounts: {
mnemonic: 'myth like bonus scare over problem client lizard pioneer submit female collect',
},
mining: {
auto: true,
interval: 0,
},
},
ganache: {
chainId: 1337,
url: 'http://localhost:8545',
},
},
etherscan: {
apiKey: {
mainnet: process.env.ETHERSCAN_API_KEY,
goerli: process.env.ETHERSCAN_API_KEY,
sepolia: process.env.ETHERSCAN_API_KEY,
arbitrumOne: process.env.ARBISCAN_API_KEY,
arbitrumGoerli: process.env.ARBISCAN_API_KEY,
arbitrumSepolia: process.env.ARBISCAN_API_KEY,
},
customChains: [
{
network: 'arbitrumSepolia',
chainId: 421614,
urls: {
apiURL: 'https://api-sepolia.arbiscan.io/api',
browserURL: 'https://sepolia.arbiscan.io',
},
},
],
},
gasReporter: {
enabled: process.env.REPORT_GAS ? true : false,
showTimeSpent: true,
currency: 'USD',
outputFile: 'reports/gas-report.log',
},
typechain: {
outDir: 'build/types',
target: 'ethers-v5',
},
abiExporter: {
path: './build/abis',
clear: false,
flat: true,
},
tenderly: {
project: process.env.TENDERLY_PROJECT,
username: process.env.TENDERLY_USERNAME,
},
contractSizer: {
alphaSort: true,
runOnCompile: false,
disambiguatePaths: true,
},
}

setupDefaultNetworkProviders(config)

export default config
Loading