Skip to content

Commit

Permalink
chore: add DataEdge contracts
Browse files Browse the repository at this point in the history
Maikol committed Mar 19, 2024
1 parent 59154f7 commit 67fd967
Showing 33 changed files with 13,105 additions and 0 deletions.
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=
5 changes: 5 additions & 0 deletions packages/data-edge/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
build/
cache/
dist/
node_modules/
reports/
15 changes: 15 additions & 0 deletions packages/data-edge/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"extends": ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
"rules": {
"prefer-const": "warn",
"no-extra-semi": "off",
"@typescript-eslint/no-extra-semi": "warn",
"@typescript-eslint/no-inferrable-types": "warn",
"@typescript-eslint/no-empty-function": "warn"
}
}
1 change: 1 addition & 0 deletions packages/data-edge/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sol linguist-language=Solidity
4 changes: 4 additions & 0 deletions packages/data-edge/.husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
cd packages/contracts

npx --no-install commitlint --edit ""
4 changes: 4 additions & 0 deletions packages/data-edge/.husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
cd packages/contracts

yarn lint
Empty file.
35 changes: 35 additions & 0 deletions packages/data-edge/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"printWidth": 120,
"useTabs": false,
"bracketSpacing": true,
"overrides": [
{
"files": "*.js",
"options": {
"semi": false,
"trailingComma": "all",
"tabWidth": 2,
"singleQuote": true,
"explicitTypes": "always"
}
},
{
"files": "*.ts",
"options": {
"semi": false,
"trailingComma": "all",
"tabWidth": 2,
"singleQuote": true,
"explicitTypes": "always"
}
},
{
"files": "*.sol",
"options": {
"tabWidth": 4,
"singleQuote": false,
"explicitTypes": "always"
}
}
]
}
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',
}
15 changes: 15 additions & 0 deletions packages/data-edge/.solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "solhint:recommended",
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"func-visibility": ["warn", { "ignoreConstructors": true }],
"compiler-version": ["off"],
"constructor-syntax": "warn",
"quotes": ["error", "double"],
"reason-string": ["off"],
"not-rely-on-time": "off",
"no-empty-blocks": "off"
}
}

1 change: 1 addition & 0 deletions packages/data-edge/.solhintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
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"
}
}
1 change: 1 addition & 0 deletions packages/data-edge/commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = { extends: ['@commitlint/config-conventional'] }
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);
}
}
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 (taskArgs, 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
97 changes: 97 additions & 0 deletions packages/data-edge/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"name": "@graphprotocol/graph-data-edge",
"version": "0.2.0",
"description": "The Graph Data Edge",
"main": "index.js",
"scripts": {
"prepare": "cd ../.. && husky install packages/contracts/.husky",
"prepublishOnly": "scripts/prepublish",
"build": "scripts/build",
"clean": "rm -rf build/ cache/ dist/",
"compile": "hardhat compile",
"test": "scripts/test",
"test:gas": "RUN_EVM=true REPORT_GAS=true scripts/test",
"test:coverage": "scripts/coverage",
"lint": "yarn lint:ts && yarn lint:sol",
"lint:fix": "yarn lint:ts:fix && yarn lint:sol:fix",
"lint:ts": "eslint '*/**/*.{js,ts}'",
"lint:ts:fix": "yarn prettier:ts && eslint '*/**/*.{js,ts}' --fix",
"lint:sol": "solhint './contracts/**/*.sol'",
"lint:sol:fix": "yarn prettier:sol && solhint --fix './contracts/**/*.sol'",
"prettier": "yarn prettier:ts && yarn prettier:sol",
"prettier:ts": "prettier --write 'test/**/*.ts'",
"prettier:sol": "prettier --write 'contracts/**/*.sol'",
"security": "scripts/security",
"flatten": "scripts/flatten",
"typechain": "hardhat typechain",
"verify": "hardhat verify",
"size": "hardhat size-contracts",
"deploy": "hardhat run scripts/deploy.ts"
},
"files": [
"dist/**/*",
"README.md",
"LICENSE"
],
"lint-staged": {
"contracts/*.sol": [
"prettier --write"
],
"test/**/*.ts": [
"prettier --write"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"pre-push": "git diff HEAD --quiet && yarn lint && yarn test"
}
},
"author": "The Graph Team",
"license": "GPL-2.0-or-later",
"devDependencies": {
"@commitlint/cli": "^16.2.1",
"@commitlint/config-conventional": "^16.2.1",
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-etherscan": "^3.1.2",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@openzeppelin/contracts": "^4.5.0",
"@openzeppelin/hardhat-upgrades": "^1.8.2",
"@tenderly/hardhat-tenderly": "^1.0.12",
"@typechain/ethers-v5": "^9.0.0",
"@typechain/hardhat": "^4.0.0",
"@types/mocha": "^9.0.0",
"@types/node": "^17.0.0",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"chai": "^4.2.0",
"dotenv": "^16.0.0",
"eslint": "^8.0.0",
"eslint-config-prettier": "^8.0.0",
"eslint-config-standard": "^16.0.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-mocha-no-only": "^1.1.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-standard": "^5.0.0",
"ethereum-waffle": "^3.0.2",
"ethers": "^5.1.3",
"ethlint": "^1.2.5",
"hardhat": "^2.6.1",
"hardhat-abi-exporter": "^2.2.0",
"hardhat-contract-sizer": "^2.0.3",
"hardhat-gas-reporter": "^1.0.4",
"husky": "^7.0.4",
"lint-staged": "^12.3.5",
"prettier": "^2.1.1",
"prettier-plugin-solidity": "^1.0.0-alpha.56",
"solhint": "^3.3.7",
"solhint-plugin-prettier": "^0.0.5",
"solidity-coverage": "^0.7.10",
"truffle-flattener": "^1.4.4",
"ts-node": "^10.5.0",
"typechain": "^7.0.0",
"typescript": "^4.0.2"
}
}
6 changes: 6 additions & 0 deletions packages/data-edge/scripts/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

set -eo pipefail

# Build
yarn compile
6 changes: 6 additions & 0 deletions packages/data-edge/scripts/coverage
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

set -eo pipefail

yarn compile
npx hardhat coverage $@
39 changes: 39 additions & 0 deletions packages/data-edge/scripts/deploy-local.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import '@nomiclabs/hardhat-ethers'
import { ethers, network } from 'hardhat'

import addresses from '../addresses.json'

import { promises as fs } from 'fs'

async function main() {
const factory = await ethers.getContractFactory('EventfulDataEdge')

// If we had constructor arguments, they would be passed into deploy()
console.log(`Deploying contract...`)
const contract = await factory.deploy()
const tx = contract.deployTransaction

// The address the Contract WILL have once mined
console.log(`> deployer: ${await contract.signer.getAddress()}`)
console.log(`> contract: ${contract.address}`)
console.log(`> tx: ${tx.hash} nonce:${tx.nonce} limit: ${tx.gasLimit} gas: ${tx.gasPrice.toNumber() / 1e9} (gwei)`)

// The contract is NOT deployed yet; we must wait until it is mined
await contract.deployed()
console.log(`Done!`)

// Update addresses.json
const chainId = (network.config.chainId as number).toString()
if (!addresses[chainId]) {
addresses[chainId] = {}
}
addresses[chainId]['EventfulDataEdge'] = contract.address
return fs.writeFile('addresses.json', JSON.stringify(addresses, null, 2))
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exit(1)
})
39 changes: 39 additions & 0 deletions packages/data-edge/scripts/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import '@nomiclabs/hardhat-ethers'
import { ethers, network } from 'hardhat'

import addresses from '../addresses.json'

import { promises as fs } from 'fs'

async function main() {
const factory = await ethers.getContractFactory('DataEdge')

// If we had constructor arguments, they would be passed into deploy()
console.log(`Deploying contract...`)
const contract = await factory.deploy()
const tx = contract.deployTransaction

// The address the Contract WILL have once mined
console.log(`> deployer: ${await contract.signer.getAddress()}`)
console.log(`> contract: ${contract.address}`)
console.log(`> tx: ${tx.hash} nonce:${tx.nonce} limit: ${tx.gasLimit} gas: ${tx.gasPrice.toNumber() / 1e9} (gwei)`)

// The contract is NOT deployed yet; we must wait until it is mined
await contract.deployed()
console.log(`Done!`)

// Update addresses.json
const chainId = (network.config.chainId as number).toString()
if (!addresses[chainId]) {
addresses[chainId] = {}
}
addresses[chainId]['DataEdge'] = contract.address
return fs.writeFile('addresses.json', JSON.stringify(addresses, null, 2))
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exit(1)
})
21 changes: 21 additions & 0 deletions packages/data-edge/scripts/flatten
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

OUT_DIR="build/flatten"

mkdir -p ${OUT_DIR}

echo "Flattening contracts..."

FILES=(
"contracts/Counter.sol"
)

for path in ${FILES[@]}; do
IFS='/'
parts=( $path )
name=${parts[${#parts[@]}-1]}
echo "Flatten > ${name}"
hardhat flatten "${path}" > "${OUT_DIR}/${name}"
done

echo "Done!"
23 changes: 23 additions & 0 deletions packages/data-edge/scripts/prepublish
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

TYPECHAIN_DIR=dist/types

set -eo pipefail

# Build contracts
yarn clean
yarn build

# Refresh distribution folder
rm -rf dist && mkdir -p dist/types/_src
cp -R build/abis/ dist/abis
cp -R build/types/ dist/types/_src

### Build Typechain bindings

# Build and create TS declarations
tsc -d ${TYPECHAIN_DIR}/_src/*.ts --outdir ${TYPECHAIN_DIR}
# Copy back sources
cp ${TYPECHAIN_DIR}/_src/*.ts ${TYPECHAIN_DIR}
# Delete temporary src dir
rm -rf ${TYPECHAIN_DIR}/_src
17 changes: 17 additions & 0 deletions packages/data-edge/scripts/security
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

## Before running:
# This tool requires to have solc installed.
# Ensure that you have the binaries installed by pip3 in your path.
# Install: https://github.com/crytic/slither#how-to-install
# Usage: https://github.com/crytic/slither/wiki/Usage

mkdir -p reports

pip3 install --user slither-analyzer && \
yarn build && \

echo "Analyzing contracts..."
slither . &> reports/analyzer-report.log && \

echo "Done!"
56 changes: 56 additions & 0 deletions packages/data-edge/scripts/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/bash

set -eo pipefail

MNEMONIC="myth like bonus scare over problem client lizard pioneer submit female collect"
TESTRPC_PORT=8545

### Functions

evm_running() {
nc -z localhost "$TESTRPC_PORT"
}

evm_start() {
echo "Starting our own evm instance at port $TESTRPC_PORT"
npx hardhat node --port "$TESTRPC_PORT" > /dev/null &
}

evm_kill() {
if evm_running; then
echo "Killing evm instance at port $TESTRPC_PORT"
kill -9 $(lsof -i:$TESTRPC_PORT -t)
fi
}

### Setup EVM

# Ensure we compiled sources

yarn build

# Gas reporter needs to run in its own evm instance
if [ "$RUN_EVM" = true ]; then
evm_kill
evm_start
sleep 5
fi

### Main

mkdir -p reports

# Run using the standalone evm instance
npx hardhat test --network hardhat

### Cleanup

# Exit error mode so the evm instance always gets killed
set +e
result=0

if [ "$RUN_EVM" = true ]; then
evm_kill
fi

exit $result
48 changes: 48 additions & 0 deletions packages/data-edge/tasks/craft-calldata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { task } from 'hardhat/config'
import '@nomiclabs/hardhat-ethers'
import { Contract } from 'ethers'

const baseABI = [
{
inputs: [
{
internalType: 'bytes',
name: '_payload',
type: 'bytes',
},
],
name: '',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
]

const getContract = (contractAddress: string, abi, provider) => {
return new Contract(contractAddress, abi, provider)
}

const getAbiForSelector = (selector: string) => {
return baseABI.map((item) => {
item.name = selector
return item
})
}

task('data:craft', 'Build calldata')
.addParam('edge', 'Address of the data edge contract')
.addParam('selector', 'Selector name')
.addParam('data', 'Call data to post')
.setAction(async (taskArgs, hre) => {
// parse input
const edgeAddress = taskArgs.edge
const calldata = taskArgs.data
const selector = taskArgs.selector

// build data
const abi = getAbiForSelector(selector)
const contract = getContract(edgeAddress, abi, hre.ethers.provider)
const tx = await contract.populateTransaction[selector](calldata)
const txData = tx.data
console.log(txData)
})
27 changes: 27 additions & 0 deletions packages/data-edge/tasks/post-calldata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { task } from 'hardhat/config'
import '@nomiclabs/hardhat-ethers'

task('data:post', 'Post calldata')
.addParam('edge', 'Address of the data edge contract')
.addParam('data', 'Call data to post')
.setAction(async (taskArgs, hre) => {
// prepare data
const edgeAddress = taskArgs.edge
const txData = taskArgs.data
const contract = await hre.ethers.getContractAt('DataEdge', edgeAddress)
const txRequest = {
data: txData,
to: contract.address,
}

// send transaction
console.log(`Sending data...`)
console.log(`> edge: ${contract.address}`)
console.log(`> sender: ${await contract.signer.getAddress()}`)
console.log(`> payload: ${txData}`)
const tx = await contract.signer.sendTransaction(txRequest)
console.log(`> tx: ${tx.hash} nonce:${tx.nonce} limit: ${tx.gasLimit} gas: ${tx.gasPrice.toNumber() / 1e9} (gwei)`)
const rx = await tx.wait()
console.log('> rx: ', rx.status == 1 ? 'success' : 'failed')
console.log(`Done!`)
})
56 changes: 56 additions & 0 deletions packages/data-edge/test/dataedge.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { ethers } from 'hardhat'
import '@nomiclabs/hardhat-ethers'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'

import { DataEdge__factory, DataEdge } from '../build/types'
import { expect } from 'chai'

const { getContractFactory, getSigners } = ethers
const { id, hexConcat, randomBytes, hexlify, defaultAbiCoder } = ethers.utils

describe('DataEdge', () => {
let edge: DataEdge
let me: SignerWithAddress

beforeEach(async () => {
;[me] = await getSigners() // eslint-disable-line @typescript-eslint/no-extra-semi

const factory = (await getContractFactory('DataEdge', me)) as DataEdge__factory
edge = await factory.deploy()
await edge.deployed()
})

describe('submit data', async () => {
it('post any arbitrary data as selector', async () => {
// virtual function call
const txRequest = {
data: '0x123123',
to: edge.address,
}
// send transaction
const tx = await me.sendTransaction(txRequest)
const rx = await tx.wait()
// transaction must work - it just stores data
expect(rx.status).eq(1)
})

it('post long calldata', async () => {
// virtual function call
const selector = id('setEpochBlocksPayload(bytes)').slice(0, 10)
// calldata payload
const messageBlocks = hexlify(randomBytes(1000))
const txCalldata = defaultAbiCoder.encode(['bytes'], [messageBlocks]) // we abi encode to allow the subgraph to decode it properly
const txData = hexConcat([selector, txCalldata])
// craft full transaction
const txRequest = {
data: txData,
to: edge.address,
}
// send transaction
const tx = await me.sendTransaction(txRequest)
const rx = await tx.wait()
// transaction must work - it just stores data
expect(rx.status).eq(1)
})
})
})
62 changes: 62 additions & 0 deletions packages/data-edge/test/eventful-dataedge.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { ethers } from 'hardhat'
import '@nomiclabs/hardhat-ethers'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'

import { EventfulDataEdge__factory, EventfulDataEdge } from '../build/types'
import { expect } from 'chai'

const { getContractFactory, getSigners } = ethers
const { id, hexConcat, randomBytes, hexlify, defaultAbiCoder } = ethers.utils

describe('EventfulDataEdge', () => {
let edge: EventfulDataEdge
let me: SignerWithAddress

beforeEach(async () => {
;[me] = await getSigners() // eslint-disable-line @typescript-eslint/no-extra-semi

const factory = (await getContractFactory('EventfulDataEdge', me)) as EventfulDataEdge__factory
edge = await factory.deploy()
await edge.deployed()
})

describe('submit data', async () => {
it('post any arbitrary data as selector', async () => {
// virtual function call
const txRequest = {
data: '0x123123',
to: edge.address,
}
// send transaction
const tx = await me.sendTransaction(txRequest)
const rx = await tx.wait()
// transaction must work - it just stores data
expect(rx.status).eq(1)
// emit log event
const event = edge.interface.parseLog(rx.logs[0]).args
expect(event.data).eq(txRequest.data)
})

it('post long calldata', async () => {
// virtual function call
const selector = id('setEpochBlocksPayload(bytes)').slice(0, 10)
// calldata payload
const messageBlocks = hexlify(randomBytes(1000))
const txCalldata = defaultAbiCoder.encode(['bytes'], [messageBlocks]) // we abi encode to allow the subgraph to decode it properly
const txData = hexConcat([selector, txCalldata])
// craft full transaction
const txRequest = {
data: txData,
to: edge.address,
}
// send transaction
const tx = await me.sendTransaction(txRequest)
const rx = await tx.wait()
// transaction must work - it just stores data
expect(rx.status).eq(1)
// emit log event
const event = edge.interface.parseLog(rx.logs[0]).args
expect(event.data).eq(txRequest.data)
})
})
})
22 changes: 22 additions & 0 deletions packages/data-edge/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"lib": ["ES2020", "dom"],
"module": "commonjs",
"moduleResolution": "node",
"target": "ES2020",
"outDir": "dist",
"resolveJsonModule": true,
"esModuleInterop": true
},
"exclude": ["dist", "node_modules"],
"files": [
"./hardhat.config.ts",
"./scripts/**/*.ts",
"./test/**/*.ts",
"node_modules/@nomiclabs/hardhat-ethers/internal/type-extensions.d.ts",
"node_modules/@nomiclabs/hardhat-etherscan/dist/src/type-extensions.d.ts",
"node_modules/@nomiclabs/hardhat-waffle/dist/src/type-extensions.d.ts",
"node_modules/@typechain/hardhat/dist/type-extensions.d.ts",
"./index.d.ts"
]
}
11,908 changes: 11,908 additions & 0 deletions packages/data-edge/yarn.lock

Large diffs are not rendered by default.

0 comments on commit 67fd967

Please sign in to comment.