Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
Contracts V3 (paritytech#882)
Browse files Browse the repository at this point in the history
Co-authored-by: David Dunn <26876072+doubledup@users.noreply.github.com>
Co-authored-by: Clara van Staden <claravanstaden64@gmail.com>
Co-authored-by: Alistair Singh <alistair.singh7@gmail.com>
Co-authored-by: Ron <yrong1997@gmail.com>
Co-authored-by: claravanstaden <Cats 4 life!>
  • Loading branch information
5 people authored Jul 30, 2023
1 parent 3c4bec4 commit 30d0f0a
Show file tree
Hide file tree
Showing 258 changed files with 8,975 additions and 10,796 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/contracts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: contracts

on:
push:
paths:
- "contracts/**"
- "!contracts/**/README.md"
branches:
- main
pull_request:
paths:
- "contracts/**"
- "!contracts/**/README.md"

jobs:
build:
runs-on: snowbridge-runner
timeout-minutes: 15
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 2
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Test
working-directory: contracts
run: forge test
- name: Coverage
working-directory: contracts
run: forge coverage --report=lcov --via-ir
- name: Upload coverage reports to Codecov with GitHub Action
uses: codecov/codecov-action@v3
with:
working-directory: contracts
files: lcov.info
flags: solidity
51 changes: 0 additions & 51 deletions .github/workflows/ethereum.yml

This file was deleted.

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ node_modules/
.envrc
parachain/build_rs_cov.profraw
compiler_config.json
contracts/beefy-state.json

go/
22 changes: 10 additions & 12 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@
path = cumulus
url = https://github.com/Snowfork/cumulus
branch = snowbridge
[submodule "core/packages/contracts/lib/forge-std"]
path = core/packages/contracts/lib/forge-std
[submodule "contracts/lib/forge-std"]
path = contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
branch = master
[submodule "core/packages/contracts/lib/ds-test"]
path = core/packages/contracts/lib/ds-test
[submodule "contracts/lib/openzeppelin-contracts"]
path = contracts/lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "contracts/lib/ds-test"]
path = contracts/lib/ds-test
url = https://github.com/dapphub/ds-test
[submodule "core/packages/contracts/lib/openzeppelin-contracts"]
path = core/packages/contracts/lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
branch = v4.8.2
[submodule "core/packages/contracts/lib/canonical-weth"]
path = core/packages/contracts/lib/canonical-weth
url = https://github.com/snowfork/canonical-weth
[submodule "contracts/lib/canonical-weth"]
path = contracts/lib/canonical-weth
url = https://github.com/Snowfork/canonical-weth
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ Off-chain relayer services for relaying messages between Polkadot and Ethereum.

### Contracts

Ethereum contracts and unit tests. See [core/packages/contracts/README.md](core/packages/contracts/README.md)
Ethereum contracts and unit tests. See [contracts/README.md](contracts/README.md)

### Integration Tests

This component includes our end to end tests, that pull together all the above services and set them up easily through scripts for automated E2E tests. See [core/packages/test/README.md](core/packages/test/README.md).
This component includes our end to end tests, that pull together all the above services and set them up easily through scripts for automated E2E tests. See [web/packages/test/README.md](web/packages/test/README.md).

## Development

Expand All @@ -31,15 +31,19 @@ mkdir -p ~/.config/nix
echo 'experimental-features = nix-command flakes' >> ~/.config/nix/nix.conf
```

(if you don't want to use flakes, you can instead pass the flag `--experimental-features nix-command flakes` to nix, eg.
`nix --experimental-features 'nix-command flakes' develop`)

Then activate a developer shell in the root of our repo, where [`flake.nix`](./flake.nix) is located:

```sh
nix develop
```

Also make sure to run this initialization script once:
```sh
scripts/init.sh
```

### Support for code editors

To ensure your code editor (such as VS Code) can execute tools in the nix shell, startup your editor within the
interactive shell.

Expand All @@ -50,21 +54,25 @@ nix develop
code .
```

### Custom shells

The developer shell is bash by default. To preserve your existing shell:

```sh
nix develop --command $SHELL
```

### Automatic developer shells

