Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: refactor zero check #76

Merged
merged 1 commit into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/contracts-bedrock/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
"sourceCodeHash": "0x4b806cc85cead74c8df34ab08f4b6c6a95a1a387a335ec8a7cb2de4ea4e1cf41"
},
"src/L2/OptimismSuperchainERC20.sol": {
"initCodeHash": "0xfdb4acd9496a7d3949f71e7e98786ff909730a8ad62d33cf7e29765dceecc6db",
"initCodeHash": "0xc6452d9aef6d76bdc789f3cddac6862658a481c619e6a2e7a74f6d61147f927b",
"sourceCodeHash": "0x2502433e4b622e1697ca071f91a95b08fa40fdb03bfd958c44b2033a47df2010"
},
"src/L2/OptimismSuperchainERC20Beacon.sol": {
Expand All @@ -133,11 +133,11 @@
},
"src/L2/SuperchainERC20.sol": {
"initCodeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
"sourceCodeHash": "0xddd32f6332510e63d8c98d70321e058b71eda02e6b32a9b6e41540c58d1e653e"
"sourceCodeHash": "0x9bc2e208774eb923894dbe391a5038a6189d7d36c202f4bf3e2c4dd332b0adf0"
},
"src/L2/SuperchainERC20Bridge.sol": {
"initCodeHash": "0x77d3173e1f269f6bf57f85685abecb4979a7d7d3c672c7afa2a648b66228122f",
"sourceCodeHash": "0xf0749a0b9366a06981d2a8f66a55ce1a37e3d5d7dd77704f618741c18cd79009"
"initCodeHash": "0xa21232df1d7239fd20e7eaa320cfc91efc76343c93d833d8060a58b54ac5c8bf",
"sourceCodeHash": "0x83188d878ce0b2890a7f7f41d09a8807f94a126e0ea274f0dac8b93f77217d3b"
},
"src/L2/SuperchainWETH.sol": {
"initCodeHash": "0xf30071df59d85e0e8a552845031aca8d6f0261762e1b4ea1b28ff30379eaa20e",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@
"type": "uint256"
}
],
"name": "SuperchainBurn",
"name": "SuperchainBurnt",
"type": "event"
},
{
Expand All @@ -507,7 +507,7 @@
"type": "uint256"
}
],
"name": "SuperchainMint",
"name": "SuperchainMinted",
"type": "event"
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,5 +151,10 @@
"inputs": [],
"name": "InvalidCrossDomainSender",
"type": "error"
},
{
"inputs": [],
"name": "ZeroAddress",
"type": "error"
}
]
8 changes: 2 additions & 6 deletions packages/contracts-bedrock/src/L2/SuperchainERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,17 @@ abstract contract SuperchainERC20 is ERC20, ISuperchainERC20Extension, ISemver {
/// @param _to Address to mint tokens to.
/// @param _amount Amount of tokens to mint.
function __superchainMint(address _to, uint256 _amount) external virtual onlySuperchainERC20Bridge {
if (_to == address(0)) revert ZeroAddress();

_mint(_to, _amount);

emit SuperchainMint(_to, _amount);
emit SuperchainMinted(_to, _amount);
}

/// @notice Allows the SuperchainERC20Bridge to burn tokens.
/// @param _from Address to burn tokens from.
/// @param _amount Amount of tokens to burn.
function __superchainBurn(address _from, uint256 _amount) external virtual onlySuperchainERC20Bridge {
if (_from == address(0)) revert ZeroAddress();

_burn(_from, _amount);

emit SuperchainBurn(_from, _amount);
emit SuperchainBurnt(_from, _amount);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
emit SuperchainBurnt(_from, _amount);
emit SuperchainBurned(_from, _amount);

}
}
2 changes: 2 additions & 0 deletions packages/contracts-bedrock/src/L2/SuperchainERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ contract SuperchainERC20Bridge is ISuperchainERC20Bridge {
/// @param _amount Amount of tokens to send.
/// @param _chainId Chain ID of the destination chain.
function sendERC20(address _token, address _to, uint256 _amount, uint256 _chainId) external {
if (_to == address(0)) revert ZeroAddress();

ISuperchainERC20(_token).__superchainBurn(msg.sender, _amount);

bytes memory message = abi.encodeCall(this.relayERC20, (_token, msg.sender, _to, _amount));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { IERC20Solady } from "src/vendor/interfaces/IERC20Solady.sol";
/// @title IOptimismSuperchainERC20Errors
/// @notice Interface containing the errors added in the OptimismSuperchainERC20 implementation.
interface IOptimismSuperchainERC20Errors {
/// @notice Thrown when attempting to perform an operation and the account is the zero address.
error ZeroAddress();

/// @notice Thrown when attempting to mint or burn tokens and the function caller is not the L2StandardBridge
error OnlyL2StandardBridge();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import { IERC20Solady } from "src/vendor/interfaces/IERC20Solady.sol";
/// @title ISuperchainERC20Errors
/// @notice Interface containing the errors added in the SuperchainERC20 implementation.
interface ISuperchainERC20Errors {
/// @notice Thrown when attempting to perform an operation and the account is the zero address.
error ZeroAddress();

/// @notice Thrown when attempting to mint or burn tokens and the function caller is not the SuperchainERC20Bridge.
error OnlySuperchainERC20Bridge();
}
Expand All @@ -20,12 +17,12 @@ interface ISuperchainERC20Extension is ISuperchainERC20Errors {
/// @notice Emitted whenever tokens are minted for by the SuperchainERC20Bridge.
/// @param account Address of the account tokens are being minted for.
/// @param amount Amount of tokens minted.
event SuperchainMint(address indexed account, uint256 amount);
event SuperchainMinted(address indexed account, uint256 amount);

/// @notice Emitted whenever tokens are burned by the SuperchainERC20Bridge.
/// @param account Address of the account tokens are being burned from.
/// @param amount Amount of tokens burned.
event SuperchainBurn(address indexed account, uint256 amount);
event SuperchainBurnt(address indexed account, uint256 amount);

/// @notice Allows the SuperchainERC20Bridge to mint tokens.
/// @param _to Address to mint tokens to.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol";
/// @title ISuperchainERC20Bridge
/// @notice Interface for the SuperchainERC20Bridge contract.
interface ISuperchainERC20Bridge is ISemver {
/// @notice Thrown when attempting to perform an operation and the account is the zero address.
error ZeroAddress();

/// @notice Thrown when attempting to relay a message and the function caller (msg.sender) is not
/// L2ToL2CrossDomainMessenger.
error CallerNotL2ToL2CrossDomainMessenger();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
IOptimismSuperchainERC20Extension,
IOptimismSuperchainERC20Errors
} from "src/L2/interfaces/IOptimismSuperchainERC20.sol";
import { ISuperchainERC20Errors } from "src/L2/interfaces/ISuperchainERC20.sol";

/// @title OptimismSuperchainERC20Test
/// @notice Contract for testing the OptimismSuperchainERC20 contract.
Expand Down Expand Up @@ -133,7 +132,7 @@ contract OptimismSuperchainERC20Test is Test {
/// @notice Tests the `mint` function reverts when the amount is zero.
function testFuzz_mint_zeroAddressTo_reverts(uint256 _amount) public {
// Expect the revert with `ZeroAddress` selector
vm.expectRevert(ISuperchainERC20Errors.ZeroAddress.selector);
vm.expectRevert(IOptimismSuperchainERC20Errors.ZeroAddress.selector);

// Call the `mint` function with the zero address
vm.prank(L2_BRIDGE);
Expand Down Expand Up @@ -182,7 +181,7 @@ contract OptimismSuperchainERC20Test is Test {
/// @notice Tests the `burn` function reverts when the amount is zero.
function testFuzz_burn_zeroAddressFrom_reverts(uint256 _amount) public {
// Expect the revert with `ZeroAddress` selector
vm.expectRevert(ISuperchainERC20Errors.ZeroAddress.selector);
vm.expectRevert(IOptimismSuperchainERC20Errors.ZeroAddress.selector);

// Call the `burn` function with the zero address
vm.prank(L2_BRIDGE);
Expand Down
30 changes: 5 additions & 25 deletions packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,6 @@ contract SuperchainERC20Test is Test {
superchainERC20.__superchainMint(_to, _amount);
}

/// @notice Tests the `mint` function reverts when the amount is zero.
function testFuzz___superchainMint_zeroAddressTo_reverts(uint256 _amount) public {
// Expect the revert with `ZeroAddress` selector
vm.expectRevert(ISuperchainERC20Errors.ZeroAddress.selector);

// Call the `mint` function with the zero address
vm.prank(SUPERCHAIN_ERC20_BRIDGE);
superchainERC20.__superchainMint({ _to: ZERO_ADDRESS, _amount: _amount });
}

/// @notice Tests the `mint` succeeds and emits the `Mint` event.
function testFuzz___superchainMint_succeeds(address _to, uint256 _amount) public {
// Ensure `_to` is not the zero address
Expand All @@ -85,9 +75,9 @@ contract SuperchainERC20Test is Test {
vm.expectEmit(address(superchainERC20));
emit IERC20.Transfer(ZERO_ADDRESS, _to, _amount);

// Look for the emit of the `SuperchainMint` event
// Look for the emit of the `SuperchainMinted` event
vm.expectEmit(address(superchainERC20));
emit ISuperchainERC20Extension.SuperchainMint(_to, _amount);
emit ISuperchainERC20Extension.SuperchainMinted(_to, _amount);

// Call the `mint` function with the bridge caller
vm.prank(SUPERCHAIN_ERC20_BRIDGE);
Expand Down Expand Up @@ -117,17 +107,7 @@ contract SuperchainERC20Test is Test {
superchainERC20.__superchainBurn(_from, _amount);
}

/// @notice Tests the `burn` function reverts when the amount is zero.
function testFuzz___superchainBurn_zeroAddressFrom_reverts(uint256 _amount) public {
// Expect the revert with `ZeroAddress` selector
vm.expectRevert(ISuperchainERC20Errors.ZeroAddress.selector);

// Call the `burn` function with the zero address
vm.prank(SUPERCHAIN_ERC20_BRIDGE);
superchainERC20.__superchainBurn({ _from: ZERO_ADDRESS, _amount: _amount });
}

/// @notice Tests the `burn` burns the amount and emits the `Burn` event.
/// @notice Tests the `burn` burns the amount and emits the `SuperchainBurnt` event.
function testFuzz___superchainBurn_succeeds(address _from, uint256 _amount) public {
// Ensure `_from` is not the zero address
vm.assume(_from != ZERO_ADDRESS);
Expand All @@ -144,9 +124,9 @@ contract SuperchainERC20Test is Test {
vm.expectEmit(address(superchainERC20));
emit IERC20.Transfer(_from, ZERO_ADDRESS, _amount);

// Look for the emit of the `Burn` event
// Look for the emit of the `SuperchainBurnt` event
vm.expectEmit(address(superchainERC20));
emit ISuperchainERC20Extension.SuperchainBurn(_from, _amount);
emit ISuperchainERC20Extension.SuperchainBurnt(_from, _amount);

// Call the `burn` function with the bridge caller
vm.prank(SUPERCHAIN_ERC20_BRIDGE);
Expand Down
10 changes: 10 additions & 0 deletions packages/contracts-bedrock/test/L2/SuperchainERC20Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ contract SuperchainERC20BridgeTest is Bridge_Initializer {
vm.expectCall(_receiver, _calldata);
}

/// @notice Tests the `sendERC20` function reverts when the address `_to` is zero.
function testFuzz_sendERC20_zeroAddressTo_reverts(address _sender, uint256 _amount, uint256 _chainId) public {
// Expect the revert with `ZeroAddress` selector
vm.expectRevert(ISuperchainERC20Bridge.ZeroAddress.selector);

// Call the `sendERC20` function with the zero address as `_to`
vm.prank(_sender);
superchainERC20Bridge.sendERC20(address(superchainERC20), ZERO_ADDRESS, _amount, _chainId);
}

/// @notice Tests the `sendERC20` function burns the sender tokens, sends the message, and emits the `SendERC20`
/// event.
function testFuzz_sendERC20_succeeds(address _sender, address _to, uint256 _amount, uint256 _chainId) external {
Expand Down