Skip to content

Commit 4e393e3

Browse files
committed
docs: added NatSpecs for the bridge contracts, moved the events to the interface level
1 parent 388fe48 commit 4e393e3

File tree

7 files changed

+221
-74
lines changed

7 files changed

+221
-74
lines changed

contracts/deploy/02-home-chain.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
2222
: await hre.companionNetworks.foreign.deployments.get("FastBridgeReceiverOnEthereum");
2323
const fastBridgeSender = await deploy("FastBridgeSenderToEthereum", {
2424
from: deployer,
25-
args: [deployer, fastBridgeReceiver.address],
25+
args: [deployer, fastBridgeReceiver.address, ethers.constants.AddressZero],
2626
log: true,
2727
}); // nonce+0
2828

@@ -40,7 +40,7 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
4040

4141
const fastSender = await hre.ethers
4242
.getContractAt("FastBridgeSenderToEthereum", fastBridgeSender.address)
43-
.then((contract) => contract.fastSender());
43+
.then((contract) => contract.fastBridgeSender());
4444
if (fastSender === ethers.constants.AddressZero) {
4545
await execute("FastBridgeSenderToEthereum", { from: deployer, log: true }, "changeFastSender", homeGateway.address);
4646
}

contracts/src/bridge/FastBridgeReceiverOnEthereum.sol

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,22 @@ contract FastBridgeReceiverOnEthereum is SafeBridgeReceiverOnEthereum, IFastBrid
4747
// ************************************* //
4848

4949
uint256 public constant ONE_BASIS_POINT = 1e4; // One basis point, for scaling.
50-
uint256 public override claimDeposit;
51-
uint256 public override challengeDeposit;
52-
uint256 public override challengeDuration;
50+
uint256 public override claimDeposit; // The deposit required to submit a claim.
51+
uint256 public override challengeDeposit; // The deposit required to submit a challenge.
52+
uint256 public override challengeDuration; // The duration of the period allowing to challenge a claim.
5353
uint256 public override alpha; // Basis point of claim or challenge deposit that are lost when dishonest.
5454
mapping(uint256 => Ticket) public tickets; // The tickets by ticketID.
5555

56-
// ************************************* //
57-
// * Events * //
58-
// ************************************* //
59-
60-
event ClaimReceived(uint256 indexed _ticketID, bytes32 indexed messageHash, uint256 claimedAt);
61-
event ClaimChallenged(uint256 indexed _ticketID, bytes32 indexed _messageHash, uint256 challengedAt);
62-
56+
/**
57+
* @dev Constructor.
58+
* @param _governor The governor's address.
59+
* @param _safeBridgeSender The address of the Safe Bridge sender on Arbitrum.
60+
* @param _inbox The address of the Arbitrum Inbox contract.
61+
* @param _claimDeposit The deposit amount to submit a claim in wei.
62+
* @param _challengeDeposit The deposit amount to submit a challenge in wei.
63+
* @param _challengeDuration The duration of the period allowing to challenge a claim.
64+
* @param _alpha Basis point of claim or challenge deposit that are lost when dishonest.
65+
*/
6366
constructor(
6467
address _governor,
6568
address _safeBridgeSender,
@@ -79,6 +82,11 @@ contract FastBridgeReceiverOnEthereum is SafeBridgeReceiverOnEthereum, IFastBrid
7982
// * State Modifiers * //
8083
// ************************************* //
8184

85+
/**
86+
* @dev Submit a claim about the `messageHash` for a particular Fast Bridge `ticketID` and submit a deposit. The `messageHash` should match the one on the sending side otherwise the sender will lose his deposit.
87+
* @param _ticketID The ticket identifier referring to a message going through the bridge.
88+
* @param _messageHash The hash claimed for the ticket.
89+
*/
8290
function claim(uint256 _ticketID, bytes32 _messageHash) external payable override {
8391
Ticket storage ticket = tickets[_ticketID];
8492
require(ticket.claim.bridger == address(0), "Claim already made");
@@ -96,6 +104,10 @@ contract FastBridgeReceiverOnEthereum is SafeBridgeReceiverOnEthereum, IFastBrid
96104
emit ClaimReceived(_ticketID, _messageHash, block.timestamp);
97105
}
98106

107+
/**
108+
* @dev Submit a challenge for a particular Fast Bridge `ticketID` and submit a deposit. The `messageHash` in the claim already made for this `ticketID` should be different from the one on the sending side, otherwise the sender will lose his deposit.
109+
* @param _ticketID The ticket identifier referring to a message going through the bridge.
110+
*/
99111
function challenge(uint256 _ticketID) external payable override {
100112
Ticket storage ticket = tickets[_ticketID];
101113
require(ticket.claim.bridger != address(0), "Claim does not exist");
@@ -109,18 +121,24 @@ contract FastBridgeReceiverOnEthereum is SafeBridgeReceiverOnEthereum, IFastBrid
109121
challengeDeposit: msg.value
110122
});
111123

112-
emit ClaimChallenged(_ticketID, ticket.claim.messageHash, block.timestamp);
124+
emit ClaimChallenged(_ticketID, block.timestamp);
113125
}
114126

127+
/**
128+
* @dev Relay the message for this `ticketID` if the challenge period has passed and the claim is unchallenged. The hash computed over `messageData` and the other parameters must match the hash provided by the claim.
129+
* @param _ticketID The ticket identifier referring to a message going through the bridge.
130+
* @param _blockNumber The block number on the cross-domain chain when the message with this ticketID has been sent.
131+
* @param _messageData The data on the cross-domain chain for the message sent with this ticketID.
132+
*/
115133
function verifyAndRelay(
116134
uint256 _ticketID,
117-
uint256 blockNumber,
135+
uint256 _blockNumber,
118136
bytes calldata _messageData
119137
) external override {
120138
Ticket storage ticket = tickets[_ticketID];
121139
require(ticket.claim.bridger != address(0), "Claim does not exist");
122140
require(
123-
ticket.claim.messageHash == keccak256(abi.encode(_ticketID, blockNumber, _messageData)),
141+
ticket.claim.messageHash == keccak256(abi.encode(_ticketID, _blockNumber, _messageData)),
124142
"Invalid hash"
125143
);
126144
require(ticket.claim.claimedAt + challengeDuration < block.timestamp, "Challenge period not over");
@@ -132,9 +150,16 @@ contract FastBridgeReceiverOnEthereum is SafeBridgeReceiverOnEthereum, IFastBrid
132150
require(_relay(_messageData), "Failed to call contract"); // Checks-Effects-Interaction
133151
}
134152

153+
/**
154+
* Note: Access restricted to the Safe Bridge.
155+
* @dev Relay the message for this `ticketID` as provided by the Safe Bridge. Resolve a challenged claim for this `ticketID` if any.
156+
* @param _ticketID The ticket identifier referring to a message going through the bridge.
157+
* @param _blockNumber The block number on the cross-domain chain when the message with this ticketID has been sent.
158+
* @param _messageData The data on the cross-domain chain for the message sent with this ticketID.
159+
*/
135160
function verifyAndRelaySafe(
136161
uint256 _ticketID,
137-
uint256 blockNumber,
162+
uint256 _blockNumber,
138163
bytes calldata _messageData
139164
) external override {
140165
require(isSentBySafeBridge(), "Access not allowed: SafeBridgeSender only.");
@@ -143,7 +168,7 @@ contract FastBridgeReceiverOnEthereum is SafeBridgeReceiverOnEthereum, IFastBrid
143168
require(ticket.relayed == false, "Message already relayed");
144169

145170
// Claim assessment if any
146-
bytes32 messageHash = keccak256(abi.encode(_ticketID, blockNumber, _messageData));
171+
bytes32 messageHash = keccak256(abi.encode(_ticketID, _blockNumber, _messageData));
147172
if (ticket.claim.bridger != address(0) && ticket.claim.messageHash == messageHash) {
148173
ticket.claim.verified = true;
149174
}
@@ -152,6 +177,10 @@ contract FastBridgeReceiverOnEthereum is SafeBridgeReceiverOnEthereum, IFastBrid
152177
require(_relay(_messageData), "Failed to call contract"); // Checks-Effects-Interaction
153178
}
154179

180+
/**
181+
* @dev Sends the deposit back to the Bridger if his claim is not successfully challenged. Includes a portion of the Challenger's deposit if unsuccessfully challenged.
182+
* @param _ticketID The ticket identifier referring to a message going through the bridge.
183+
*/
155184
function withdrawClaimDeposit(uint256 _ticketID) external override {
156185
Ticket storage ticket = tickets[_ticketID];
157186
require(ticket.relayed == true, "Message not relayed yet");
@@ -165,6 +194,10 @@ contract FastBridgeReceiverOnEthereum is SafeBridgeReceiverOnEthereum, IFastBrid
165194
// Checks-Effects-Interaction
166195
}
167196

197+
/**
198+
* @dev Sends the deposit back to the Challenger if his challenge is successful. Includes a portion of the Bridger's deposit.
199+
* @param _ticketID The ticket identifier referring to a message going through the bridge.
200+
*/
168201
function withdrawChallengeDeposit(uint256 _ticketID) external override {
169202
Ticket storage ticket = tickets[_ticketID];
170203
require(ticket.relayed == true, "Message not relayed");
@@ -182,7 +215,12 @@ contract FastBridgeReceiverOnEthereum is SafeBridgeReceiverOnEthereum, IFastBrid
182215
// * Public Views * //
183216
// ************************************* //
184217

185-
function challengePeriod(uint256 _ticketID) public view returns (uint256 start, uint256 end) {
218+
/**
219+
* @dev Returns the `start` and `end` time of challenge period for this `ticketID`.
220+
* @return start The start time of the challenge period.
221+
* @return end The end time of the challenge period.
222+
*/
223+
function challengePeriod(uint256 _ticketID) external view override returns (uint256 start, uint256 end) {
186224
Ticket storage ticket = tickets[_ticketID];
187225
require(ticket.claim.bridger != address(0), "Claim does not exist");
188226

contracts/src/bridge/FastBridgeSenderToEthereum.sol

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -33,28 +33,12 @@ contract FastBridgeSenderToEthereum is SafeBridgeSenderToEthereum, IFastBridgeSe
3333
// * Storage * //
3434
// ************************************* //
3535

36-
address public governor;
37-
IFastBridgeReceiver public fastBridgeReceiver;
38-
address public fastSender;
36+
address public governor; // The governor of the contract.
37+
IFastBridgeReceiver public fastBridgeReceiver; // The address of the Fast Bridge on Ethereum.
38+
address public fastBridgeSender; // The address of the Fast Bridge sender on Arbitrum, generally the Home Gateway.
3939
uint256 public currentTicketID = 1; // Zero means not set, start at 1.
4040
mapping(uint256 => Ticket) public tickets; // The tickets by ticketID.
4141

42-
// ************************************* //
43-
// * Events * //
44-
// ************************************* //
45-
46-
/**
47-
* The bridgers need to watch for these events and
48-
* relay the messageHash on the FastBridgeReceiverOnEthereum.
49-
*/
50-
event OutgoingMessage(
51-
uint256 indexed ticketID,
52-
uint256 blockNumber,
53-
address target,
54-
bytes32 indexed messageHash,
55-
bytes message
56-
);
57-
5842
// ************************************* //
5943
// * Function Modifiers * //
6044
// ************************************* //
@@ -64,25 +48,35 @@ contract FastBridgeSenderToEthereum is SafeBridgeSenderToEthereum, IFastBridgeSe
6448
_;
6549
}
6650

67-
constructor(address _governor, IFastBridgeReceiver _fastBridgeReceiver) SafeBridgeSenderToEthereum() {
51+
/**
52+
* @dev Constructor.
53+
* @param _governor The governor's address.
54+
* @param _fastBridgeReceiver The address of the Fast Bridge on Ethereum.
55+
* @param _fastBridgeSender The address of the Fast Bridge sender on Arbitrum, generally the Home Gateway.
56+
*/
57+
constructor(
58+
address _governor,
59+
IFastBridgeReceiver _fastBridgeReceiver,
60+
address _fastBridgeSender
61+
) SafeBridgeSenderToEthereum() {
6862
governor = _governor;
6963
fastBridgeReceiver = _fastBridgeReceiver;
64+
fastBridgeSender = _fastBridgeSender;
7065
}
7166

7267
// ************************************* //
7368
// * State Modifiers * //
7469
// ************************************* //
7570

7671
/**
77-
* Sends an arbitrary message from one domain to another
78-
* via the fast bridge mechanism
79-
*
80-
* @param _receiver The L1 contract address who will receive the calldata
72+
* Note: Access restricted to the `fastSender`, generally the Gateway.
73+
* @dev Sends an arbitrary message to Ethereum using the Fast Bridge.
74+
* @param _receiver The address of the contract on Ethereum which receives the calldata.
8175
* @param _calldata The receiving domain encoded message data.
82-
* @return ticketID The identifier to provide to sendSafeFallback()
76+
* @return ticketID The identifier to provide to sendSafeFallback().
8377
*/
8478
function sendFast(address _receiver, bytes memory _calldata) external override returns (uint256 ticketID) {
85-
require(msg.sender == fastSender, "Access not allowed: Fast Sender only.");
79+
require(msg.sender == fastBridgeSender, "Access not allowed: Fast Sender only.");
8680

8781
ticketID = currentTicketID++;
8882

@@ -93,25 +87,17 @@ contract FastBridgeSenderToEthereum is SafeBridgeSenderToEthereum, IFastBridgeSe
9387
}
9488

9589
/**
96-
* Sends an arbitrary message from one domain to another
97-
* via the safe bridge mechanism, which relies on the chain's native bridge.
98-
*
99-
* It is unnecessary during normal operations but essential only in case of challenge.
100-
*
101-
* It may require some ETH (or whichever native token) to pay for the bridging cost,
102-
* depending on the underlying safe bridge.
103-
*
104-
* TODO: check if keeping _calldata in storage in sendFast() is cheaper than passing it again as a parameter here
105-
*
106-
* @param _ticketID The ticketID as provided by `sendFast()` if any.
107-
* @param _receiver The L1 contract address who will receive the calldata
90+
* @dev Sends an arbitrary message to Ethereum using the Safe Bridge, which relies on Arbitrum's canonical bridge. It is unnecessary during normal operations but essential only in case of challenge.
91+
* @param _ticketID The ticketID as returned by `sendFast()`.
92+
* @param _receiver The address of the contract on Ethereum which receives the calldata.
10893
* @param _calldata The receiving domain encoded message data.
10994
*/
11095
function sendSafeFallback(
11196
uint256 _ticketID,
11297
address _receiver,
11398
bytes memory _calldata
11499
) external payable override {
100+
// TODO: check if keeping _calldata in storage in sendFast() is cheaper than passing it again as a parameter here
115101
Ticket storage ticket = tickets[_ticketID];
116102
require(ticket.messageHash != 0, "Ticket does not exist.");
117103
require(ticket.sentSafe == false, "Ticket already sent safely.");
@@ -136,9 +122,8 @@ contract FastBridgeSenderToEthereum is SafeBridgeSenderToEthereum, IFastBridgeSe
136122
// * Governance * //
137123
// ************************ //
138124

139-
function changeFastSender(address _fastSender) external onlyByGovernor {
140-
require(fastSender == address(0));
141-
fastSender = _fastSender;
125+
function changeFastSender(address _fastBridgeSender) external onlyByGovernor {
126+
fastBridgeSender = _fastBridgeSender;
142127
}
143128

144129
// ************************ //

contracts/src/bridge/SafeBridgeReceiverOnEthereum.sol

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ contract SafeBridgeReceiverOnEthereum is ISafeBridgeReceiver {
2323
// * Storage * //
2424
// ************************************* //
2525

26-
address public governor;
27-
address public safeBridgeSender;
28-
IInbox public inbox;
26+
address public governor; // The governor of the contract.
27+
address public safeBridgeSender; // The address of the Safe Bridge sender on Arbitrum.
28+
IInbox public inbox; // The address of the Arbitrum Inbox contract.
2929

3030
// ************************************* //
3131
// * Function Modifiers * //
@@ -36,6 +36,12 @@ contract SafeBridgeReceiverOnEthereum is ISafeBridgeReceiver {
3636
_;
3737
}
3838

39+
/**
40+
* @dev Constructor.
41+
* @param _governor The governor's address.
42+
* @param _safeBridgeSender The address of the Safe Bridge sender on Arbitrum.
43+
* @param _inbox The address of the Arbitrum Inbox contract.
44+
*/
3945
constructor(
4046
address _governor,
4147
address _safeBridgeSender,

contracts/src/bridge/SafeBridgeSenderToEthereum.sol

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,22 @@ import "./interfaces/ISafeBridgeSender.sol";
2020
* Counterpart of `SafeBridgeReceiverOnEthereum`
2121
*/
2222
contract SafeBridgeSenderToEthereum is ISafeBridgeSender {
23-
IArbSys public constant ARB_SYS = IArbSys(address(100));
23+
// ************************************* //
24+
// * Events * //
25+
// ************************************* //
2426

2527
event L2ToL1TxCreated(uint256 indexed withdrawalId);
2628

29+
// ************************************* //
30+
// * Storage * //
31+
// ************************************* //
32+
33+
IArbSys public constant ARB_SYS = IArbSys(address(100));
34+
35+
// ************************************* //
36+
// * Function Modifiers * //
37+
// ************************************* //
38+
2739
function _sendSafe(address _receiver, bytes memory _calldata) internal override returns (uint256) {
2840
uint256 withdrawalId = ARB_SYS.sendTxToL1(_receiver, _calldata);
2941

0 commit comments

Comments
 (0)