@@ -5,14 +5,11 @@ import {IETHBridge} from "./IETHBridge.sol";
55import {ISignalService} from "./ISignalService.sol " ;
66import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol " ;
77
8- /// @dev ETH bridging contract to send native ETH between L1 <-> L2 using storage proofs.
9- /// @dev In contracts to the `SignalService`, this contract does not expect the bridge to be deployed on the same
8+ /// @dev In contrast to the `SignalService`, this contract does not expect the bridge to be deployed on the same
109/// address on both chains. This is because it is designed so that each rollup has its own independent bridge contract,
1110/// and they may furthermore decide to deploy a new version of the bridge in the future.
12- ///
13- /// IMPORTANT: No recovery mechanism is implemented in case an account creates a deposit that can't be claimed.
1411contract ETHBridge is IETHBridge , ReentrancyGuardTransient {
15- mapping (bytes32 id = > bool claimed ) private _claimed ;
12+ mapping (bytes32 id = > bool processed ) private _processed ;
1613
1714 /// Incremental nonce to generate unique deposit IDs.
1815 uint256 private _globalDepositNonce;
@@ -39,8 +36,8 @@ contract ETHBridge is IETHBridge, ReentrancyGuardTransient {
3936 }
4037
4138 /// @inheritdoc IETHBridge
42- function claimed (bytes32 id ) public view returns (bool ) {
43- return _claimed [id];
39+ function processed (bytes32 id ) public view returns (bool ) {
40+ return _processed [id];
4441 }
4542
4643 /// @inheritdoc IETHBridge
@@ -49,8 +46,13 @@ contract ETHBridge is IETHBridge, ReentrancyGuardTransient {
4946 }
5047
5148 /// @inheritdoc IETHBridge
52- function deposit (address to , bytes memory data , bytes memory context ) public payable returns (bytes32 id ) {
53- ETHDeposit memory ethDeposit = ETHDeposit (_globalDepositNonce, msg .sender , to, msg .value , data, context);
49+ function deposit (address to , bytes memory data , bytes memory context , address canceler )
50+ public
51+ payable
52+ returns (bytes32 id )
53+ {
54+ ETHDeposit memory ethDeposit =
55+ ETHDeposit (_globalDepositNonce, msg .sender , to, msg .value , data, context, canceler);
5456 id = _generateId (ethDeposit);
5557 unchecked {
5658 ++ _globalDepositNonce;
@@ -62,15 +64,36 @@ contract ETHBridge is IETHBridge, ReentrancyGuardTransient {
6264
6365 /// @inheritdoc IETHBridge
6466 function claimDeposit (ETHDeposit memory ethDeposit , uint256 height , bytes memory proof ) external nonReentrant {
65- bytes32 id = _generateId (ethDeposit);
66- require (! claimed (id), AlreadyClaimed ());
67+ bytes32 id = _claimDeposit (ethDeposit, ethDeposit.to, ethDeposit.data, height, proof);
68+ emit DepositClaimed (id, ethDeposit);
69+ }
6770
68- signalService.verifySignal (height, trustedCommitmentPublisher, counterpart, id, proof);
71+ /// @inheritdoc IETHBridge
72+ function cancelDeposit (ETHDeposit memory ethDeposit , address claimee , uint256 height , bytes memory proof )
73+ external
74+ nonReentrant
75+ {
76+ require (msg .sender == ethDeposit.canceler, OnlyCanceler ());
6977
70- _claimed[id] = true ;
71- _sendETH (ethDeposit.to, ethDeposit.amount, ethDeposit.data);
78+ bytes32 id = _claimDeposit (ethDeposit, claimee, bytes ("" ), height, proof);
7279
73- emit DepositClaimed (id, ethDeposit);
80+ emit DepositCancelled (id, claimee);
81+ }
82+
83+ function _claimDeposit (
84+ ETHDeposit memory ethDeposit ,
85+ address to ,
86+ bytes memory data ,
87+ uint256 height ,
88+ bytes memory proof
89+ ) internal returns (bytes32 id ) {
90+ id = _generateId (ethDeposit);
91+ require (! processed (id), AlreadyClaimed ());
92+
93+ signalService.verifySignal (height, trustedCommitmentPublisher, counterpart, id, proof);
94+
95+ _processed[id] = true ;
96+ _sendETH (to, ethDeposit.amount, data);
7497 }
7598
7699 /// @dev Function to transfer ETH to the receiver but ignoring the returndata.
0 commit comments