-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add SuperchainERC20 baseline (#11675)
* feat: add superchain erc20 baseline (#37) * feat: add superchain erc20 baseline * feat: make superchain ERC20 simpler * fix: small version fix and tests * test: fix test name * test: remove unused import * feat: making baseline abstract * fix: interfaces to comply with the new interface checker * fix: import paths and empty line * fix: lint line --------- Co-authored-by: 0xng <[email protected]> Co-authored-by: 0xng <[email protected]>
- Loading branch information
1 parent
7efa4e7
commit 9968aa3
Showing
8 changed files
with
424 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.25; | ||
|
||
import { ISuperchainERC20Extensions, ISuperchainERC20Errors } from "src/L2/interfaces/ISuperchainERC20.sol"; | ||
import { ERC20 } from "@solady/tokens/ERC20.sol"; | ||
import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomainMessenger.sol"; | ||
import { Predeploys } from "src/libraries/Predeploys.sol"; | ||
|
||
/// @title SuperchainERC20 | ||
/// @notice SuperchainERC20 is a standard extension of the base ERC20 token contract that unifies ERC20 token | ||
/// bridging to make it fungible across the Superchain. It builds on top of the L2ToL2CrossDomainMessenger for | ||
/// both replay protection and domain binding. | ||
abstract contract SuperchainERC20 is ISuperchainERC20Extensions, ISuperchainERC20Errors, ERC20 { | ||
/// @notice Address of the L2ToL2CrossDomainMessenger Predeploy. | ||
address internal constant MESSENGER = Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER; | ||
|
||
/// @notice Sends tokens to some target address on another chain. | ||
/// @param _to Address to send tokens to. | ||
/// @param _amount Amount of tokens to send. | ||
/// @param _chainId Chain ID of the destination chain. | ||
function sendERC20(address _to, uint256 _amount, uint256 _chainId) external virtual { | ||
if (_to == address(0)) revert ZeroAddress(); | ||
|
||
_burn(msg.sender, _amount); | ||
|
||
bytes memory _message = abi.encodeCall(this.relayERC20, (msg.sender, _to, _amount)); | ||
IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), _message); | ||
|
||
emit SendERC20(msg.sender, _to, _amount, _chainId); | ||
} | ||
|
||
/// @notice Relays tokens received from another chain. | ||
/// @param _from Address of the msg.sender of sendERC20 on the source chain. | ||
/// @param _to Address to relay tokens to. | ||
/// @param _amount Amount of tokens to relay. | ||
function relayERC20(address _from, address _to, uint256 _amount) external virtual { | ||
if (msg.sender != MESSENGER) revert CallerNotL2ToL2CrossDomainMessenger(); | ||
|
||
if (IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSender() != address(this)) { | ||
revert InvalidCrossDomainSender(); | ||
} | ||
|
||
uint256 source = IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSource(); | ||
|
||
_mint(_to, _amount); | ||
|
||
emit RelayERC20(_from, _to, _amount, source); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
packages/contracts-bedrock/src/dependency/interfaces/IERC20Solady.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
interface IERC20Solady { | ||
/// @dev The total supply has overflowed. | ||
error TotalSupplyOverflow(); | ||
|
||
/// @dev The allowance has overflowed. | ||
error AllowanceOverflow(); | ||
|
||
/// @dev The allowance has underflowed. | ||
error AllowanceUnderflow(); | ||
|
||
/// @dev Insufficient balance. | ||
error InsufficientBalance(); | ||
|
||
/// @dev Insufficient allowance. | ||
error InsufficientAllowance(); | ||
|
||
/// @dev The permit is invalid. | ||
error InvalidPermit(); | ||
|
||
/// @dev The permit has expired. | ||
error PermitExpired(); | ||
|
||
/// @dev Emitted when `amount` tokens is transferred from `from` to `to`. | ||
event Transfer(address indexed from, address indexed to, uint256 amount); | ||
|
||
/// @dev Emitted when `amount` tokens is approved by `owner` to be used by `spender`. | ||
event Approval(address indexed owner, address indexed spender, uint256 amount); | ||
|
||
/// @dev Returns the name of the token. | ||
function name() external view returns (string memory); | ||
|
||
/// @dev Returns the symbol of the token. | ||
function symbol() external view returns (string memory); | ||
|
||
/// @dev Returns the decimals places of the token. | ||
function decimals() external view returns (uint8); | ||
|
||
/// @dev Returns the amount of tokens in existence. | ||
function totalSupply() external view returns (uint256 result); | ||
|
||
/// @dev Returns the amount of tokens owned by `owner` | ||
function balanceOf(address owner) external view returns (uint256 result); | ||
|
||
/// @dev Returns the amount of tokens that `spender` can spend on behalf of `owner`. | ||
function allowance(address owner, address spender) external view returns (uint256 result); | ||
|
||
/// @dev Sets `amount` as the allowance of `spender` over the caller's tokens. | ||
/// | ||
/// Emits a {Approval} event. | ||
function approve(address spender, uint256 amount) external returns (bool); | ||
|
||
/// @dev Transfer `amount` tokens from the caller to `to`. | ||
/// | ||
/// Requirements: | ||
/// - `from` must at least have `amount`. | ||
/// | ||
/// Emits a {Transfer} event. | ||
function transfer(address to, uint256 amount) external returns (bool); | ||
|
||
/// @dev Transfers `amount` tokens from `from` to `to`. | ||
/// | ||
/// Note: Does not update the allowance if it is the maximum uint256 value. | ||
/// | ||
/// Requirements: | ||
/// - `from` must at least have `amount`. | ||
/// - The caller must have at least `amount` of allowance to transfer the tokens of `from`. | ||
/// | ||
/// Emits a {Transfer} event. | ||
function transferFrom(address from, address to, uint256 amount) external returns (bool); | ||
|
||
/// @dev Returns the current nonce for `owner`. | ||
/// This value is used to compute the signature for EIP-2612 permit. | ||
function nonces(address owner) external view returns (uint256 result); | ||
|
||
/// @dev Sets `value` as the allowance of `spender` over the tokens of `owner`, | ||
/// authorized by a signed approval by `owner`. | ||
/// | ||
/// Emits a {Approval} event. | ||
function permit( | ||
address owner, | ||
address spender, | ||
uint256 value, | ||
uint256 deadline, | ||
uint8 v, | ||
bytes32 r, | ||
bytes32 s | ||
) | ||
external; | ||
|
||
/// @dev Returns the EIP-712 domain separator for the EIP-2612 permit. | ||
function DOMAIN_SEPARATOR() external view returns (bytes32 result); | ||
} |
Oops, something went wrong.