To automatically enter the developer shell whenever you open the project, install
[`direnv`](https://direnv.net/docs/installation.html) and use the template `.envrc`:

```sh
cp .envrc.example .envrc
direnv allow
````
```

## Upgrade
### Upgrading the Rust toolchain

Sometimes we would like to upgrade rust toolchain. First update `parachain/rust-toolchain.toml` as required and then update `flake.lock` running
```sh
Expand Down
2 changes: 1 addition & 1 deletion _typos.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[files]
extend-exclude = [
"core/packages/contracts/lib",
"contracts/lib",
"**/*.yaml",
"**/*.json",
"**/fixtures/*.js",
Expand Down
12 changes: 6 additions & 6 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ coverage:
github_checks:
annotations: false
ignore:
- "core/packages/contracts/test/mocks"
- "core/packages/contracts/src/utils"
- "core/packages/contracts/src/ScaleCodec.sol"
- "core/packages/contracts/src/SubstrateTypes.sol"
- "contracts/test/mocks"
- "contracts/src/utils"
- "contracts/src/ScaleCodec.sol"
- "contracts/src/SubstrateTypes.sol"
- "parachain/tools"
- "parachain/pallets/ethereum-beacon-client/src/benchmarking"
- "parachain/pallets/ethereum-beacon-client/src/weights.rs"
- "core/packages/contracts/src/DeployScript.sol"
- "contracts/src/DeployScript.sol"
flags:
solidity:
paths:
- core/packages/contracts
- contracts
carryforward: true
rust:
paths:
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ source_up_if_exists
## BeefyClient
export RANDAO_COMMIT_DELAY=3
export RANDAO_COMMIT_EXP=8
export PREV_RANDAO=377
export ValidatorSetSize=300

## ParachainClient
export PARAID=1000
Expand Down
70 changes: 70 additions & 0 deletions contracts/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
AgentTest:testInvoke() (gas: 20810)
AgentTest:testInvokeFail() (gas: 13429)
AgentTest:testInvokeUnauthorized() (gas: 13974)
BeefyClientTest:testCreateFinalBitfield() (gas: 278225)
BeefyClientTest:testCreateFinalBitfieldInvalid() (gas: 265008)
BeefyClientTest:testCreateInitialBitfield() (gas: 650507)
BeefyClientTest:testCreateInitialBitfieldInvalid() (gas: 578841)
BeefyClientTest:testScaleEncodeCommit() (gas: 32353)
BeefyClientTest:testSubmit():((uint32,uint64,(bytes2,bytes)[])) (gas: 708627)
BeefyClientTest:testSubmitFailForPrevRandaoCapturedMoreThanOnce() (gas: 266184)
BeefyClientTest:testSubmitFailForPrevRandaoTooEarlyOrTooLate() (gas: 207388)
BeefyClientTest:testSubmitFailInvalidSignature() (gas: 657123)
BeefyClientTest:testSubmitFailValidatorNotInBitfield() (gas: 645077)
BeefyClientTest:testSubmitFailWithInvalidBitfield() (gas: 634383)
BeefyClientTest:testSubmitFailWithInvalidMMRLeaf() (gas: 748779)
BeefyClientTest:testSubmitFailWithInvalidMMRLeafProof() (gas: 752764)
BeefyClientTest:testSubmitFailWithInvalidTicket() (gas: 638107)
BeefyClientTest:testSubmitFailWithInvalidValidatorSet() (gas: 642432)
BeefyClientTest:testSubmitFailWithNotEnoughClaims() (gas: 197586)
BeefyClientTest:testSubmitFailWithStaleCommitment() (gas: 835952)
BeefyClientTest:testSubmitFailWithoutPrevRandao() (gas: 532261)
BeefyClientTest:testSubmitWithHandover() (gas: 736139)
BeefyClientTest:testSubmitWithHandoverFailStaleCommitment() (gas: 859922)
BeefyClientTest:testSubmitWithHandoverFailWithInvalidValidatorSet() (gas: 666242)
BeefyClientTest:testSubmitWithHandoverFailWithoutPrevRandao() (gas: 556301)
GatewayTest:testAgentExecution() (gas: 52791)
GatewayTest:testAgentExecutionBadOrigin() (gas: 23354)
GatewayTest:testAgentExecutionBadPayload() (gas: 22077)
GatewayTest:testCreateAgent() (gas: 254909)
GatewayTest:testCreateAgentAlreadyCreated() (gas: 256489)
GatewayTest:testCreateChannel() (gas: 332117)
GatewayTest:testCreateChannelFailsAgentDoesNotExist() (gas: 19185)
GatewayTest:testCreateChannelFailsChannelAlreadyExists() (gas: 335995)
GatewayTest:testDisableOutboundMessaging() (gas: 67040)
GatewayTest:testDisableOutboundMessagingForChannel() (gas: 161374)
GatewayTest:testGetters() (gas: 37883)
GatewayTest:testHandlersNotExternallyCallable() (gas: 52292)
GatewayTest:testInitializeNotExternallyCallable() (gas: 16762)
GatewayTest:testRegisterToken() (gas: 85845)
GatewayTest:testRelayerNotRewarded() (gas: 75289)
GatewayTest:testRelayerRewardedFromAgent() (gas: 310728)
GatewayTest:testSendTokenAddress20() (gas: 128049)
GatewayTest:testSendTokenAddress20FailsInvalidDestination() (gas: 59703)
GatewayTest:testSendTokenAddress32() (gas: 129387)
GatewayTest:testSendTokenAddress32ToAssetHub() (gas: 128776)
GatewayTest:testSetOperatingMode() (gas: 39208)
GatewayTest:testSubmitFailInvalidChannel() (gas: 27926)
GatewayTest:testSubmitFailInvalidNonce() (gas: 318948)
GatewayTest:testSubmitHappyPath() (gas: 312342)
GatewayTest:testUpdateChannel() (gas: 58121)
GatewayTest:testUpdateChannelFailDoesNotExist() (gas: 20107)
GatewayTest:testUpdateChannelSanityChecksForBridgeHubChannel() (gas: 22147)
GatewayTest:testUpgrade() (gas: 208455)
GatewayTest:testUpgradeFailCodeHashMismatch() (gas: 178843)
GatewayTest:testUpgradeFailOnInitializationFailure() (gas: 182568)
GatewayTest:testUserDoesNotProvideEnoughFees() (gas: 218463)
GatewayTest:testUserPaysFees() (gas: 244678)
GatewayTest:testWithdrawAgentFunds() (gas: 64315)
MMRProofTest:testVerifyLeafProof() (gas: 370749)
MMRProofTest:testVerifyLeafProofFailsExceededProofSize() (gas: 358741)
ScaleCodecTest:testCheckedEncodeCompactU32() (gas: 5120)
ScaleCodecTest:testEncodeCompactU32() (gas: 9722)
ScaleCodecTest:testEncodeU128() (gas: 192)
ScaleCodecTest:testEncodeU16() (gas: 434)
ScaleCodecTest:testEncodeU256() (gas: 478)
ScaleCodecTest:testEncodeU32() (gas: 170)
ScaleCodecTest:testEncodeU64() (gas: 280)
VerificationTest:testCreateParachainHeaderMerkleFailInvalidHeader() (gas: 11341)
VerificationTest:testCreateParachainHeaderMerkleLeaf() (gas: 20830)
VerificationTest:testIsCommitmentInHeaderDigest() (gas: 21863)
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ types/
tsconfig.tsbuildinfo
lcov.info
tenderly.yaml
docs/
File renamed without changes.
71 changes: 71 additions & 0 deletions contracts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Ethereum Contracts

## Overview

### Gateway

The Ethereum side of the bridge is organised around a central `Gateway` contract, responsible for the following:
* Receiving, verifying, and dispatching inbound messages from Polkadot
* Accepting outbound messages for delivery to Polkadot
* Higher-level application features such as token transfers

The gateway is defined by the following contracts
* [IGateway.sol](src/interfaces/IGateway.sol): Public API of the gateway
* [GatewayProxy.sol](src/Gateway.sol): Proxy contract for the gateway
* [Gateway.sol](src/Gateway.sol): Implementation contract of the gateway

The gateway is modular in design, being composed of libraries implementing specific functionality:

* [Verification.sol](src/Verification.sol): Verification of inbound messages from Polakdot
* [Assets.sol](src/Assets.sol): ERC20 token transfers to Polkadot

#### Governance

Using cross-chain messaging, the gateway is governed remotely by the governance of the Polkadot relay chain.

#### Upgrades

The gateway consists of an upgradable proxy, and an implementation contract, loosely following the [ERC1967](https://eips.ethereum.org/EIPS/eip-1967) standard.

### Agents

Agents are proxy contracts for arbitrary consensus systems on Polkadot. Logically, one can think of them as the sovereign accounts of remote consensus systems.

They have a number of uses:
* When an Ethereum user sends ERC20 tokens to Polkadot (Specifically the AssetHub parachain), these tokens are actually locked into the agent contract corresponding to the AssetHub parachain. Then finally, on the AssetHub parachain, wrapped tokens are minted into an account controlled by the sender.
* When a Polkadot parachain wishes to call a function on an Ethereum contract, it will appear to the destination contract that the message sender is the agent contract for the origin parachain.
* Agents control the funds for receiving fees from users and disbursing rewards to message relayers

Agents are defined by the following contracts:
* [Agent.sol](src/Agent.sol): Agent contract
* [AgentExecutor.sol](src/AgentExecutor.sol): Code executed within an agent using `delegatecall`

The creation of new agents can be initiated by calling `EthereumControl::create_agent` extrinsic on the BridgeHub parachain.

### BeefyClient

The [BeefyClient.sol](src/BeefyClient.sol) contract implements a light client for following a subset of Polkadot consensus. In conjunction with the [Verification.sol](src/Verification.sol) library, it used to verify inbound messages from the BridgeHub parachain.

## Testing

Run all tests:

```bash
forge test
```

Run coverage reports:

```bash
forge coverage
```

## Test Fixtures

Some of the unit tests require fixture data generated by a live deployment. For this purpose, we use logging artifacts from the offchain relayers running in the [E2E](../web/packages/test) stack.
```
BEEFY commitments & proofs extracted from `/tmp/snowbridge/beefy-relay.log`.
1. Search for `Sent SubmitFinal transaction` in relayer log file
2. Copy into `test/data/beefy-commitment.json`
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ optimizer = true
optimizer_runs = 20_000
via_ir = true
test = 'test'
ffi = true
fs_permissions = [{ access = "read-write", path = "test/data"}, { access = "read", path = "./"}]

ignored_error_codes = [
# DeployScript.sol is never deployed
5574
]

# no_match_test = "testRegenerateBitField"
1 change: 1 addition & 0 deletions contracts/lib/forge-std
Submodule forge-std added at 74cfb7
1 change: 1 addition & 0 deletions contracts/lib/openzeppelin-contracts
Submodule openzeppelin-contracts added at e50c24
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 30d0f0a

Please sign in to comment.