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
390dbcbe
Commit
390dbcbe
authored
Mar 08, 2023
by
Mark Tyneway
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
contracts-bedrock: add tests for legacy mintable token
parent
3380a610
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
142 additions
and
27 deletions
+142
-27
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+6
-4
LegacyMintableERC20.sol
...ontracts-bedrock/contracts/legacy/LegacyMintableERC20.sol
+89
-0
CommonTest.t.sol
packages/contracts-bedrock/contracts/test/CommonTest.t.sol
+10
-0
L2StandardBridge.t.sol
...s/contracts-bedrock/contracts/test/L2StandardBridge.t.sol
+37
-23
No files found.
packages/contracts-bedrock/.gas-snapshot
View file @
390dbcbe
...
...
@@ -174,11 +174,13 @@ L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 26208)
L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 15149)
L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 20175)
L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 180481)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 390084)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 390315)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 385788)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 389773)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 390006)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 385280)
L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 393552)
L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 393878)
L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251758)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 385
973
)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 385
508
)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 23843)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 23982)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 23870)
...
...
packages/contracts-bedrock/contracts/legacy/LegacyMintableERC20.sol
0 → 100644
View file @
390dbcbe
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { ILegacyMintableERC20 } from "../universal/OptimismMintableERC20.sol";
/**
* @title LegacyMintableERC20
* @notice The legacy implementation of the OptimismMintableERC20. This
* contract is deprecated and should no longer be used.
*/
contract LegacyMintableERC20 is ILegacyMintableERC20, ERC20 {
/**
* @notice Emitted when the token is minted by the bridge.
*/
event Mint(address indexed _account, uint256 _amount);
/**
* @notice Emitted when a token is burned by the bridge.
*/
event Burn(address indexed _account, uint256 _amount);
/**
* @notice The token on the remote domain.
*/
address public l1Token;
/**
* @notice The local bridge.
*/
address public l2Bridge;
/**
* @param _l2Bridge Address of the L2 standard bridge.
* @param _l1Token Address of the corresponding L1 token.
* @param _name ERC20 name.
* @param _symbol ERC20 symbol.
*/
constructor(
address _l2Bridge,
address _l1Token,
string memory _name,
string memory _symbol
) ERC20(_name, _symbol) {
l1Token = _l1Token;
l2Bridge = _l2Bridge;
}
/**
* @notice Modifier that requires the contract was called by the bridge.
*/
modifier onlyL2Bridge() {
require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn");
_;
}
/**
* @notice EIP165 implementation.
*/
function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {
bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
bytes4 secondSupportedInterface = ILegacyMintableERC20.l1Token.selector ^
ILegacyMintableERC20.mint.selector ^
ILegacyMintableERC20.burn.selector;
return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface;
}
/**
* @notice Only the bridge can mint tokens.
* @param _to The account receiving tokens.
* @param _amount The amount of tokens to receive.
*/
function mint(address _to, uint256 _amount) public virtual onlyL2Bridge {
_mint(_to, _amount);
emit Mint(_to, _amount);
}
/**
* @notice Only the bridge can burn tokens.
* @param _from The account having tokens burnt.
* @param _amount The amount of tokens being burnt.
*/
function burn(address _from, uint256 _amount) public virtual onlyL2Bridge {
_burn(_from, _amount);
emit Burn(_from, _amount);
}
}
packages/contracts-bedrock/contracts/test/CommonTest.t.sol
View file @
390dbcbe
...
...
@@ -27,6 +27,7 @@ import { AddressManager } from "../legacy/AddressManager.sol";
import { L1ChugSplashProxy } from "../legacy/L1ChugSplashProxy.sol";
import { IL1ChugSplashDeployer } from "../legacy/L1ChugSplashProxy.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { LegacyMintableERC20 } from "../legacy/LegacyMintableERC20.sol";
contract CommonTest is Test {
address alice = address(128);
...
...
@@ -276,6 +277,7 @@ contract Bridge_Initializer is Messenger_Initializer {
ERC20 L1Token;
ERC20 BadL1Token;
OptimismMintableERC20 L2Token;
LegacyMintableERC20 LegacyL2Token;
ERC20 NativeL2Token;
ERC20 BadL2Token;
OptimismMintableERC20 RemoteL1Token;
...
...
@@ -398,6 +400,14 @@ contract Bridge_Initializer is Messenger_Initializer {
L1Token = new ERC20("Native L1 Token", "L1T");
LegacyL2Token = new LegacyMintableERC20({
_l2Bridge: address(L2Bridge),
_l1Token: address(L1Token),
_name: string.concat("LegacyL2-", L1Token.name()),
_symbol: string.concat("LegacyL2-", L1Token.symbol())
});
vm.label(address(LegacyL2Token), "LegacyMintableERC20");
// Deploy the L2 ERC20 now
L2Token = OptimismMintableERC20(
L2TokenFactory.createStandardL2Token(
...
...
packages/contracts-bedrock/contracts/test/L2StandardBridge.t.sol
View file @
390dbcbe
...
...
@@ -155,15 +155,15 @@ contract L2StandardBridge_Test is Bridge_Initializer {
contract PreBridgeERC20 is Bridge_Initializer {
// withdraw and BridgeERC20 should behave the same when transferring ERC20 tokens
// so they should share the same setup and expectEmit calls
function _preBridgeERC20(bool
isLegacy
) internal {
function _preBridgeERC20(bool
_isLegacy, address _l2Token
) internal {
// Alice has 100 L2Token
deal(
address(L2Token)
, alice, 100, true);
assertEq(
L2Token
.balanceOf(alice), 100);
deal(
_l2Token
, alice, 100, true);
assertEq(
ERC20(_l2Token)
.balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector,
address(L1Token),
address(L2Token)
,
_l2Token
,
alice,
alice,
100,
...
...
@@ -190,12 +190,12 @@ contract PreBridgeERC20 is Bridge_Initializer {
})
);
if (isLegacy) {
if (
_
isLegacy) {
vm.expectCall(
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.withdraw.selector,
address(L2Token)
,
_l2Token
,
100,
1000,
hex""
...
...
@@ -206,7 +206,7 @@ contract PreBridgeERC20 is Bridge_Initializer {
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.bridgeERC20.selector,
address(L2Token)
,
_l2Token
,
address(L1Token),
100,
1000,
...
...
@@ -237,15 +237,15 @@ contract PreBridgeERC20 is Bridge_Initializer {
// The L2Bridge should burn the tokens
vm.expectCall(
address(L2Token)
,
_l2Token
,
abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)
);
vm.expectEmit(true, true, true, true);
emit WithdrawalInitiated(address(L1Token),
address(L2Token)
, alice, alice, 100, hex"");
emit WithdrawalInitiated(address(L1Token),
_l2Token
, alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true);
emit ERC20BridgeInitiated(
address(L2Token)
, address(L1Token), alice, alice, 100, hex"");
emit ERC20BridgeInitiated(
_l2Token
, address(L1Token), alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true);
emit MessagePassed(
...
...
@@ -276,7 +276,7 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {
// - emits WithdrawalInitiated
// - calls Withdrawer.initiateWithdrawal
function test_withdraw_withdrawingERC20_succeeds() external {
_preBridgeERC20({
isLegacy: true
});
_preBridgeERC20({
_isLegacy: true, _l2Token: address(L2Token)
});
L2Bridge.withdraw(address(L2Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
...
...
@@ -287,12 +287,26 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {
// - emits WithdrawalInitiated
// - calls Withdrawer.initiateWithdrawal
function test_bridgeERC20_succeeds() external {
_preBridgeERC20({
isLegacy: false
});
_preBridgeERC20({
_isLegacy: false, _l2Token: address(L2Token)
});
L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
}
function test_withdrawLegacyERC20_succeeds() external {
_preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) });
L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
}
function test_bridgeLegacyERC20_succeeds() external {
_preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) });
L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
}
function test_withdraw_notEOA_reverts() external {
// This contract has 100 L2Token
deal(address(L2Token), address(this), 100, true);
...
...
@@ -305,14 +319,14 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {
contract PreBridgeERC20To is Bridge_Initializer {
// withdrawTo and BridgeERC20To should behave the same when transferring ERC20 tokens
// so they should share the same setup and expectEmit calls
function _preBridgeERC20To(bool
isLegacy
) internal {
deal(
address(L2Token)
, alice, 100, true);
assertEq(
L2Token
.balanceOf(alice), 100);
function _preBridgeERC20To(bool
_isLegacy, address _l2Token
) internal {
deal(
_l2Token
, alice, 100, true);
assertEq(
ERC20(L2Token)
.balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce();
bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector,
address(L1Token),
address(L2Token)
,
_l2Token
,
alice,
bob,
100,
...
...
@@ -340,10 +354,10 @@ contract PreBridgeERC20To is Bridge_Initializer {
);
vm.expectEmit(true, true, true, true, address(L2Bridge));
emit WithdrawalInitiated(address(L1Token),
address(L2Token)
, alice, bob, 100, hex"");
emit WithdrawalInitiated(address(L1Token),
_l2Token
, alice, bob, 100, hex"");
vm.expectEmit(true, true, true, true, address(L2Bridge));
emit ERC20BridgeInitiated(
address(L2Token)
, address(L1Token), alice, bob, 100, hex"");
emit ERC20BridgeInitiated(
_l2Token
, address(L1Token), alice, bob, 100, hex"");
vm.expectEmit(true, true, true, true, address(messagePasser));
emit MessagePassed(
...
...
@@ -364,12 +378,12 @@ contract PreBridgeERC20To is Bridge_Initializer {
vm.expectEmit(true, true, true, true, address(L2Messenger));
emit SentMessageExtension1(address(L2Bridge), 0);
if (isLegacy) {
if (
_
isLegacy) {
vm.expectCall(
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.withdrawTo.selector,
address(L2Token)
,
_l2Token
,
bob,
100,
1000,
...
...
@@ -381,7 +395,7 @@ contract PreBridgeERC20To is Bridge_Initializer {
address(L2Bridge),
abi.encodeWithSelector(
L2Bridge.bridgeERC20To.selector,
address(L2Token)
,
_l2Token
,
address(L1Token),
bob,
100,
...
...
@@ -427,7 +441,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {
// - emits WithdrawalInitiated w/ correct recipient
// - calls Withdrawer.initiateWithdrawal
function test_withdrawTo_withdrawingERC20_succeeds() external {
_preBridgeERC20To({
isLegacy: true
});
_preBridgeERC20To({
_isLegacy: true, _l2Token: address(L2Token)
});
L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
...
...
@@ -438,7 +452,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {
// - emits WithdrawalInitiated w/ correct recipient
// - calls Withdrawer.initiateWithdrawal
function test_bridgeERC20To_succeeds() external {
_preBridgeERC20To({
isLegacy: false
});
_preBridgeERC20To({
_isLegacy: false, _l2Token: address(L2Token)
});
L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0);
}
...
...
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