Skip to content

Commit 1d7ed4e

Browse files
committed
made signal verify more generic
comment
1 parent 49f4745 commit 1d7ed4e

File tree

5 files changed

+52
-51
lines changed

5 files changed

+52
-51
lines changed

src/libs/LibSignal.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,12 @@ library LibSignal {
8787
address(this), deriveSlot(chainId, sender, value), value, root, accountProof, storageProof
8888
);
8989
}
90+
91+
function verifySignal(bytes32 root, uint64 chainId, address sender, bytes32 value, bytes[] memory storageProof)
92+
internal
93+
pure
94+
returns (bool valid)
95+
{
96+
valid = LibTrieProof.verifyState(LibSignal.deriveSlot(chainId, sender, value), value, root, storageProof);
97+
}
9098
}

src/protocol/ETHBridge.sol

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity ^0.8.28;
33

4-
import {LibTrieProof} from "../libs/LibTrieProof.sol";
5-
64
import {IETHBridge} from "./IETHBridge.sol";
75
import {StorageSlot} from "@openzeppelin/contracts/utils/StorageSlot.sol";
86

@@ -39,12 +37,10 @@ abstract contract ETHBridge is IETHBridge {
3937
}
4038

4139
/// @inheritdoc IETHBridge
42-
function claimDeposit(
43-
ETHDeposit memory deposit,
44-
uint256 height,
45-
bytes[] memory accountProof,
46-
bytes[] memory storageProof
47-
) external virtual returns (bytes32 id);
40+
function claimDeposit(ETHDeposit memory deposit, uint256 height, bytes memory proof)
41+
external
42+
virtual
43+
returns (bytes32 id);
4844

4945
/// @dev Processes deposit claim by id.
5046
/// @param id Identifier of the deposit

src/protocol/IETHBridge.sol

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,8 @@ interface IETHBridge {
5656
/// sent to the receiver (`to`) after verifying a storage proof.
5757
/// @param deposit The ETH deposit
5858
/// @param height The `height` of the checkpoint on the source chain (i.e. the block number or commitmentId)
59-
/// @param accountProof Merkle proof for the contract's account against the state root
60-
/// @param storageProof Merkle proof for the derived storage slot against the account's storage root
61-
function claimDeposit(
62-
ETHDeposit memory deposit,
63-
uint256 height,
64-
bytes[] memory accountProof,
65-
bytes[] memory storageProof
66-
) external returns (bytes32 id);
59+
/// @param proof Encoded proof of the storage slot where the deposit is stored
60+
function claimDeposit(ETHDeposit memory deposit, uint256 height, bytes memory proof)
61+
external
62+
returns (bytes32 id);
6763
}

src/protocol/ISignalService.sol

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ pragma solidity ^0.8.28;
99
///
1010
/// Signals are broadcast without specific recipients, allowing flexible cross-chain messaging
1111
interface ISignalService {
12+
struct SignalProof {
13+
bytes[] accountProof;
14+
bytes[] storageProof;
15+
}
16+
1217
/// @dev Emitted when a signal is sent.
1318
/// @param sender The address that sent the signal on the source chain
1419
/// @param value The signal value
@@ -43,14 +48,6 @@ interface ISignalService {
4348
/// @param height This refers to the block number / commitmentId where the trusted root is mapped to
4449
/// @param sender The address that originally sent the signal on the source chain
4550
/// @param value The signal value to verify
46-
/// @param accountProof Merkle proof for the contract's account against the state root
47-
/// @param storageProof Merkle proof for the derived storage slot against the account's storage root
48-
function verifySignal(
49-
uint64 chainId,
50-
uint256 height,
51-
address sender,
52-
bytes32 value,
53-
bytes[] memory accountProof,
54-
bytes[] memory storageProof
55-
) external;
51+
/// @param proof The encoded value of the SignalProof struct
52+
function verifySignal(uint64 chainId, uint256 height, address sender, bytes32 value, bytes memory proof) external;
5653
}

src/protocol/SignalService.sol

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,8 @@ contract SignalService is ISignalService, ETHBridge, CommitmentStore {
3434
}
3535

3636
/// @inheritdoc ISignalService
37-
function verifySignal(
38-
uint64 chainId,
39-
uint256 height,
40-
address sender,
41-
bytes32 value,
42-
bytes[] memory accountProof,
43-
bytes[] memory storageProof
44-
) external {
45-
_verifySignal(chainId, height, sender, value, accountProof, storageProof);
37+
function verifySignal(uint64 chainId, uint256 height, address sender, bytes32 value, bytes memory proof) external {
38+
_verifySignal(chainId, height, sender, value, proof);
4639
emit SignalVerified(chainId, sender, value);
4740
}
4841

@@ -55,29 +48,40 @@ contract SignalService is ISignalService, ETHBridge, CommitmentStore {
5548
// CHECK: Should this function be non-reentrant?
5649
/// @inheritdoc ETHBridge
5750
/// @dev Overrides ETHBridge.claimDeposit to add signal verification logic.
58-
function claimDeposit(
59-
ETHDeposit memory deposit,
60-
uint256 height,
61-
bytes[] memory accountProof,
62-
bytes[] memory storageProof
63-
) external override returns (bytes32 id) {
51+
function claimDeposit(ETHDeposit memory deposit, uint256 height, bytes memory proof)
52+
external
53+
override
54+
returns (bytes32 id)
55+
{
6456
id = _generateId(deposit);
6557

66-
_verifySignal(deposit.chainId, height, deposit.from, id, accountProof, storageProof);
58+
_verifySignal(deposit.chainId, height, deposit.from, id, proof);
6759

6860
super._processClaimDepositWithId(id, deposit);
6961
}
7062

71-
function _verifySignal(
72-
uint64 chainId,
73-
uint256 height,
74-
address sender,
75-
bytes32 value,
76-
bytes[] memory accountProof,
77-
bytes[] memory storageProof
78-
) internal view {
63+
function _verifySignal(uint64 chainId, uint256 height, address sender, bytes32 value, bytes memory proof)
64+
internal
65+
view
66+
virtual
67+
{
68+
// TODO: commitmentAt(height) might not be the 'state root' of the chain
69+
// For now it could be the block hash or other hashed value
70+
// further work is needed to ensure we get the 'state root' of the chain
7971
bytes32 root = commitmentAt(height);
80-
bool valid = LibSignal.verifySignal(root, chainId, sender, value, accountProof, storageProof);
72+
73+
SignalProof memory signalProof = abi.decode(proof, (SignalProof));
74+
bytes[] memory accountProof = signalProof.accountProof;
75+
bytes[] memory storageProof = signalProof.storageProof;
76+
bool valid;
77+
// If the account proof is empty we assume `root` is the root of the signal tree
78+
if (accountProof.length == 0) {
79+
// Only verifies a state proof not full storage proof
80+
valid = LibSignal.verifySignal(root, chainId, sender, value, storageProof);
81+
require(valid, SignalNotReceived(chainId, value));
82+
return;
83+
}
84+
valid = LibSignal.verifySignal(root, chainId, sender, value, accountProof, storageProof);
8185
require(valid, SignalNotReceived(chainId, value));
8286
}
8387
}

0 commit comments

Comments
 (0)