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

feat: superchain erc20 redesign #73

Draft
wants to merge 11 commits into
base: develop
Choose a base branch
from

Conversation

agusduha
Copy link
Member

@agusduha agusduha commented Oct 1, 2024

No description provided.

agusduha and others added 6 commits September 25, 2024 15:20
* feat: add superchain erc20 bridge

* fix: interfaces and versions
* refactor: use oz upgradeable erc20 as dependency

* chore: update interfaces

* fix: tests based on changes

* refactor: remove op as dependency

* feat: add check for supererc20 bridge on modifier

* chore: update tests and interfaces

* chore: update stack vars name on test

* chore: remove empty gitmodules file

* chore: update superchain weth errors
* test: add superchain erc20 bridge tests

* test: add optimism superchain erc20 beacon tests

* test: remove unnecessary test

* test: tests fixes

* test: tests fixes
* chore: update missing bridge on natspec

* fix: natspecs

---------

Co-authored-by: agusduha <[email protected]>
* refactor: rename mint and burn functions on superchain erc20

* chore: rename optimism superchain erc20 to superchain erc20

* feat: create optimism superchain erc20 contract

* chore: update natspec and errors

* fix: superchain erc20 tests

* refactor: make superchain erc20 abstract

* refactor: move storage and erc20 metadata functions to implementation

* chore: update interfaces

* chore: update superchain erc20 events

* fix: tests

* fix: natspecs

* fix: add semmver lock and snapshots

* fix: remove unused imports

* fix: natspecs

---------

Co-authored-by: 0xDiscotech <[email protected]>
Copy link

@0xParticle 0xParticle left a comment

Choose a reason for hiding this comment

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

Amazing work guys <3

/// @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();

Choose a reason for hiding this comment

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

whats the reason to enforce this revert in the standard?
Also, if you go this path, why revert here and not in the SuperchainERC20Bridge and save an external call?

/// @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();

Choose a reason for hiding this comment

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

same


/// @title SuperchainWETH
/// @notice SuperchainWETH is a version of WETH that can be freely transfrered between chains
/// within the superchain. SuperchainWETH can be converted into native ETH on chains that
/// do not use a custom gas token.
contract SuperchainWETH is WETH98, ISuperchainERC20Extensions, ISemver {
contract SuperchainWETH is WETH98, ISuperchainWETH, ISemver {

Choose a reason for hiding this comment

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

I was not involved with SuperchainWETH, but it seems like the design has a lot of differences with the SuperchainERC20 now. Can we push for an implementation update here?

/// @notice Tests the `relayERC20` mints the proper amount and emits the `RelayERC20` event.
function testFuzz_relayERC20_succeeds(address _from, address _to, uint256 _amount, uint256 _source) public {
/// @notice Tests the `burn` burns the amount and emits the `Burn` event.
function testFuzz___superchainBurn_succeeds(address _from, uint256 _amount) public {

Choose a reason for hiding this comment

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

you can add the new SuperchainBurn event emision check here. Same for SuperchainMint where it belongs

Copy link
Member

@0xng 0xng left a comment

Choose a reason for hiding this comment

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

Looks good guys!

Run all added/modified tests with the flag --fuzz-runs 100000 if possible so we reduce the possibilities of getting flaky errors.

A general question I have is, we are mentioning L2StandardBridge in many places when the actual contract is called L2StandardBridgeInterop. Should we change it to that, or given that it will most likely be merged into one eventually just leave it at L2StandardBridge. What do you think?

/// @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();
Copy link
Member

Choose a reason for hiding this comment

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

not sure how i feel about having this check, it feels opinionated, users calling this can check it themselves if they want, tokens extending it can add it.

also minting happens async, so after the burn, so if the _to is address 0, the user will lose the tokens either way - if anything this check should be in the bridge

bytes memory message = abi.encodeCall(this.relayERC20, (_token, msg.sender, _to, _amount));
IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), message);

emit SendERC20(_token, msg.sender, _to, _amount, _chainId);
Copy link
Member

Choose a reason for hiding this comment

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

Let's stick to past tense like we do for all events for cohesion in the codebase, same in relayERC20. I know these are in present tense in the standard but we should change that

/// @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 {
Copy link
Member

Choose a reason for hiding this comment

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

the standard says these should be public, we can modify the standard for them to be external also if we prefer it

Choose a reason for hiding this comment

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

oh good catch, I rather have them external to enforce the sender check :)

/// @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();
Copy link
Member

Choose a reason for hiding this comment

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

same with this check, not fully convinced it's needed here

Comment on lines +31 to +40
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));
IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), message);

emit SendERC20(_token, msg.sender, _to, _amount, _chainId);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants