Commit 26f536dc authored by Andreas Bigger's avatar Andreas Bigger

Fix up styling

parent b903b980
...@@ -12,6 +12,7 @@ import { Semver } from "../universal/Semver.sol"; ...@@ -12,6 +12,7 @@ import { Semver } from "../universal/Semver.sol";
/// for sending and receiving data on the L1 side. Users are encouraged to use this /// for sending and receiving data on the L1 side. Users are encouraged to use this
/// interface instead of interacting with lower-level contracts directly. /// interface instead of interacting with lower-level contracts directly.
contract L1CrossDomainMessenger is CrossDomainMessenger, Semver { contract L1CrossDomainMessenger is CrossDomainMessenger, Semver {
/// @notice Address of the OptimismPortal. /// @notice Address of the OptimismPortal.
OptimismPortal public immutable PORTAL; OptimismPortal public immutable PORTAL;
......
...@@ -11,6 +11,7 @@ import { Semver } from "../universal/Semver.sol"; ...@@ -11,6 +11,7 @@ import { Semver } from "../universal/Semver.sol";
/// make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract /// make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract
/// acts as an escrow for ERC721 tokens deposited into L2. /// acts as an escrow for ERC721 tokens deposited into L2.
contract L1ERC721Bridge is ERC721Bridge, Semver { contract L1ERC721Bridge is ERC721Bridge, Semver {
/// @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token /// @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token
/// by ID was deposited for a given L2 token. /// by ID was deposited for a given L2 token.
mapping(address => mapping(address => mapping(uint256 => bool))) public deposits; mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;
...@@ -26,7 +27,6 @@ contract L1ERC721Bridge is ERC721Bridge, Semver { ...@@ -26,7 +27,6 @@ contract L1ERC721Bridge is ERC721Bridge, Semver {
/// @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the /// @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the
/// recipient on this domain. /// recipient on this domain.
///
/// @param _localToken Address of the ERC721 token on this domain. /// @param _localToken Address of the ERC721 token on this domain.
/// @param _remoteToken Address of the ERC721 token on the other domain. /// @param _remoteToken Address of the ERC721 token on the other domain.
/// @param _from Address that triggered the bridge on the other domain. /// @param _from Address that triggered the bridge on the other domain.
......
...@@ -16,6 +16,7 @@ import { Semver } from "../universal/Semver.sol"; ...@@ -16,6 +16,7 @@ import { Semver } from "../universal/Semver.sol";
/// of some token types that may not be properly supported by this contract include, but are /// of some token types that may not be properly supported by this contract include, but are
/// not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists. /// not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.
contract L1StandardBridge is StandardBridge, Semver { contract L1StandardBridge is StandardBridge, Semver {
/// @custom:legacy /// @custom:legacy
/// @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated. /// @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.
/// @param from Address of the depositor. /// @param from Address of the depositor.
......
...@@ -11,6 +11,7 @@ import { Types } from "../libraries/Types.sol"; ...@@ -11,6 +11,7 @@ import { Types } from "../libraries/Types.sol";
/// commitment to the state of the L2 chain. Other contracts like the OptimismPortal use /// commitment to the state of the L2 chain. Other contracts like the OptimismPortal use
/// these outputs to verify information about the state of L2. /// these outputs to verify information about the state of L2.
contract L2OutputOracle is Initializable, Semver { contract L2OutputOracle is Initializable, Semver {
/// @notice The interval in L2 blocks at which checkpoints must be submitted. /// @notice The interval in L2 blocks at which checkpoints must be submitted.
/// Although this is immutable, it can safely be modified by upgrading the /// Although this is immutable, it can safely be modified by upgrading the
/// implementation contract. /// implementation contract.
......
...@@ -19,6 +19,7 @@ import { Semver } from "../universal/Semver.sol"; ...@@ -19,6 +19,7 @@ import { Semver } from "../universal/Semver.sol";
/// and L2. Messages sent directly to the OptimismPortal have no form of replayability. /// and L2. Messages sent directly to the OptimismPortal have no form of replayability.
/// Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface. /// Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface.
contract OptimismPortal is Initializable, ResourceMetering, Semver { contract OptimismPortal is Initializable, ResourceMetering, Semver {
/// @notice Represents a proven withdrawal. /// @notice Represents a proven withdrawal.
/// @custom:field outputRoot Root of the L2 output this was proven against. /// @custom:field outputRoot Root of the L2 output this was proven against.
/// @custom:field timestamp Timestamp at whcih the withdrawal was proven. /// @custom:field timestamp Timestamp at whcih the withdrawal was proven.
......
...@@ -11,6 +11,7 @@ import { Arithmetic } from "../libraries/Arithmetic.sol"; ...@@ -11,6 +11,7 @@ import { Arithmetic } from "../libraries/Arithmetic.sol";
/// @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing /// @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing
/// updates automatically based on current demand. /// updates automatically based on current demand.
abstract contract ResourceMetering is Initializable { abstract contract ResourceMetering is Initializable {
/// @notice Represents the various parameters that control the way in which resources are /// @notice Represents the various parameters that control the way in which resources are
/// metered. Corresponds to the EIP-1559 resource metering system. /// metered. Corresponds to the EIP-1559 resource metering system.
/// @custom:field prevBaseFee Base fee from the previous block(s). /// @custom:field prevBaseFee Base fee from the previous block(s).
......
...@@ -12,6 +12,7 @@ import { ResourceMetering } from "./ResourceMetering.sol"; ...@@ -12,6 +12,7 @@ import { ResourceMetering } from "./ResourceMetering.sol";
/// All configuration is stored on L1 and picked up by L2 as part of the derviation of /// All configuration is stored on L1 and picked up by L2 as part of the derviation of
/// the L2 chain. /// the L2 chain.
contract SystemConfig is OwnableUpgradeable, Semver { contract SystemConfig is OwnableUpgradeable, Semver {
/// @notice Enum representing different types of updates. /// @notice Enum representing different types of updates.
/// @custom:value BATCHER Represents an update to the batcher hash. /// @custom:value BATCHER Represents an update to the batcher hash.
/// @custom:value GAS_CONFIG Represents an update to txn fee config on L2. /// @custom:value GAS_CONFIG Represents an update to txn fee config on L2.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
/* Testing utilities */ // Testing utilities
import { Messenger_Initializer, Reverter, ConfigurableCaller } from "./CommonTest.t.sol"; import { Messenger_Initializer, Reverter, ConfigurableCaller } from "./CommonTest.t.sol";
import { L2OutputOracle_Initializer } from "./L2OutputOracle.t.sol"; import { L2OutputOracle_Initializer } from "./L2OutputOracle.t.sol";
/* Libraries */ // Libraries
import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "../vendor/AddressAliasHelper.sol";
import { Predeploys } from "../libraries/Predeploys.sol"; import { Predeploys } from "../libraries/Predeploys.sol";
import { Hashing } from "../libraries/Hashing.sol"; import { Hashing } from "../libraries/Hashing.sol";
import { Encoding } from "../libraries/Encoding.sol"; import { Encoding } from "../libraries/Encoding.sol";
/* Target contract dependencies */ // Target contract dependencies
import { L2OutputOracle } from "../L1/L2OutputOracle.sol"; import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { OptimismPortal } from "../L1/OptimismPortal.sol"; import { OptimismPortal } from "../L1/OptimismPortal.sol";
/* Target contract */ // Target contract
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol"; import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
contract L1CrossDomainMessenger_Test is Messenger_Initializer { contract L1CrossDomainMessenger_Test is Messenger_Initializer {
// Receiver address for testing
/// @dev The receiver address
address recipient = address(0xabbaacdc); address recipient = address(0xabbaacdc);
// Storage slot of the l2Sender /// @dev The storage slot of the l2Sender
uint256 constant senderSlotIndex = 50; uint256 constant senderSlotIndex = 50;
// the version is encoded in the nonce /// @dev Tests that the version can be decoded from the message nonce.
function test_messageVersion_succeeds() external { function test_messageVersion_succeeds() external {
(, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce()); (, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce());
assertEq(version, L1Messenger.MESSAGE_VERSION()); assertEq(version, L1Messenger.MESSAGE_VERSION());
} }
// sendMessage: should be able to send a single message /// @dev Tests that the sendMessage function is able to send a single message.
// TODO: this same test needs to be done with the legacy message type /// TODO: this same test needs to be done with the legacy message type
// by setting the message version to 0 /// by setting the message version to 0
function test_sendMessage_succeeds() external { function test_sendMessage_succeeds() external {
// deposit transaction on the optimism portal should be called // deposit transaction on the optimism portal should be called
vm.expectCall( vm.expectCall(
...@@ -86,7 +87,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -86,7 +87,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
L1Messenger.sendMessage(recipient, hex"ff", uint32(100)); L1Messenger.sendMessage(recipient, hex"ff", uint32(100));
} }
// sendMessage: should be able to send the same message twice /// @dev Tests that the sendMessage function is able to send
/// the same message twice.
function test_sendMessage_twice_succeeds() external { function test_sendMessage_twice_succeeds() external {
uint256 nonce = L1Messenger.messageNonce(); uint256 nonce = L1Messenger.messageNonce();
L1Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); L1Messenger.sendMessage(recipient, hex"aa", uint32(500_000));
...@@ -95,11 +97,14 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -95,11 +97,14 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
assertEq(nonce + 2, L1Messenger.messageNonce()); assertEq(nonce + 2, L1Messenger.messageNonce());
} }
/// @dev Tests that the xDomainMessageSender reverts when not set.
function test_xDomainSender_notSet_reverts() external { function test_xDomainSender_notSet_reverts() external {
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender(); L1Messenger.xDomainMessageSender();
} }
/// @dev Tests that the relayMessage function reverts when
/// the message version is not 0 or 1.
function test_relayMessage_v2_reverts() external { function test_relayMessage_v2_reverts() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
...@@ -124,7 +129,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -124,7 +129,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
} }
// relayMessage: should send a successful call to the target contract /// @dev Tests that the relayMessage function is able to relay a message
/// successfully by calling the target contract.
function test_relayMessage_succeeds() external { function test_relayMessage_succeeds() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
...@@ -163,7 +169,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -163,7 +169,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
assertEq(L1Messenger.failedMessages(hash), false); assertEq(L1Messenger.failedMessages(hash), false);
} }
// relayMessage: should revert if attempting to relay a message sent to an L1 system contract /// @dev Tests that relayMessage reverts if attempting to relay a message
/// sent to an L1 system contract.
function test_relayMessage_toSystemContract_reverts() external { function test_relayMessage_toSystemContract_reverts() external {
// set the target to be the OptimismPortal // set the target to be the OptimismPortal
address target = address(op); address target = address(op);
...@@ -193,7 +200,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -193,7 +200,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
} }
// relayMessage: should revert if eth is sent from a contract other than the standard bridge /// @dev Tests that the relayMessage function reverts if eth is
/// sent from a contract other than the standard bridge.
function test_replayMessage_withValue_reverts() external { function test_replayMessage_withValue_reverts() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
...@@ -212,7 +220,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -212,7 +220,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
} }
// relayMessage: the xDomainMessageSender is reset to the original value /// @dev Tests that the xDomainMessageSender is reset to the original value
/// after a message is relayed.
function test_xDomainMessageSender_reset_succeeds() external { function test_xDomainMessageSender_reset_succeeds() external {
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender(); L1Messenger.xDomainMessageSender();
...@@ -234,8 +243,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -234,8 +243,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
L1Messenger.xDomainMessageSender(); L1Messenger.xDomainMessageSender();
} }
// relayMessage: should send a successful call to the target contract after the first message /// @dev Tests that relayMessage should successfully call the target contract after
// fails and ETH gets stuck, but the second message succeeds /// the first message fails and ETH is stuck, but the second message succeeds
/// with a version 1 message.
function test_relayMessage_retryAfterFailure_succeeds() external { function test_relayMessage_retryAfterFailure_succeeds() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
...@@ -291,6 +301,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -291,6 +301,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
assertEq(L1Messenger.failedMessages(hash), true); assertEq(L1Messenger.failedMessages(hash), true);
} }
/// @dev Tests that relayMessage should successfully call the target contract after
/// the first message fails and ETH is stuck, but the second message succeeds
/// with a legacy message.
function test_relayMessage_legacy_succeeds() external { function test_relayMessage_legacy_succeeds() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
...@@ -332,6 +345,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -332,6 +345,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
assertEq(L1Messenger.failedMessages(hash), false); assertEq(L1Messenger.failedMessages(hash), false);
} }
/// @dev Tests that relayMessage should revert if the message is already replayed.
function test_relayMessage_legacyOldReplay_reverts() external { function test_relayMessage_legacyOldReplay_reverts() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
...@@ -375,6 +389,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -375,6 +389,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
assertEq(L1Messenger.failedMessages(hash), false); assertEq(L1Messenger.failedMessages(hash), false);
} }
/// @dev Tests that relayMessage can be retried after a failure with a legacy message.
function test_relayMessage_legacyRetryAfterFailure_succeeds() external { function test_relayMessage_legacyRetryAfterFailure_succeeds() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
...@@ -450,6 +465,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -450,6 +465,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
assertEq(L1Messenger.failedMessages(hash), true); assertEq(L1Messenger.failedMessages(hash), true);
} }
/// @dev Tests that relayMessage cannot be retried after success with a legacy message.
function test_relayMessage_legacyRetryAfterSuccess_reverts() external { function test_relayMessage_legacyRetryAfterSuccess_reverts() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
...@@ -509,6 +525,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -509,6 +525,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
} }
/// @dev Tests that relayMessage cannot be called after a failure and a successful replay.
function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external { function test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; // Testing utilities
import { Messenger_Initializer } from "./CommonTest.t.sol"; import { Messenger_Initializer } from "./CommonTest.t.sol";
import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// Target contract dependencies
import { L2ERC721Bridge } from "../L2/L2ERC721Bridge.sol"; import { L2ERC721Bridge } from "../L2/L2ERC721Bridge.sol";
// Target contract
import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol";
/// @dev Test ERC721 contract.
contract TestERC721 is ERC721 { contract TestERC721 is ERC721 {
constructor() ERC721("Test", "TST") {} constructor() ERC721("Test", "TST") {}
...@@ -39,6 +45,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -39,6 +45,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
bytes extraData bytes extraData
); );
/// @dev Sets up the testing environment.
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
...@@ -58,6 +65,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -58,6 +65,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
localToken.approve(address(bridge), tokenId); localToken.approve(address(bridge), tokenId);
} }
/// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() public { function test_constructor_succeeds() public {
assertEq(address(bridge.MESSENGER()), address(L1Messenger)); assertEq(address(bridge.MESSENGER()), address(L1Messenger));
assertEq(address(bridge.OTHER_BRIDGE()), otherBridge); assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);
...@@ -65,6 +73,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -65,6 +73,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(address(bridge.otherBridge()), otherBridge); assertEq(address(bridge.otherBridge()), otherBridge);
} }
/// @dev Tests that the ERC721 can be bridged successfully.
function test_bridgeERC721_succeeds() public { function test_bridgeERC721_succeeds() public {
// Expect a call to the messenger. // Expect a call to the messenger.
vm.expectCall( vm.expectCall(
...@@ -109,6 +118,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -109,6 +118,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), address(bridge)); assertEq(localToken.ownerOf(tokenId), address(bridge));
} }
/// @dev Tests that the ERC721 bridge reverts for non externally owned accounts.
function test_bridgeERC721_fromContract_reverts() external { function test_bridgeERC721_fromContract_reverts() external {
// Bridge the token. // Bridge the token.
vm.etch(alice, hex"01"); vm.etch(alice, hex"01");
...@@ -121,6 +131,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -121,6 +131,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
/// @dev Tests that the ERC721 bridge reverts for a zero address local token.
function test_bridgeERC721_localTokenZeroAddress_reverts() external { function test_bridgeERC721_localTokenZeroAddress_reverts() external {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
...@@ -132,6 +143,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -132,6 +143,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
/// @dev Tests that the ERC721 bridge reverts for a zero address remote token.
function test_bridgeERC721_remoteTokenZeroAddress_reverts() external { function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
...@@ -143,6 +155,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -143,6 +155,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
/// @dev Tests that the ERC721 bridge reverts for an incorrect owner.
function test_bridgeERC721_wrongOwner_reverts() external { function test_bridgeERC721_wrongOwner_reverts() external {
// Bridge the token. // Bridge the token.
vm.prank(bob); vm.prank(bob);
...@@ -154,6 +167,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -154,6 +167,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
/// @dev Tests that the ERC721 bridge successfully sends a token
/// to a different address than the owner.
function test_bridgeERC721To_succeeds() external { function test_bridgeERC721To_succeeds() external {
// Expect a call to the messenger. // Expect a call to the messenger.
vm.expectCall( vm.expectCall(
...@@ -198,6 +213,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -198,6 +213,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), address(bridge)); assertEq(localToken.ownerOf(tokenId), address(bridge));
} }
/// @dev Tests that the ERC721 bridge reverts for non externally owned accounts
/// when sending to a different address than the owner.
function test_bridgeERC721To_localTokenZeroAddress_reverts() external { function test_bridgeERC721To_localTokenZeroAddress_reverts() external {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
...@@ -209,6 +226,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -209,6 +226,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
/// @dev Tests that the ERC721 bridge reverts for a zero address remote token
/// when sending to a different address than the owner.
function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external { function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
...@@ -220,6 +239,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -220,6 +239,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
/// @dev Tests that the ERC721 bridge reverts for an incorrect owner
//// when sending to a different address than the owner.
function test_bridgeERC721To_wrongOwner_reverts() external { function test_bridgeERC721To_wrongOwner_reverts() external {
// Bridge the token. // Bridge the token.
vm.prank(bob); vm.prank(bob);
...@@ -238,6 +259,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -238,6 +259,7 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
/// @dev Tests that the ERC721 bridge successfully finalizes a withdrawal.
function test_finalizeBridgeERC721_succeeds() external { function test_finalizeBridgeERC721_succeeds() external {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
...@@ -275,6 +297,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -275,6 +297,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
/// @dev Tests that the ERC721 bridge finalize reverts when not called
/// by the remote bridge.
function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external { function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.prank(alice); vm.prank(alice);
...@@ -289,6 +313,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -289,6 +313,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
); );
} }
/// @dev Tests that the ERC721 bridge finalize reverts when not called
/// from the remote messenger.
function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
...@@ -308,6 +334,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -308,6 +334,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
); );
} }
/// @dev Tests that the ERC721 bridge finalize reverts when the local token
/// is set as the bridge itself.
function test_finalizeBridgeERC721_selfToken_reverts() external { function test_finalizeBridgeERC721_selfToken_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
...@@ -327,6 +355,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer { ...@@ -327,6 +355,8 @@ contract L1ERC721Bridge_Test is Messenger_Initializer {
); );
} }
/// @dev Tests that the ERC721 bridge finalize reverts when the remote token
/// is not escrowed in the L1 bridge.
function test_finalizeBridgeERC721_notEscrowed_reverts() external { function test_finalizeBridgeERC721_notEscrowed_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment