Skip to content

Commit

Permalink
fix: PR fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
agusduha committed Aug 13, 2024
1 parent b8bd100 commit 809a71b
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 33 deletions.
10 changes: 9 additions & 1 deletion packages/contracts-bedrock/scripts/L2Genesis.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,15 @@ contract L2Genesis is Deployer {

/// @notice This predeploy is following the safety invariant #1.
function setL2StandardBridge(address payable _l1StandardBridgeProxy) public {
address impl = _setImplementationCode(Predeploys.L2_STANDARD_BRIDGE);
address impl;
if (cfg.useInterop()) {
string memory cname = "L2StandardBridgeInterop";
impl = Predeploys.predeployToCodeNamespace(Predeploys.L2_STANDARD_BRIDGE);
console.log("Setting %s implementation at: %s", cname, impl);
vm.etch(impl, vm.getDeployedCode(string.concat(cname, ".sol:", cname)));
} else {
impl = _setImplementationCode(Predeploys.L2_STANDARD_BRIDGE);
}

L2StandardBridge(payable(impl)).initialize({ _otherBridge: L1StandardBridge(payable(address(0))) });

Expand Down
8 changes: 6 additions & 2 deletions packages/contracts-bedrock/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,12 @@
"sourceCodeHash": "0xb0806d362ba5cc39acfb09e0606059a2b10a7c1d5bc1f86cd4561fd24f7dcada"
},
"src/L2/L2StandardBridge.sol": {
"initCodeHash": "0xb6af582e9edaae531d48559b7cd0ca5813a112361ea19b8cb46292726ad88d40",
"sourceCodeHash": "0xb4a9f333f04008f610eb55fa6ff7e610bab340d53156cb50ec65a575c9576b0e"
"initCodeHash": "0xfbfc7bd101022024b94114c26128c6028c25dec07e8d40fdcfdb180c0ba6ddee",
"sourceCodeHash": "0xb1a5fb22b124e8fa8eb5bae4b8e0770abbdbebe32be00480317cf4aaada28ed3"
},
"src/L2/L2StandardBridgeInterop.sol": {
"initCodeHash": "0xd7f85eef12b60211104cddbd86d9f458cd31a0ba74f382404799bcf86ef003ba",
"sourceCodeHash": "0x00f415380689a5ee1762e93b032d5c3de2fcddb36b0a068cb5616f7e8001ddc0"
},
"src/L2/L2ToL1MessagePasser.sol": {
"initCodeHash": "0x08bbede75cd6dfd076903b8f04d24f82fa7881576c135825098778632e37eebc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@
"type": "string"
}
],
"stateMutability": "view",
"stateMutability": "pure",
"type": "function"
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@
"type": "string"
}
],
"stateMutability": "view",
"stateMutability": "pure",
"type": "function"
},
{
Expand Down Expand Up @@ -678,12 +678,12 @@
},
{
"inputs": [],
"name": "InvalidLegacyAddress",
"name": "InvalidLegacyERC20Address",
"type": "error"
},
{
"inputs": [],
"name": "InvalidSuperchainAddress",
"name": "InvalidSuperchainERC20Address",
"type": "error"
},
{
Expand Down
7 changes: 5 additions & 2 deletions packages/contracts-bedrock/src/L2/L2StandardBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ contract L2StandardBridge is StandardBridge, ISemver {
bytes extraData
);

/// @custom:semver 1.10.0
string public constant version = "1.10.0";
/// @notice Semantic version.
/// @custom:semver 1.11.0
function version() public pure virtual returns (string memory) {
return "1.11.0";
}

/// @notice Constructs the L2StandardBridge contract.
constructor() StandardBridge() {
Expand Down
18 changes: 13 additions & 5 deletions packages/contracts-bedrock/src/L2/L2StandardBridgeInterop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ import { IOptimismERC20Factory } from "src/L2/IOptimismERC20Factory.sol";
error InvalidDecimals();

/// @notice Thrown when the legacy address is not found in the OptimismMintableERC20Factory.
error InvalidLegacyAddress();
error InvalidLegacyERC20Address();

/// @notice Thrown when the SuperchainERC20 address is not found in the SuperchainERC20Factory.
error InvalidSuperchainAddress();
error InvalidSuperchainERC20Address();

/// @notice Thrown when the remote addresses of the tokens are not the same.
error InvalidTokenPair();

// TODO: Use an existing interface with `mint` and `burn`?
/// TODO: Define a better naming convention for this interface.
/// @notice Interface for minting and burning tokens in the L2StandardBridge.
/// Used for StandardL2ERC20, OptimismMintableERC20 and OptimismSuperchainERC20.
interface MintableAndBurnable is IERC20 {
function mint(address, uint256) external;
function burn(address, uint256) external;
Expand All @@ -39,6 +41,12 @@ contract L2StandardBridgeInterop is L2StandardBridge {
/// @param amount The amount of tokens being converted.
event Converted(address indexed from, address indexed to, address indexed caller, uint256 amount);

/// @notice Semantic version.
/// @custom:semver +interop
function version() public pure override returns (string memory) {
return string.concat(super.version(), "+interop");
}

/// @notice Converts `amount` of `from` token to `to` token.
/// @param _from The token being converted from.
/// @param _to The token being converted to.
Expand Down Expand Up @@ -74,12 +82,12 @@ contract L2StandardBridgeInterop is L2StandardBridge {
// 2. Valid legacy check
address _legacyRemoteToken =
IOptimismERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).deployments(_legacyAddr);
if (_legacyRemoteToken == address(0)) revert InvalidLegacyAddress();
if (_legacyRemoteToken == address(0)) revert InvalidLegacyERC20Address();

// 3. Valid SuperchainERC20 check
address _superRemoteToken =
IOptimismERC20Factory(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY).deployments(_superAddr);
if (_superRemoteToken == address(0)) revert InvalidSuperchainAddress();
if (_superRemoteToken == address(0)) revert InvalidSuperchainERC20Address();

// 4. Same remote address check
if (_legacyRemoteToken != _superRemoteToken) revert InvalidTokenPair();
Expand Down
3 changes: 2 additions & 1 deletion packages/contracts-bedrock/src/libraries/Predeploys.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ library Predeploys {
/// @notice Address of the ETHLiquidity predeploy.
address internal constant ETH_LIQUIDITY = 0x4200000000000000000000000000000000000025;

/// TODO: Add correct predeploy address for OptimismSuperchainERC20Factory
/// @notice Address of the OptimismSuperchainERC20Factory predeploy.
address internal constant OPTIMISM_SUPERCHAIN_ERC20_FACTORY = 0x4200000000000000000000000000000000000026;

Expand All @@ -107,7 +108,7 @@ library Predeploys {
if (_addr == WETH) return "WETH";
if (_addr == L2_CROSS_DOMAIN_MESSENGER) return "L2CrossDomainMessenger";
if (_addr == GAS_PRICE_ORACLE) return "GasPriceOracle";
if (_addr == L2_STANDARD_BRIDGE) return "L2StandardBridgeInterop";
if (_addr == L2_STANDARD_BRIDGE) return "L2StandardBridge";
if (_addr == SEQUENCER_FEE_WALLET) return "SequencerFeeVault";
if (_addr == OPTIMISM_MINTABLE_ERC20_FACTORY) return "OptimismMintableERC20Factory";
if (_addr == L1_BLOCK_NUMBER) return "L1BlockNumber";
Expand Down
42 changes: 24 additions & 18 deletions packages/contracts-bedrock/test/L2/L2StandardBridgeInterop.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { console2 } from "forge-std/console2.sol";
import {
L2StandardBridgeInterop,
InvalidDecimals,
InvalidLegacyAddress,
InvalidSuperchainAddress,
InvalidLegacyERC20Address,
InvalidSuperchainERC20Address,
InvalidTokenPair,
IOptimismERC20Factory,
MintableAndBurnable
Expand All @@ -26,6 +26,12 @@ contract L2StandardBridgeInterop_Test is Bridge_Initializer {
/// @notice Emitted when a conversion is made.
event Converted(address indexed from, address indexed to, address indexed caller, uint256 amount);

/// @notice Test setup.
function setUp() public virtual override {
super.enableInterop();
super.setUp();
}

/// @notice Helper function to setup a mock and expect a call to it.
function _mockAndExpect(address _receiver, bytes memory _calldata, bytes memory _returned) internal {
vm.mockCall(_receiver, _calldata, _returned);
Expand Down Expand Up @@ -97,23 +103,23 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T
l2StandardBridge.convert(_from, _to, _amount);
}

/// @notice Test that the `convert` function with an invalid legacy address reverts
function testFuzz_convert_invalidLegacyAddress_reverts(address _from, address _to, uint256 _amount) public {
/// @notice Test that the `convert` function with an invalid legacy ERC20 address reverts
function testFuzz_convert_invalidLegacyERC20Address_reverts(address _from, address _to, uint256 _amount) public {
// Arrange
_setUpLegacyToSuper(_from, _to);

// Mock the legacy factory to return address(0)
_mockDeployments(address(l2OptimismMintableERC20Factory), _from, address(0));

// Expect the revert with `InvalidLegacyAddress` selector
vm.expectRevert(InvalidLegacyAddress.selector);
// Expect the revert with `InvalidLegacyERC20Address` selector
vm.expectRevert(InvalidLegacyERC20Address.selector);

// Act
l2StandardBridge.convert(_from, _to, _amount);
}

/// @notice Test that the `convert` function with an invalid superchain address reverts
function testFuzz_convert_invalidSuperchainAddress_reverts(
/// @notice Test that the `convert` function with an invalid superchain ERC20 address reverts
function testFuzz_convert_invalidSuperchainERC20Address_reverts(
address _from,
address _to,
uint256 _amount,
Expand All @@ -133,8 +139,8 @@ contract L2StandardBridgeInterop_LegacyToSuper_Test is L2StandardBridgeInterop_T
// Mock the superchain factory to return address(0)
_mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _to, address(0));

// Expect the revert with `InvalidSuperchainAddress` selector
vm.expectRevert(InvalidSuperchainAddress.selector);
// Expect the revert with `InvalidSuperchainERC20Address` selector
vm.expectRevert(InvalidSuperchainERC20Address.selector);

// Act
l2StandardBridge.convert(_from, _to, _amount);
Expand Down Expand Up @@ -246,23 +252,23 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T
l2StandardBridge.convert(_from, _to, _amount);
}

/// @notice Test that the `convert` function with an invalid legacy address reverts
function testFuzz_convert_invalidLegacyAddress_reverts(address _from, address _to, uint256 _amount) public {
/// @notice Test that the `convert` function with an invalid legacy ERC20 address reverts
function testFuzz_convert_invalidLegacyERC20Address_reverts(address _from, address _to, uint256 _amount) public {
// Arrange
_setUpSuperToLegacy(_from, _to);

// Mock the legacy factory to return address(0)
_mockDeployments(address(l2OptimismMintableERC20Factory), _to, address(0));

// Expect the revert with `InvalidLegacyAddress` selector
vm.expectRevert(InvalidLegacyAddress.selector);
// Expect the revert with `InvalidLegacyERC20Address` selector
vm.expectRevert(InvalidLegacyERC20Address.selector);

// Act
l2StandardBridge.convert(_from, _to, _amount);
}

/// @notice Test that the `convert` function with an invalid superchain address reverts
function testFuzz_convert_invalidSuperchainAddress_reverts(
/// @notice Test that the `convert` function with an invalid superchain ERC20 address reverts
function testFuzz_convert_invalidSuperchainERC20Address_reverts(
address _from,
address _to,
uint256 _amount,
Expand All @@ -282,8 +288,8 @@ contract L2StandardBridgeInterop_SuperToLegacy_Test is L2StandardBridgeInterop_T
// Mock the superchain factory to return address(0)
_mockDeployments(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY, _from, address(0));

// Expect the revert with `InvalidSuperchainAddress` selector
vm.expectRevert(InvalidSuperchainAddress.selector);
// Expect the revert with `InvalidSuperchainERC20Address` selector
vm.expectRevert(InvalidSuperchainERC20Address.selector);

// Act
l2StandardBridge.convert(_from, _to, _amount);
Expand Down

0 comments on commit 809a71b

Please sign in to comment.