Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
476f3322
Unverified
Commit
476f3322
authored
Dec 14, 2022
by
mergify[bot]
Committed by
GitHub
Dec 14, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4421 from ethereum-optimism/sc/ctb-l2erc721-tests
test(ctb): port L2ERC721Bridge tests
parents
c542198e
c18173e9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
421 additions
and
0 deletions
+421
-0
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+15
-0
L2ERC721Bridge.t.sol
...ges/contracts-bedrock/contracts/test/L2ERC721Bridge.t.sol
+406
-0
No files found.
packages/contracts-bedrock/.gas-snapshot
View file @
476f3322
...
@@ -115,6 +115,21 @@ L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 122533)
...
@@ -115,6 +115,21 @@ L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 122533)
L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 134671)
L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 134671)
L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 52594)
L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 52594)
L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10524)
L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10524)
L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 26432)
L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 21748)
L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 146998)
L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 29427)
L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22149)
L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 24244)
L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 19584)
L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 144600)
L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 29257)
L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 10133)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 29106)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 19852)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 16148)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 17637)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 168905)
L2OutputOracleTest:test_computeL2Timestamp_succeeds() (gas: 37184)
L2OutputOracleTest:test_computeL2Timestamp_succeeds() (gas: 37184)
L2OutputOracleTest:test_constructor_badTimestamp_reverts() (gas: 70717)
L2OutputOracleTest:test_constructor_badTimestamp_reverts() (gas: 70717)
L2OutputOracleTest:test_constructor_succeeds() (gas: 33760)
L2OutputOracleTest:test_constructor_succeeds() (gas: 33760)
...
...
packages/contracts-bedrock/contracts/test/L2ERC721Bridge.t.sol
0 → 100644
View file @
476f3322
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { Messenger_Initializer } from "./CommonTest.t.sol";
import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol";
import { L2ERC721Bridge } from "../L2/L2ERC721Bridge.sol";
import { OptimismMintableERC721 } from "../universal/OptimismMintableERC721.sol";
contract TestERC721 is ERC721 {
constructor() ERC721("Test", "TST") {}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
}
contract TestMintableERC721 is OptimismMintableERC721 {
constructor(address _bridge, address _remoteToken) OptimismMintableERC721(_bridge, 1, _remoteToken, "Test", "TST") {}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
}
contract L2ERC721Bridge_Test is Messenger_Initializer {
TestMintableERC721 internal localToken;
TestERC721 internal remoteToken;
L2ERC721Bridge internal bridge;
address internal constant otherBridge = address(0x3456);
uint256 internal constant tokenId = 1;
event ERC721BridgeInitiated(
address indexed localToken,
address indexed remoteToken,
address indexed from,
address to,
uint256 tokenId,
bytes extraData
);
event ERC721BridgeFinalized(
address indexed localToken,
address indexed remoteToken,
address indexed from,
address to,
uint256 tokenId,
bytes extraData
);
function setUp() public override {
super.setUp();
// Create necessary contracts.
bridge = new L2ERC721Bridge(address(L2Messenger), otherBridge);
remoteToken = new TestERC721();
localToken = new TestMintableERC721(address(bridge), address(remoteToken));
// Label the bridge so we get nice traces.
vm.label(address(bridge), "L2ERC721Bridge");
// Mint alice a token.
localToken.mint(alice, tokenId);
// Approve the bridge to transfer the token.
vm.prank(alice);
localToken.approve(address(bridge), tokenId);
}
function test_constructor_succeeds() public {
assertEq(address(bridge.MESSENGER()), address(L2Messenger));
assertEq(address(bridge.OTHER_BRIDGE()), otherBridge);
assertEq(address(bridge.messenger()), address(L2Messenger));
assertEq(address(bridge.otherBridge()), otherBridge);
}
function test_bridgeERC721_succeeds() public {
// Expect a call to the messenger.
vm.expectCall(
address(L2Messenger),
abi.encodeCall(
L2Messenger.sendMessage,
(
address(otherBridge),
abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721,
(
address(remoteToken),
address(localToken),
alice,
alice,
tokenId,
hex"5678"
)
),
1234
)
)
);
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
// Bridge the token.
vm.prank(alice);
bridge.bridgeERC721(
address(localToken),
address(remoteToken),
tokenId,
1234,
hex"5678"
);
// Token is burned.
vm.expectRevert("ERC721: invalid token ID");
localToken.ownerOf(tokenId);
}
function test_bridgeERC721_fromContract_reverts() external {
// Bridge the token.
vm.etch(alice, hex"01");
vm.prank(alice);
vm.expectRevert("ERC721Bridge: account is not externally owned");
bridge.bridgeERC721(
address(localToken),
address(remoteToken),
tokenId,
1234,
hex"5678"
);
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
}
function test_bridgeERC721_localTokenZeroAddress_reverts() external {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
bridge.bridgeERC721(
address(0),
address(remoteToken),
tokenId,
1234,
hex"5678"
);
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
}
function test_bridgeERC721_remoteTokenZeroAddress_reverts() external {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("ERC721Bridge: remote token cannot be address(0)");
bridge.bridgeERC721(
address(localToken),
address(0),
tokenId,
1234,
hex"5678"
);
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
}
function test_bridgeERC721_wrongOwner_reverts() external {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("Withdrawal is not being initiated by NFT owner");
bridge.bridgeERC721(
address(localToken),
address(remoteToken),
tokenId,
1234,
hex"5678"
);
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
}
function test_bridgeERC721To_succeeds() external {
// Expect a call to the messenger.
vm.expectCall(
address(L2Messenger),
abi.encodeCall(
L2Messenger.sendMessage,
(
address(otherBridge),
abi.encodeCall(
L1ERC721Bridge.finalizeBridgeERC721,
(
address(remoteToken),
address(localToken),
alice,
bob,
tokenId,
hex"5678"
)
),
1234
)
)
);
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
emit ERC721BridgeInitiated(
address(localToken),
address(remoteToken),
alice,
bob,
tokenId,
hex"5678"
);
// Bridge the token.
vm.prank(alice);
bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
// Token is burned.
vm.expectRevert("ERC721: invalid token ID");
localToken.ownerOf(tokenId);
}
function test_bridgeERC721To_localTokenZeroAddress_reverts() external {
// Bridge the token.
vm.prank(alice);
vm.expectRevert();
bridge.bridgeERC721To(
address(0),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
}
function test_bridgeERC721To_remoteTokenZeroAddress_reverts() external {
// Bridge the token.
vm.prank(alice);
vm.expectRevert("ERC721Bridge: remote token cannot be address(0)");
bridge.bridgeERC721To(
address(localToken),
address(0),
bob,
tokenId,
1234,
hex"5678"
);
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
}
function test_bridgeERC721To_wrongOwner_reverts() external {
// Bridge the token.
vm.prank(bob);
vm.expectRevert("Withdrawal is not being initiated by NFT owner");
bridge.bridgeERC721To(
address(localToken),
address(remoteToken),
bob,
tokenId,
1234,
hex"5678"
);
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
}
function test_finalizeBridgeERC721_succeeds() external {
// Bridge the token.
vm.prank(alice);
bridge.bridgeERC721(
address(localToken),
address(remoteToken),
tokenId,
1234,
hex"5678"
);
// Expect an event to be emitted.
vm.expectEmit(true, true, true, true);
emit ERC721BridgeFinalized(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
// Finalize a withdrawal.
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(otherBridge)
);
vm.prank(address(L2Messenger));
bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
// Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice);
}
function test_finalizeBridgeERC721_notViaLocalMessenger_reverts() external {
// Finalize a withdrawal.
vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
}
function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {
// Finalize a withdrawal.
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(alice)
);
vm.prank(address(L2Messenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
}
function test_finalizeBridgeERC721_selfToken_reverts() external {
// Finalize a withdrawal.
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(otherBridge)
);
vm.prank(address(L2Messenger));
vm.expectRevert("L2ERC721Bridge: local token cannot be self");
bridge.finalizeBridgeERC721(
address(bridge),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
}
function test_finalizeBridgeERC721_alreadyExists_reverts() external {
// Finalize a withdrawal.
vm.mockCall(
address(L2Messenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector),
abi.encode(otherBridge)
);
vm.prank(address(L2Messenger));
vm.expectRevert("ERC721: token already minted");
bridge.finalizeBridgeERC721(
address(localToken),
address(remoteToken),
alice,
alice,
tokenId,
hex"5678"
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment