Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0d50179

Browse files
committedFeb 2, 2023
fix: revert focused on the bad variable rename only
1 parent 2e6970a commit 0d50179

File tree

2 files changed

+7
-302
lines changed

2 files changed

+7
-302
lines changed
 

‎contracts/src/FastBridgeReceiverOnEthereum.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22

33
/**
4-
* @authors: [@jaybuidl, @shotaronowhere, @hrishibhat]
4+
* @authors: [@jaybuidl, @shotaronowhere, @hrishibhat, @adi274]
55
* @reviewers: []
66
* @auditors: []
77
* @bounties: []
@@ -36,9 +36,9 @@ contract FastBridgeReceiverOnEthereum is IFastBridgeReceiver, ISafeBridgeReceive
3636
// * Views * //
3737
// ************************************* //
3838

39-
function isSentBySafeBridge() internal view override returns (bool) {
39+
function isSentBySafeBridge() internal view virtual override returns (bool) {
4040
IOutbox outbox = IOutbox(inbox.bridge().activeOutbox());
41-
return outbox.l2ToL1Sender() == safeBridgeSender;
41+
return msg.sender == address(outbox) && outbox.l2ToL1Sender() == safeBridgeSender;
4242
}
4343

4444
/**
+4-299
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22

33
/**
4-
* @authors: [@jaybuidl, @shotaronowhere, @hrishibhat]
4+
* @authors: [@jaybuidl, @shotaronowhere, @hrishibhat, @adi274]
55
* @reviewers: []
66
* @auditors: []
77
* @bounties: []
@@ -10,28 +10,19 @@
1010

1111
pragma solidity ^0.8.0;
1212

13-
import "../interfaces/IFastBridgeReceiver.sol";
14-
import "../interfaces/ISafeBridgeReceiver.sol";
15-
import "../canonical/arbitrum/IInbox.sol";
16-
import "../canonical/arbitrum/IOutbox.sol";
13+
import "../FastBridgeReceiverOnEthereum.sol";
1714

1815
/**
1916
* Fast Receiver On Ethereum
2017
* Counterpart of `FastSenderFromArbitrum`
2118
*/
22-
contract FastBridgeReceiverOnEthereumMock is IFastBridgeReceiver, ISafeBridgeReceiver {
19+
contract FastBridgeReceiverOnEthereumMock is FastBridgeReceiverOnEthereum {
2320
// **************************************** //
2421
// * * //
2522
// * Ethereum Receiver Specific * //
2623
// * * //
2724
// **************************************** //
2825

29-
// ************************************* //
30-
// * Storage * //
31-
// ************************************* //
32-
33-
IInbox public immutable inbox; // The address of the Arbitrum Inbox contract.
34-
3526
// ************************************* //
3627
// * Views * //
3728
// ************************************* //
@@ -55,291 +46,5 @@ contract FastBridgeReceiverOnEthereumMock is IFastBridgeReceiver, ISafeBridgeRec
5546
uint256 _challengePeriod,
5647
address _safeBridgeSender,
5748
address _inbox // Ethereum receiver specific
58-
) {
59-
deposit = _deposit;
60-
epochPeriod = _epochPeriod;
61-
challengePeriod = _challengePeriod;
62-
safeBridgeSender = _safeBridgeSender;
63-
inbox = IInbox(_inbox); // Ethereum receiver specific
64-
}
65-
66-
// ************************************** //
67-
// * * //
68-
// * General Receiver * //
69-
// * * //
70-
// ************************************** //
71-
72-
// ************************************* //
73-
// * Enums / Structs * //
74-
// ************************************* //
75-
76-
struct Claim {
77-
bytes32 batchMerkleRoot;
78-
address bridger;
79-
uint32 timestamp;
80-
bool honest;
81-
bool verificationAttempted;
82-
bool depositAndRewardWithdrawn;
83-
}
84-
85-
struct Challenge {
86-
address challenger;
87-
bool honest;
88-
bool depositAndRewardWithdrawn;
89-
}
90-
91-
// ************************************* //
92-
// * Storage * //
93-
// ************************************* //
94-
95-
uint256 public immutable deposit; // The deposit required to submit a claim or challenge
96-
uint256 public immutable override epochPeriod; // Epochs mark the period between potential batches of messages.
97-
uint256 public immutable override challengePeriod; // Epochs mark the period between potential batches of messages.
98-
address public immutable safeBridgeSender; // The address of the Safe Bridge Sender on the connecting chain.
99-
100-
mapping(uint256 => bytes32) public fastInbox; // epoch => validated batch merkle root(optimistically, or challenged and verified with the safe bridge)
101-
mapping(uint256 => Claim) public claims; // epoch => claim
102-
mapping(uint256 => Challenge) public challenges; // epoch => challenge
103-
mapping(uint256 => mapping(uint256 => bytes32)) public relayed; // epoch => packed replay bitmap
104-
105-
// ************************************* //
106-
// * State Modifiers * //
107-
// ************************************* //
108-
109-
/**
110-
* @dev Submit a claim about the `_batchMerkleRoot` for the last completed epoch from the Fast Bridge and submit a deposit. The `_batchMerkleRoot` should match the one on the sending side otherwise the sender will lose his deposit.
111-
* @param _epoch The epoch in which the batch to claim.
112-
* @param _batchMerkleRoot The batch merkle root claimed for the last completed epoch.
113-
*/
114-
function claim(uint256 _epoch, bytes32 _batchMerkleRoot) external payable override {
115-
require(msg.value >= deposit, "Insufficient claim deposit.");
116-
require(_batchMerkleRoot != bytes32(0), "Invalid claim.");
117-
118-
uint256 epochNow = block.timestamp / epochPeriod;
119-
// allow claim about current or previous epoch
120-
require(_epoch == epochNow || _epoch == epochNow - 1, "Invalid epoch.");
121-
require(claims[_epoch].bridger == address(0), "Claim already made for most recent finalized epoch.");
122-
123-
claims[_epoch] = Claim({
124-
batchMerkleRoot: _batchMerkleRoot,
125-
bridger: msg.sender,
126-
timestamp: uint32(block.timestamp),
127-
honest: false,
128-
verificationAttempted: false,
129-
depositAndRewardWithdrawn: false
130-
});
131-
emit ClaimReceived(_epoch, _batchMerkleRoot);
132-
}
133-
134-
/**
135-
* @dev Submit a challenge for the claim of the current epoch's Fast Bridge batch merkleroot state and submit a deposit. The `batchMerkleRoot` in the claim already made for the last finalized epoch should be different from the one on the sending side, otherwise the sender will lose his deposit.
136-
* @param _epoch The epoch of the claim to challenge.
137-
*/
138-
function challenge(uint256 _epoch) external payable override {
139-
require(msg.value >= deposit, "Not enough claim deposit");
140-
141-
// Can only challenge the only active claim, about the previous epoch
142-
require(claims[_epoch].bridger != address(0), "No claim to challenge.");
143-
require(block.timestamp < uint256(claims[_epoch].timestamp) + challengePeriod, "Challenge period elapsed.");
144-
145-
challenges[_epoch] = Challenge({challenger: msg.sender, honest: false, depositAndRewardWithdrawn: false});
146-
emit ClaimChallenged(_epoch);
147-
}
148-
149-
/**
150-
* @dev Resolves the optimistic claim for '_epoch'.
151-
* @param _epoch The epoch of the optimistic claim.
152-
*/
153-
function verifyBatch(uint256 _epoch) external override {
154-
Claim storage claim = claims[_epoch];
155-
require(claim.bridger != address(0), "Invalid epoch, no claim to verify.");
156-
require(claim.verificationAttempted == false, "Optimistic verification already attempted.");
157-
require(
158-
block.timestamp > uint256(claims[_epoch].timestamp) + challengePeriod,
159-
"Challenge period has not yet elapsed."
160-
);
161-
162-
if (challenges[_epoch].challenger == address(0)) {
163-
// Optimistic happy path
164-
claim.honest = true;
165-
fastInbox[_epoch] = claim.batchMerkleRoot;
166-
emit BatchVerified(_epoch, true);
167-
} else {
168-
emit BatchVerified(_epoch, false);
169-
}
170-
claim.verificationAttempted = true;
171-
}
172-
173-
/**
174-
* Note: Access restricted to the Safe Bridge.
175-
* @dev Resolves any challenge of the optimistic claim for '_epoch'.
176-
* @param _epoch The epoch to verify.
177-
* @param _batchMerkleRoot The true batch merkle root for the epoch.
178-
*/
179-
function verifySafeBatch(uint256 _epoch, bytes32 _batchMerkleRoot) external override {
180-
require(isSentBySafeBridge(), "Access not allowed: SafeBridgeSender only.");
181-
182-
fastInbox[_epoch] = _batchMerkleRoot;
183-
184-
// Corner cases:
185-
// a) No claim submitted,
186-
// b) Receiving the root of an empty batch,
187-
// c) Batch root is zero.
188-
if (claims[_epoch].bridger != address(0)) {
189-
if (_batchMerkleRoot == claims[_epoch].batchMerkleRoot) {
190-
claims[_epoch].honest = true;
191-
} else {
192-
claims[_epoch].honest = false;
193-
challenges[_epoch].honest = true;
194-
}
195-
}
196-
emit BatchSafeVerified(_epoch, claims[_epoch].honest, challenges[_epoch].honest);
197-
}
198-
199-
/**
200-
* @dev Verifies merkle proof for the given message and associated nonce for the epoch and relays the message.
201-
* @param _epoch The epoch in which the message was batched by the bridge.
202-
* @param _proof The merkle proof to prove the membership of the message and nonce in the merkle tree for the epoch.
203-
* @param _message The data on the cross-domain chain for the message.
204-
*/
205-
function verifyAndRelayMessage(
206-
uint256 _epoch,
207-
bytes32[] calldata _proof,
208-
bytes calldata _message
209-
) external override {
210-
bytes32 batchMerkleRoot = fastInbox[_epoch];
211-
require(batchMerkleRoot != bytes32(0), "Invalid epoch.");
212-
213-
// Claim assessment if any
214-
require(validateProof(_proof, sha256(_message), batchMerkleRoot) == true, "Invalid proof.");
215-
require(_checkReplayAndRelay(_epoch, _message), "Failed to call contract"); // Checks-Effects-Interaction
216-
}
217-
218-
/**
219-
* @dev Sends the deposit back to the Bridger if their claim is not successfully challenged. Includes a portion of the Challenger's deposit if unsuccessfully challenged.
220-
* @param _epoch The epoch associated with the claim deposit to withraw.
221-
*/
222-
function withdrawClaimDeposit(uint256 _epoch) external override {
223-
Claim storage claim = claims[_epoch];
224-
225-
require(claim.bridger != address(0), "Claim does not exist");
226-
require(claim.honest == true, "Claim failed.");
227-
require(claim.depositAndRewardWithdrawn == false, "Claim deposit and any rewards already withdrawn.");
228-
229-
uint256 amount = deposit;
230-
if (challenges[_epoch].challenger != address(0) && challenges[_epoch].honest == false) {
231-
amount += deposit / 2; // half burnt
232-
}
233-
234-
claim.depositAndRewardWithdrawn = true;
235-
emit ClaimDepositWithdrawn(_epoch, claim.bridger);
236-
237-
payable(claim.bridger).send(amount); // Use of send to prevent reverting fallback. User is responsibility for accepting ETH.
238-
// Checks-Effects-Interaction
239-
}
240-
241-
/**
242-
* @dev Sends the deposit back to the Challenger if their challenge is successful. Includes a portion of the Bridger's deposit.
243-
* @param _epoch The epoch associated with the challenge deposit to withraw.
244-
*/
245-
function withdrawChallengeDeposit(uint256 _epoch) external override {
246-
Challenge storage challenge = challenges[_epoch];
247-
248-
require(challenge.challenger != address(0), "Challenge does not exist");
249-
require(challenge.honest == true, "Challenge failed.");
250-
require(challenge.depositAndRewardWithdrawn == false, "Challenge deposit and rewards already withdrawn.");
251-
252-
uint256 amount = deposit;
253-
if (claims[_epoch].bridger != address(0) && claims[_epoch].honest == false) {
254-
amount += deposit / 2; // half burnt
255-
}
256-
257-
challenge.depositAndRewardWithdrawn = true;
258-
emit ChallengeDepositWithdrawn(_epoch, challenge.challenger);
259-
260-
payable(challenge.challenger).send(amount); // Use of send to prevent reverting fallback. User is responsibility for accepting ETH.
261-
// Checks-Effects-Interaction
262-
}
263-
264-
// ********************************** //
265-
// * Merkle Proof * //
266-
// ********************************** //
267-
268-
/**
269-
* @dev Validates membership of leaf in merkle tree with merkle proof.
270-
* Note: Inlined from `merkle/MerkleProof.sol` for performance.
271-
* @param proof The merkle proof.
272-
* @param leaf The leaf to validate membership in merkle tree.
273-
* @param merkleRoot The root of the merkle tree.
274-
*/
275-
function validateProof(
276-
bytes32[] memory proof,
277-
bytes32 leaf,
278-
bytes32 merkleRoot
279-
) internal pure returns (bool) {
280-
return (merkleRoot == calculateRoot(proof, leaf));
281-
}
282-
283-
/**
284-
* @dev Calculates merkle root from proof.
285-
* @param proof The merkle proof.
286-
* @param leaf The leaf to validate membership in merkle tree..
287-
*/
288-
function calculateRoot(bytes32[] memory proof, bytes32 leaf) private pure returns (bytes32) {
289-
uint256 proofLength = proof.length;
290-
require(proofLength <= 32, "Invalid Proof");
291-
bytes32 h = leaf;
292-
for (uint256 i = 0; i < proofLength; i++) {
293-
bytes32 proofElement = proof[i];
294-
// effecient hash
295-
if (proofElement > h)
296-
assembly {
297-
mstore(0x00, h)
298-
mstore(0x20, proofElement)
299-
h := keccak256(0x00, 0x40)
300-
}
301-
else
302-
assembly {
303-
mstore(0x00, proofElement)
304-
mstore(0x20, h)
305-
h := keccak256(0x00, 0x40)
306-
}
307-
}
308-
return h;
309-
}
310-
311-
// ************************************* //
312-
// * Public Views * //
313-
// ************************************* //
314-
315-
/**
316-
* @dev Returns the `start` and `end` time of challenge period for this `epoch`.
317-
* @param _epoch The epoch of the claim to request the challenge period.
318-
* @return start The start time of the challenge period.
319-
* @return end The end time of the challenge period.
320-
*/
321-
function claimChallengePeriod(uint256 _epoch) external view override returns (uint256 start, uint256 end) {
322-
// start begins latest after the claim deadline expiry
323-
// however can begin as soon as a claim is made
324-
// can only challenge the only active claim, about the previous epoch
325-
start = claims[_epoch].timestamp;
326-
end = start + challengePeriod;
327-
}
328-
329-
// ************************ //
330-
// * Internal * //
331-
// ************************ //
332-
333-
function _checkReplayAndRelay(uint256 _epoch, bytes calldata _messageData) internal returns (bool success) {
334-
// Decode the receiver gateway address from the data encoded by the IFastBridgeSender
335-
(uint256 nonce, address receiver, bytes memory data) = abi.decode(_messageData, (uint256, address, bytes));
336-
uint256 index = nonce / 256;
337-
uint256 offset = nonce % 256;
338-
bytes32 replay = relayed[_epoch][index];
339-
require(((replay >> offset) & bytes32(uint256(1))) == 0, "Message already relayed");
340-
relayed[_epoch][index] = replay | bytes32(1 << offset);
341-
emit MessageRelayed(_epoch, nonce);
342-
(success, ) = receiver.call(data);
343-
// Checks-Effects-Interaction
344-
}
49+
) FastBridgeReceiverOnEthereum(_deposit, _epochPeriod, _challengePeriod, _safeBridgeSender, _inbox) {}
34550
}

0 commit comments

Comments
 (0)
Please sign in to comment.