Skip to content

Commit d7da73f

Browse files
committed
remove root as a param
simplify comment updated event explain root
1 parent ba82fcc commit d7da73f

File tree

7 files changed

+69
-68
lines changed

7 files changed

+69
-68
lines changed

src/libs/LibSignal.sol

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ library LibSignal {
4242

4343
/// @dev Signal a `value` at a namespaced slot for the current `block.chainid`.
4444
function signal(address account, bytes32 value) internal returns (bytes32) {
45-
return signal(block.chainid.toUint64(), account, value);
45+
return signal(uint64(block.chainid), account, value);
4646
}
4747

4848
/// @dev Signal a `value` at a namespaced slot. See `deriveSlot`.
@@ -59,25 +59,33 @@ library LibSignal {
5959

6060
/// @dev Returns the storage slot for a signal. Namespaced to the current `block.chainid`.
6161
function deriveSlot(address account, bytes32 value) internal view returns (bytes32) {
62-
return deriveSlot(block.chainid.toUint64(), account, value);
62+
return deriveSlot(uint64(block.chainid), account, value);
6363
}
6464

6565
/// @dev Returns the storage slot for a signal.
6666
function deriveSlot(uint64 chainId, address account, bytes32 value) internal pure returns (bytes32) {
6767
return string(abi.encodePacked(chainId, account, value)).erc7201Slot();
6868
}
6969

70-
/// @dev Performs a storage proof on the `account`. User must ensure the `root` is trusted for the given `chainId`.
70+
/// @dev Performs a storage proof verification for a signal stored on the contract using this library
71+
/// @param root The state root from the source chain to verify against
72+
/// @param chainId The chain ID of the source chain where the signal was sent
73+
/// @param sender The address that originally sent the signal on the source chain
74+
/// @param value The signal value to verify
75+
/// @param accountProof Merkle proof for the contract's account against the state root
76+
/// @param storageProof Merkle proof for the derived storage slot against the account's storage root
77+
/// @return valid Boolean indicating whether the signal was successfully verified
78+
/// @return storageRoot The storage root of the account from the proof
7179
function verifySignal(
72-
address account,
7380
bytes32 root,
7481
uint64 chainId,
82+
address sender,
7583
bytes32 value,
7684
bytes[] memory accountProof,
7785
bytes[] memory storageProof
78-
) internal pure returns (bool valid, bytes32 storageRoot) {
86+
) internal view returns (bool valid, bytes32 storageRoot) {
7987
return LibTrieProof.verifyStorage(
80-
account, deriveSlot(chainId, account, value), value, root, accountProof, storageProof
88+
address(this), deriveSlot(chainId, sender, value), value, root, accountProof, storageProof
8189
);
8290
}
8391
}

src/protocol/CheckpointSyncer.sol

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ import {ICheckpointTracker} from "./ICheckpointTracker.sol";
66

77
/// @dev Tracks and synchronizes checkpoints from different chains using their chainId.
88
abstract contract CheckpointSyncer is ICheckpointSyncer {
9-
address private immutable checkpointTracker;
9+
address private immutable _checkpointTracker;
1010

1111
/// @dev Sets the checkpoint tracker.
12-
constructor(address _checkpointTracker) {
13-
_checkpointTracker = checkpointTracker;
12+
constructor(address checkpointTracker_) {
13+
checkpointTracker_ = _checkpointTracker;
14+
}
15+
16+
function checkpointTracker() public view returns (address) {
17+
return _checkpointTracker;
1418
}
1519

1620
/// @inheritdoc ICheckpointSyncer
@@ -29,7 +33,7 @@ abstract contract CheckpointSyncer is ICheckpointSyncer {
2933
virtual
3034
returns (bytes32 id)
3135
{
32-
require(msg.sender == checkpointTracker, UnauthorizedCheckpointTracker());
36+
require(msg.sender == checkpointTracker(), UnauthorizedCheckpointTracker());
3337
id = getCheckpointId(checkpoint, chainId);
3438
emit CheckpointSynced(checkpoint, chainId);
3539
}
@@ -38,9 +42,8 @@ abstract contract CheckpointSyncer is ICheckpointSyncer {
3842
function verifyCheckpoint(
3943
ICheckpointTracker.Checkpoint memory checkpoint,
4044
uint64 chainId,
41-
bytes32 root,
4245
bytes[] memory accountProof,
43-
bytes[] memory proof
46+
bytes[] memory storageProof
4447
) public view virtual returns (bytes32 id);
4548

4649
function _generateId(ICheckpointTracker.Checkpoint memory checkpoint, uint64 chainId)

src/protocol/ETHBridge.sol

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,10 @@ abstract contract ETHBridge is IETHBridge {
3838
}
3939

4040
/// @inheritdoc IETHBridge
41-
function claimDeposit(
42-
ETHDeposit memory deposit,
43-
bytes32 root,
44-
bytes[] memory accountProof,
45-
bytes[] memory stateProof
46-
) external virtual returns (bytes32 id);
41+
function claimDeposit(ETHDeposit memory deposit, bytes[] memory accountProof, bytes[] memory storageRoot)
42+
external
43+
virtual
44+
returns (bytes32 id);
4745

4846
/// @dev Function to transfer ETH to the receiver but ignoring the returndata.
4947
/// @param to Address to send the ETH to

src/protocol/ICheckpointSyncer.sol

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,11 @@ interface ICheckpointSyncer {
2727
external
2828
returns (bytes32 id);
2929

30-
/// @dev Verifies that a `checkpoint` is valid for the provided `chainId`, `height` and `root`.
31-
/// The `root` MUST be trusted.
30+
/// @dev Verifies that a `checkpoint` has been signaled on the destchain.
3231
function verifyCheckpoint(
3332
ICheckpointTracker.Checkpoint memory checkpoint,
3433
uint64 chainId,
35-
bytes32 root,
3634
bytes[] memory accountProof,
37-
bytes[] memory proof
35+
bytes[] memory storageProof
3836
) external view returns (bytes32 id);
3937
}

src/protocol/IETHBridge.sol

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,9 @@ interface IETHBridge {
5555
/// @dev Claims an ETH deposit created on `chainId` by the sender (`from`) with `nonce`. The `value` ETH claimed is
5656
/// sent to the receiver (`to`) after verifying a storage proof.
5757
/// @param deposit The ETH deposit
58-
/// @param root The state root
59-
/// @param accountProof Merkle proof for account state against global stateRoot
60-
/// @param stateProof Merkle proof for slot value against account's storageRoot
61-
function claimDeposit(
62-
ETHDeposit memory deposit,
63-
bytes32 root,
64-
bytes[] memory accountProof,
65-
bytes[] memory stateProof
66-
) external returns (bytes32 id);
58+
/// @param accountProof Merkle proof for the contract's account against the state root
59+
/// @param storageProof Merkle proof for the derived storage slot against the account's storage root
60+
function claimDeposit(ETHDeposit memory deposit, bytes[] memory accountProof, bytes[] memory storageProof)
61+
external
62+
returns (bytes32 id);
6763
}

src/protocol/ISignalService.sol

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,46 +7,43 @@ pragma solidity ^0.8.28;
77
/// Signals enable generalized on-chain communication, primarily for data transmission rather than value transfer.
88
/// Applications can leverage signals to transfer value through secondary implementations.
99
///
10-
/// Signals are broadcast without specific recipients, allowing flexible cross-chain data sourcing from any
11-
/// source chain state (e.g., full transaction logs or contract storage).
10+
/// Signals are broadcast without specific recipients, allowing flexible cross-chain messaging
1211
interface ISignalService {
1312
/// @dev Emitted when a signal is sent.
14-
/// @param signal Signal value that was stored
15-
event SignalSent(bytes32 signal);
13+
/// @param chainId The chain ID of the source chain where the signal was sent
14+
/// @param sender The address that sent the signal on the source chain
15+
/// @param value The signal value
16+
event SignalSent(address sender, uint256 chainId, bytes32 value);
1617

1718
/// @dev Emitted when a signal is verified.
19+
/// @param chainId The chain ID of the source chain where the signal was sent
1820
/// @param value Value that was signaled
19-
/// @param chainId Chain ID where the signal was sent to
20-
/// @param root TODO: check this
21-
event SignalVerified(bytes32 value, uint64 chainId, bytes32 root);
21+
event SignalVerified(uint64 chainId, address sender, bytes32 value);
2222

2323
/// @dev Error when a signal fails to be verified.
2424
/// @param value Value that was not verified
25-
error SignalNotReceived(bytes32 value, bytes32 root);
25+
error SignalNotReceived(bytes32 value);
2626

2727
/// @dev Stores a data signal and returns its storage location.
2828
/// @param value Data to be stored (signalled)
2929
function sendSignal(bytes32 value) external returns (bytes32 slot);
3030

3131
/// @dev Checks if a signal has been stored
32-
/// @dev Note: This does not mean it has been 'sent' to destination chain, only that it has been stored on the
33-
/// source chain.
32+
/// @dev Note: This does not mean it has been 'sent' to destination chain,
33+
/// only that it has been stored on the source chain.
3434
/// @param value Value to be checked is stored
35-
// @param sender The address that sent the signal
35+
/// @param sender The address that sent the signal
3636
function isSignalStored(bytes32 value, address sender) external view returns (bool);
3737

3838
/// @dev Verifies if the signal can be proved to be part of a merkle tree
39-
/// defined by `root` for the specified signal service storage.
40-
/// @param root TODO: check this
41-
/// @param chainId Chain ID where the signal was sent to
42-
/// @param value Value to be verified
43-
/// @param accountProof Merkle proof for account state against global stateRoot
44-
/// @param stateProof Merkle proof for slot value against account's storageRoot
39+
/// @dev Signals are not deleted when verified, and can be
40+
/// verified multiple times by calling this function
41+
/// @dev see `LibSignal.verifySignal`
4542
function verifySignal(
46-
bytes32 root,
4743
uint64 chainId,
44+
address sender,
4845
bytes32 value,
4946
bytes[] memory accountProof,
50-
bytes[] memory stateProof
47+
bytes[] memory storageProof
5148
) external;
5249
}

src/protocol/taiko_alethia/SignalService.sol

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,35 @@ import {ISignalService} from "../ISignalService.sol";
1212
///
1313
/// The service defines the minimal logic to broadcast signals through `sendSignal` and verify them with
1414
/// `verifySignal`. The service is designed to be used in conjunction with the `ETHBridge` contract to
15-
/// enable cross-chain communication.
15+
/// enable cross-chain communication and the CheckpointSyncer to retrieve trusted state roots.
1616
contract SignalService is ISignalService, ETHBridge, CheckpointSyncer {
1717
using LibSignal for bytes32;
1818

1919
constructor(address _checkpointTracker) CheckpointSyncer(_checkpointTracker) {}
2020

2121
/// @inheritdoc ISignalService
22-
function sendSignal(bytes32 value) external returns (bytes32 signal) {
23-
signal = value.signal();
24-
emit SignalSent(signal);
22+
function sendSignal(bytes32 value) external returns (bytes32 slot) {
23+
slot = value.signal();
24+
emit SignalSent(msg.sender, block.chainid, value);
2525
}
2626

2727
/// @inheritdoc ISignalService
2828
function isSignalStored(bytes32 value, address sender) external view returns (bool) {
2929
// This will return `false` when the signal itself is 0
30-
return value.signaled(sender);
30+
return LibSignal.signaled(sender, value);
3131
}
3232

3333
/// @inheritdoc ISignalService
3434
function verifySignal(
35-
bytes32 root,
3635
uint64 chainId,
36+
address sender,
3737
bytes32 value,
3838
bytes[] memory accountProof,
3939
bytes[] memory storageProof
4040
) external {
41-
// TODO: Get the root from the trusted source
42-
_verifySignal(root, chainId, value, accountProof, storageProof);
41+
_verifySignal(chainId, sender, value, accountProof, storageProof);
4342

44-
emit SignalVerified(value, chainId, root);
43+
emit SignalVerified(chainId, sender, value);
4544
}
4645

4746
/// @dev Overrides ETHBridge.depositETH to add signaling functionality.
@@ -53,14 +52,14 @@ contract SignalService is ISignalService, ETHBridge, CheckpointSyncer {
5352
// CHECK: Should this function be non-reentrant?
5453
/// @inheritdoc ETHBridge
5554
/// @dev Overrides ETHBridge.claimDeposit to add signal verification logic.
56-
function claimDeposit(ETHDeposit memory deposit, bytes32 root, bytes[] memory accountProof, bytes[] memory proof)
55+
function claimDeposit(ETHDeposit memory deposit, bytes[] memory accountProof, bytes[] memory storageProof)
5756
external
5857
override
5958
returns (bytes32 id)
6059
{
6160
id = _generateId(deposit);
6261

63-
_verifySignal(root, deposit.chainId, id, accountProof, proof);
62+
_verifySignal(deposit.chainId, deposit.from, id, accountProof, storageProof);
6463

6564
super._processClaimDepositWithId(id, deposit);
6665
}
@@ -77,22 +76,24 @@ contract SignalService is ISignalService, ETHBridge, CheckpointSyncer {
7776
function verifyCheckpoint(
7877
ICheckpointTracker.Checkpoint memory checkpoint,
7978
uint64 chainId,
80-
bytes32 root,
8179
bytes[] memory accountProof,
82-
bytes[] memory proof
80+
bytes[] memory storageProof
8381
) public view override returns (bytes32 id) {
8482
id = getCheckpointId(checkpoint, chainId);
85-
_verifySignal(root, chainId, id, accountProof, proof);
83+
84+
_verifySignal(chainId, checkpointTracker(), id, accountProof, storageProof);
8685
}
8786

8887
function _verifySignal(
89-
bytes32 root,
9088
uint64 chainId,
89+
address sender,
9190
bytes32 value,
9291
bytes[] memory accountProof,
93-
bytes[] memory stateProof
92+
bytes[] memory storageProof
9493
) internal view {
95-
(bool valid,) = LibSignal.verifySignal(address(this), root, chainId, value, accountProof, stateProof);
96-
require(valid, SignalNotReceived(value, root));
94+
// WARN: THIS IS NOT THE ROOT ITS JUST A PLACE HOLDER
95+
bytes32 root = keccak256("root");
96+
(bool valid,) = LibSignal.verifySignal(root, chainId, sender, value, accountProof, storageProof);
97+
require(valid, SignalNotReceived(value));
9798
}
9899
}

0 commit comments

Comments
 (0)