Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
86ad952
Reimplement OutboundQueue
vgeddes May 31, 2023
3c27d1d
Add MessageQueue pallet to BridgeHub runtime
vgeddes Jun 1, 2023
f056cc8
Relayer no longer requires snowbridge-query-events tool for querying …
vgeddes Jun 1, 2023
bd1773d
Refactor tractor
vgeddes Jun 3, 2023
da66429
fixes
vgeddes Jun 12, 2023
ff6e3d9
Merge branch 'main' into vincent/outbound-queue
vgeddes Jun 12, 2023
630dce2
rework runtime api for outbound-queue
vgeddes Jun 14, 2023
15bf1c6
misc
vgeddes Jun 14, 2023
16f4efc
Merge branch 'main' into vincent/outbound-queue
vgeddes Jun 15, 2023
a953e50
Fix ethereum unit test
vgeddes Jun 15, 2023
dd83989
update things
vgeddes Jun 15, 2023
3db3ed5
Reduce stack depth in DeployScript.sol
vgeddes Jun 15, 2023
2622339
Revert Merkle proof verifier contract (#861)
doubledup Jun 15, 2023
71981c6
Optimize merkle proof verifier
vgeddes Jun 15, 2023
71b0f21
Revert changes to relayer merkle package
doubledup Jun 15, 2023
a903c6d
Update contract bindings
vgeddes Jun 15, 2023
248f6bb
fix parachain unit tests
vgeddes Jun 15, 2023
2c1d052
More relayer fixes
vgeddes Jun 15, 2023
b817948
Fix message flow in Polkadot->Ethereum direction
vgeddes Jun 16, 2023
0175e36
linting
vgeddes Jun 16, 2023
2c749e1
revert changes to IParachainClient interface
vgeddes Jun 16, 2023
56b9d83
update cumulus
vgeddes Jun 16, 2023
12705ea
merged in companion PR
vgeddes Jun 16, 2023
ca363c1
Merge branch 'main' into vincent/outbound-queue
vgeddes Jun 16, 2023
e32608d
improve encoding of parachain header in ParachainClient.sol
vgeddes Jun 16, 2023
1058bd5
Add copyright/license boilerplate
vgeddes Jun 16, 2023
109a805
Port over ethereum location converter
vgeddes Jun 16, 2023
9c62531
remove obsolete eth1 POW code
vgeddes Jun 16, 2023
e648446
fix unit tests
vgeddes Jun 16, 2023
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
3 changes: 1 addition & 2 deletions .github/workflows/ethereum.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
run: forge test
- name: Coverage
working-directory: core/packages/contracts
run: forge coverage --report=lcov
run: forge coverage --report=lcov --via-ir
- name: Lint
working-directory: core/packages/contracts
run: pnpm lint
Expand All @@ -48,4 +48,3 @@ jobs:
with:
working-directory: core/packages/contracts
files: lcov.info

2 changes: 1 addition & 1 deletion core/packages/contracts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ artifacts/
coverage.json
coverage/
.vscode/
deployments/
out/
cache/
broadcast/
types/
tsconfig.tsbuildinfo
lcov.info
tenderly.yaml
2 changes: 1 addition & 1 deletion core/packages/contracts/.solhint.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "solhint:recommended",
"rules": {
"compiler-version": ["error", "0.8.19"],
"compiler-version": ["error", "0.8.20"],
"func-visibility": ["warn", {"ignoreConstructors":true}],
"not-rely-on-time": "off",
"avoid-low-level-calls": "off",
Expand Down
6 changes: 3 additions & 3 deletions core/packages/contracts/foundry.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[profile.default]
solc_version = '0.8.19'
solc_version = "0.8.20"
optimizer = true
optimizer_runs = 20_000
via_ir = true
test = 'test'
ffi = true

ignored_error_codes = [
# prevrandao not supported by Anvil VM
9432
# DeployScript.sol is never deployed
5574
]
2 changes: 1 addition & 1 deletion core/packages/contracts/scripts/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class ValidatorSet {
let leaves = wallets.map((w) => keccakFromHexString(w.address))
let tree = new MerkleTree(leaves, keccak, {
sortLeaves: false,
sortPairs: true,
sortPairs: false,
})

this.wallets = wallets
Expand Down
14 changes: 14 additions & 0 deletions core/packages/contracts/src/Auth.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
pragma solidity 0.8.20;

import {AccessControl} from "openzeppelin/access/AccessControl.sol";

contract Auth is AccessControl {
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");

constructor() {
_grantRole(ADMIN_ROLE, msg.sender);
_setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);
}
}
14 changes: 6 additions & 8 deletions core/packages/contracts/src/BeefyClient.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
pragma solidity 0.8.20;

import {ECDSA} from "openzeppelin/utils/cryptography/ECDSA.sol";
import {Ownable} from "openzeppelin/access/Ownable.sol";
import {MerkleProof} from "openzeppelin/utils/cryptography/MerkleProof.sol";
import {MerkleProof} from "./utils/MerkleProof.sol";
import {Bitfield} from "./utils/Bitfield.sol";
import {MMRProof} from "./utils/MMRProof.sol";
import {ScaleCodec} from "./ScaleCodec.sol";
Expand Down Expand Up @@ -441,10 +442,7 @@ contract BeefyClient is Ownable {
}

// Check that validator is actually in a validator set
//
// NOTE: This currently insecure due to a regression documented in SNO-427.
// Basically `proof.index` (the merkle leaf index) is not being validated.
if (!isValidatorInSet(vset, proof.account, proof.proof)) {
if (!isValidatorInSet(vset, proof.account, proof.index, proof.proof)) {
revert InvalidValidatorProof();
}

Expand Down Expand Up @@ -498,13 +496,13 @@ contract BeefyClient is Ownable {
* @param proof Merkle proof required for validation of the address
* @return true if the validator is in the set
*/
function isValidatorInSet(ValidatorSet memory vset, address addr, bytes32[] calldata proof)
function isValidatorInSet(ValidatorSet memory vset, address addr, uint256 index, bytes32[] calldata proof)
internal
pure
returns (bool)
{
bytes32 hashedLeaf = keccak256(abi.encodePacked(addr));
return MerkleProof.verify(proof, vset.root, hashedLeaf);
return MerkleProof.verify(vset.root, hashedLeaf, index, vset.length, proof);
}

/**
Expand Down
75 changes: 53 additions & 22 deletions core/packages/contracts/src/DeployScript.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
pragma solidity 0.8.20;

import {WETH9} from "canonical-weth/WETH9.sol";
import {Script} from "forge-std/Script.sol";
Expand All @@ -11,55 +12,77 @@ import {OutboundQueue} from "../src/OutboundQueue.sol";
import {NativeTokens} from "../src/NativeTokens.sol";
import {TokenVault} from "../src/TokenVault.sol";
import {Vault} from "../src/Vault.sol";
import {IVault} from "../src/IVault.sol";
import {UpgradeProxy} from "../src/UpgradeProxy.sol";
import {SovereignTreasury} from "../src/SovereignTreasury.sol";
import {Registry} from "../src/Registry.sol";
import {ParaID} from "../src/Types.sol";

contract DeployScript is Script {
Registry public registry;
Vault public vault;
BeefyClient public beefyClient;
ParachainClient public parachainClient;
InboundQueue public inboundQueue;
OutboundQueue public outboundQueue;
TokenVault public tokenVault;
NativeTokens public nativeTokens;
UpgradeProxy public upgradeProxy;

function setUp() public {}

function run() public {
uint256 privateKey = vm.envUint("PRIVATE_KEY");
address deployer = vm.rememberKey(privateKey);
vm.startBroadcast(deployer);

// Registry
registry = new Registry();
registry.grantRole(registry.REGISTER_ROLE(), deployer);

// Vault
vault = new Vault();

// SovereignTreasury
Vault vault = new Vault();
SovereignTreasury treasury = new SovereignTreasury(vault);
SovereignTreasury treasury = new SovereignTreasury(registry, vault);
registry.registerContract(keccak256("SovereignTreasury"), address(treasury));

// BeefyClient
uint256 randaoCommitDelay = vm.envUint("RANDAO_COMMIT_DELAY");
uint256 randaoCommitExpiration = vm.envUint("RANDAO_COMMIT_EXP");
BeefyClient beefyClient = new BeefyClient(randaoCommitDelay, randaoCommitExpiration);
beefyClient = new BeefyClient(randaoCommitDelay, randaoCommitExpiration);

// ParachainClient
uint32 paraId = uint32(vm.envUint("BRIDGE_HUB_PARAID"));
ParachainClient parachainClient = new ParachainClient(beefyClient, paraId);
parachainClient = new ParachainClient(beefyClient, paraId);

// InboundQueue
uint256 relayerReward = vm.envUint("RELAYER_REWARD");
InboundQueue inboundQueue = new InboundQueue(parachainClient, vault, relayerReward);
inboundQueue = new InboundQueue(registry, parachainClient, vault, relayerReward);
registry.registerContract(keccak256("InboundQueue"), address(inboundQueue));

// OutboundQueue
uint256 relayerFee = vm.envUint("RELAYER_FEE");
OutboundQueue outboundQueue = new OutboundQueue(vault, relayerFee);
outboundQueue = new OutboundQueue(registry, vault, relayerFee);
registry.registerContract(keccak256("OutboundQueue"), address(outboundQueue));

// NativeTokens
TokenVault tokenVault = new TokenVault();
NativeTokens nativeTokens = new NativeTokens(
tokenVault = new TokenVault();
nativeTokens = new NativeTokens(
registry,
tokenVault,
outboundQueue,
ParaID.wrap(uint32(vm.envUint("ASSET_HUB_PARAID"))),
vm.envUint("CREATE_TOKEN_FEE")
vm.envUint("CREATE_TOKEN_FEE"),
bytes2(vm.envBytes("CREATE_CALL_INDEX")),
bytes2(vm.envBytes("SET_METADATA_CALL_INDEX"))
);
inboundQueue.updateHandler(1, IRecipient(nativeTokens));
registry.registerContract(keccak256("NativeTokens"), address(nativeTokens));

// Deploy WETH for testing
new WETH9();

// Upgrades
UpgradeProxy upgradeProxy = new UpgradeProxy(ParaID.wrap(paraId));
// UpgradeProxy
upgradeProxy = new UpgradeProxy(registry, ParaID.wrap(paraId));
registry.registerContract(keccak256("UpgradeProxy"), address(upgradeProxy));

// Allow inbound queue to send messages to handlers
nativeTokens.grantRole(nativeTokens.SENDER_ROLE(), address(inboundQueue));
Expand All @@ -82,24 +105,32 @@ contract DeployScript is Script {
// Move ownership of everything to Upgrades app

treasury.grantRole(treasury.ADMIN_ROLE(), address(upgradeProxy));
treasury.revokeRole(treasury.ADMIN_ROLE(), address(this));
treasury.revokeRole(treasury.ADMIN_ROLE(), deployer);

nativeTokens.grantRole(nativeTokens.ADMIN_ROLE(), address(upgradeProxy));
nativeTokens.revokeRole(nativeTokens.ADMIN_ROLE(), address(this));
nativeTokens.revokeRole(nativeTokens.ADMIN_ROLE(), deployer);

vault.grantRole(vault.ADMIN_ROLE(), address(upgradeProxy));
vault.revokeRole(vault.ADMIN_ROLE(), address(this));
vault.revokeRole(vault.ADMIN_ROLE(), deployer);

tokenVault.grantRole(tokenVault.ADMIN_ROLE(), address(upgradeProxy));
tokenVault.revokeRole(tokenVault.ADMIN_ROLE(), address(this));
tokenVault.revokeRole(tokenVault.ADMIN_ROLE(), deployer);

inboundQueue.grantRole(inboundQueue.ADMIN_ROLE(), address(upgradeProxy));
inboundQueue.revokeRole(inboundQueue.ADMIN_ROLE(), address(this));
inboundQueue.revokeRole(inboundQueue.ADMIN_ROLE(), deployer);

outboundQueue.grantRole(outboundQueue.ADMIN_ROLE(), address(upgradeProxy));
outboundQueue.revokeRole(outboundQueue.ADMIN_ROLE(), address(this));
outboundQueue.revokeRole(outboundQueue.ADMIN_ROLE(), deployer);

registry.grantRole(outboundQueue.ADMIN_ROLE(), address(upgradeProxy));
registry.revokeRole(outboundQueue.ADMIN_ROLE(), deployer);

upgradeProxy.revokeRole(upgradeProxy.ADMIN_ROLE(), deployer);

upgradeProxy.revokeRole(upgradeProxy.ADMIN_ROLE(), address(this));
// Fund the sovereign account for the BridgeHub parachain. Used to reward relayers
// of messages originating from BridgeHub
uint256 initialDeposit = vm.envUint("BRIDGE_HUB_INITIAL_DEPOSIT");
vault.deposit{value: initialDeposit}(ParaID.wrap(paraId));

vm.stopBroadcast();
}
Expand Down
36 changes: 36 additions & 0 deletions core/packages/contracts/src/Gateway.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
pragma solidity 0.8.20;

import {AccessControl} from "openzeppelin/access/AccessControl.sol";
import {Registry} from "./Registry.sol";
import {IOutboundQueue} from "./IOutboundQueue.sol";
import {IRecipient} from "./IRecipient.sol";
import {ParaID} from "./Types.sol";
import {Auth} from "./Auth.sol";
import {RegistryLookup} from "./RegistryLookup.sol";

abstract contract Gateway is Auth, RegistryLookup, IRecipient {
bytes32 public constant SENDER_ROLE = keccak256("SENDER_ROLE");
bytes32 public constant OUTBOUND_QUEUE = keccak256("OutboundQueue");

/* Errors */

error Unauthorized();

constructor(Registry registry) RegistryLookup(registry) {
_setRoleAdmin(SENDER_ROLE, ADMIN_ROLE);
}

function handle(ParaID origin, bytes calldata message) external virtual;

function outboundQueue() internal view returns (IOutboundQueue) {
return IOutboundQueue(resolve(OUTBOUND_QUEUE));
}

function ensureOrigin(ParaID a, ParaID b) internal pure {
if (a != b) {
revert Unauthorized();
}
}
}
3 changes: 2 additions & 1 deletion core/packages/contracts/src/IOutboundQueue.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
pragma solidity 0.8.20;

import {ParaID} from "./Types.sol";

Expand Down
8 changes: 3 additions & 5 deletions core/packages/contracts/src/IParachainClient.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
pragma solidity 0.8.20;

interface IParachainClient {
function verifyCommitment(
bytes32 commitment,
bytes calldata opaqueProof
) external view returns (bool);
function verifyCommitment(bytes32 commitment, bytes calldata opaqueProof) external view returns (bool);
}
3 changes: 2 additions & 1 deletion core/packages/contracts/src/IRecipient.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
pragma solidity 0.8.20;

import {ParaID} from "./Types.sol";

Expand Down
6 changes: 0 additions & 6 deletions core/packages/contracts/src/IUpgradeTask.sol

This file was deleted.

10 changes: 0 additions & 10 deletions core/packages/contracts/src/IVault.sol

This file was deleted.

Loading