-
Notifications
You must be signed in to change notification settings - Fork 39
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
[WIP] wstETH on Mantle, DON'T MERGE #52
Changes from all commits
868d403
ef95584
69588a1
871c104
84f7f95
1408c8d
2d4a6e9
0ab4478
85a4ffe
9ea9635
5c318d8
c02d936
d5d8cd5
cdd513c
a76df23
75e023a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# Detailed info: https://github.com/lidofinance/lido-l2#Project-Configuration | ||
|
||
# ############################ | ||
# RPCs | ||
# ############################ | ||
|
||
RPC_ETH_GOERLI=https://eth-goerli.g.alchemy.com/v2/ | ||
RPC_MNT_GOERLI=https://rpc.testnet.mantle.xyz | ||
|
||
# ############################ | ||
# Etherscan | ||
# ############################ | ||
|
||
ETHERSCAN_API_KEY_ETH= | ||
ETHERSCAN_API_KEY_MNT= | ||
|
||
# ############################ | ||
# Bridge/Gateway Deployment | ||
# ############################ | ||
|
||
# Address of the token to deploy the bridge/gateway for wstETH | ||
TOKEN=0x6320cd32aa674d2898a68ec82e869385fc5f7e2f | ||
|
||
# Name of the network environments used by deployment scripts. | ||
# Might be one of: "mainnet", "goerli". | ||
NETWORK=goerli | ||
|
||
# Private key of the deployer account used for deployment process | ||
ETH_DEPLOYER_PRIVATE_KEY= | ||
MNT_DEPLOYER_PRIVATE_KEY= | ||
|
||
L1_PROXY_ADMIN=0x4333218072D5d7008546737786663c38B4D561A4 | ||
L1_BRIDGE_ADMIN=0x4333218072D5d7008546737786663c38B4D561A4 | ||
L1_DEPOSITS_ENABLED=true | ||
L1_WITHDRAWALS_ENABLED=true | ||
L1_DEPOSITS_ENABLERS=["0x4333218072D5d7008546737786663c38B4D561A4"] | ||
L1_DEPOSITS_DISABLERS="["0x4333218072D5d7008546737786663c38B4D561A4", "0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd","0xa6688D0DcAd346eCc275cda98c91086fEC3fE31C"]" | ||
L1_WITHDRAWALS_ENABLERS=["0x4333218072D5d7008546737786663c38B4D561A4"] | ||
L1_WITHDRAWALS_DISABLERS="["0x4333218072D5d7008546737786663c38B4D561A4", "0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd","0xa6688D0DcAd346eCc275cda98c91086fEC3fE31C"]" | ||
|
||
L2_PROXY_ADMIN=0xaF3dcfddBbBC59E7d2ec6f6e4273f7F1a3C7B6fe | ||
L2_BRIDGE_ADMIN=0xaF3dcfddBbBC59E7d2ec6f6e4273f7F1a3C7B6fe | ||
L2_DEPOSITS_ENABLED=true | ||
L2_WITHDRAWALS_ENABLED=true | ||
L2_DEPOSITS_ENABLERS=["0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35"] | ||
L2_DEPOSITS_DISABLERS="["0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35", "0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"]" | ||
L2_WITHDRAWALS_ENABLERS=["0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35"] | ||
L2_WITHDRAWALS_DISABLERS="["0x55C39356C714Cde16F8a80302c1Ce9DfAC6f5a35", "0x7fE7fa4EF7D134Dbf8B616Ba7B675F26286BC2cd"]" | ||
|
||
# ############################ | ||
# Integration & E2E Testing | ||
# ############################ | ||
|
||
TESTING_MNT_NETWORK=goerli | ||
TESTING_MNT_L1_TOKEN=0x6320cd32aa674d2898a68ec82e869385fc5f7e2f | ||
TESTING_MNT_L2_TOKEN=0xe8964a99d5DE7cEE2743B20113a52C953b0916E9 | ||
TESTING_MNT_L1_ERC20_TOKEN_BRIDGE=0xDdC89Bd27F9A1C47A5c20dF0783dE52f55513598 | ||
TESTING_MNT_L2_ERC20_TOKEN_BRIDGE=0x423702bC3Fb92f59Be440354456f0481934bF1f5 | ||
|
||
# ############################ | ||
# Integration Testing | ||
# ############################ | ||
|
||
TESTING_USE_DEPLOYED_CONTRACTS=true | ||
TESTING_L1_TOKENS_HOLDER= | ||
|
||
# ############################ | ||
# E2E Testing | ||
# ############################ | ||
|
||
TESTING_PRIVATE_KEY= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Detailed info: https://github.com/lidofinance/lido-l2#Project-Configuration | ||
|
||
# ############################ | ||
# RPCs | ||
# ############################ | ||
|
||
RPC_ETH_MAINNET= | ||
RPC_OPT_MAINNET= | ||
|
||
# ############################ | ||
# Etherscan | ||
# ############################ | ||
|
||
ETHERSCAN_API_KEY_ETH= | ||
ETHERSCAN_API_KEY_OPT= | ||
|
||
# ############################ | ||
# Bridge/Gateway Deployment | ||
# ############################ | ||
|
||
# Address of the token to deploy the bridge/gateway for | ||
TOKEN=0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 | ||
|
||
# Name of the network environments used by deployment scripts. | ||
# Might be one of: "mainnet", "goerli". | ||
NETWORK=mainnet | ||
|
||
# Run deployment in the forking network instead of public ones | ||
FORKING=true | ||
|
||
# Private key of the deployer account used for deployment process | ||
ETH_DEPLOYER_PRIVATE_KEY= | ||
OPT_DEPLOYER_PRIVATE_KEY= | ||
|
||
L1_PROXY_ADMIN=0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c | ||
L1_BRIDGE_ADMIN=0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c | ||
L1_DEPOSITS_ENABLED=false | ||
L1_WITHDRAWALS_ENABLED=true | ||
L1_DEPOSITS_ENABLERS=["0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c","0x3cd9F71F80AB08ea5a7Dca348B5e94BC595f26A0"] | ||
L1_DEPOSITS_DISABLERS=["0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c","0x73b047fe6337183A454c5217241D780a932777bD"] | ||
L1_WITHDRAWALS_ENABLERS=["0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c"] | ||
L1_WITHDRAWALS_DISABLERS=["0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c","0x73b047fe6337183A454c5217241D780a932777bD"] | ||
|
||
L2_PROXY_ADMIN=0xEfa0dB536d2c8089685630fafe88CF7805966FC3 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optimism There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No Safe on Mantle? |
||
L2_BRIDGE_ADMIN=0xEfa0dB536d2c8089685630fafe88CF7805966FC3 | ||
L2_DEPOSITS_ENABLED=true | ||
L2_WITHDRAWALS_ENABLED=true | ||
L2_DEPOSITS_ENABLERS=["0xEfa0dB536d2c8089685630fafe88CF7805966FC3"] | ||
L2_DEPOSITS_DISABLERS=["0xEfa0dB536d2c8089685630fafe88CF7805966FC3","0x4Cf8fE0A4c2539F7EFDD2047d8A5D46F14613088"] | ||
L2_WITHDRAWALS_ENABLERS=["0xEfa0dB536d2c8089685630fafe88CF7805966FC3"] | ||
L2_WITHDRAWALS_DISABLERS=["0xEfa0dB536d2c8089685630fafe88CF7805966FC3","0x4Cf8fE0A4c2539F7EFDD2047d8A5D46F14613088"] | ||
|
||
# ############################ | ||
# Integration Acceptance & E2E Testing | ||
# ############################ | ||
|
||
TESTING_OPT_NETWORK=mainnet | ||
TESTING_OPT_L1_TOKEN=0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 | ||
TESTING_OPT_L2_TOKEN=0x1F32b1c2345538c0c6f582fCB022739c4A194Ebb | ||
TESTING_OPT_L1_ERC20_TOKEN_BRIDGE=0x76943C0D61395d8F2edF9060e1533529cAe05dE6 | ||
TESTING_OPT_L2_ERC20_TOKEN_BRIDGE=0x8E01013243a96601a86eb3153F0d9Fa4fbFb6957 | ||
|
||
# ############################ | ||
# Integration Testing | ||
# ############################ | ||
|
||
TESTING_USE_DEPLOYED_CONTRACTS=true | ||
TESTING_L1_TOKENS_HOLDER= | ||
|
||
# ############################ | ||
# E2E Testing | ||
# ############################ | ||
|
||
TESTING_PRIVATE_KEY= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
module.exports = { | ||
skipFiles: ["stubs", "optimism/stubs", "proxy/stubs", "arbitrum/stubs"], | ||
skipFiles: ["stubs", "optimism/stubs", "proxy/stubs", "arbitrum/stubs", "mantle/stubs"], | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// SPDX-FileCopyrightText: 2022 Lido <[email protected]> | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
pragma solidity 0.8.10; | ||
|
||
import {ICrossDomainMessenger} from "./interfaces/ICrossDomainMessenger.sol"; | ||
|
||
/// @dev Helper contract for contracts performing cross-domain communications | ||
contract CrossDomainEnabled { | ||
/// @notice Messenger contract used to send and receive messages from the other domain | ||
ICrossDomainMessenger public immutable messenger; | ||
|
||
/// @param messenger_ Address of the CrossDomainMessenger on the current layer | ||
constructor(address messenger_) { | ||
messenger = ICrossDomainMessenger(messenger_); | ||
} | ||
|
||
/// @dev Sends a message to an account on another domain | ||
/// @param crossDomainTarget_ Intended recipient on the destination domain | ||
/// @param message_ Data to send to the target (usually calldata to a function with | ||
/// `onlyFromCrossDomainAccount()`) | ||
/// @param gasLimit_ gasLimit for the receipt of the message on the target domain. | ||
function sendCrossDomainMessage( | ||
address crossDomainTarget_, | ||
uint32 gasLimit_, | ||
bytes memory message_ | ||
) internal { | ||
messenger.sendMessage(crossDomainTarget_, message_, gasLimit_); | ||
} | ||
|
||
/// @dev Enforces that the modified function is only callable by a specific cross-domain account | ||
/// @param sourceDomainAccount_ The only account on the originating domain which is | ||
/// authenticated to call this function | ||
modifier onlyFromCrossDomainAccount(address sourceDomainAccount_) { | ||
if (msg.sender != address(messenger)) { | ||
revert ErrorUnauthorizedMessenger(); | ||
} | ||
if (messenger.xDomainMessageSender() != sourceDomainAccount_) { | ||
revert ErrorWrongCrossDomainSender(); | ||
} | ||
_; | ||
} | ||
|
||
error ErrorUnauthorizedMessenger(); | ||
error ErrorWrongCrossDomainSender(); | ||
} | ||
Comment on lines
+9
to
+46
Check failure Code scanning / Slither Name reused High |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
// SPDX-FileCopyrightText: 2022 Lido <[email protected]> | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
pragma solidity 0.8.10; | ||
|
||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import {Address} from "@openzeppelin/contracts/utils/Address.sol"; | ||
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; | ||
|
||
import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol"; | ||
import {IL2ERC20Bridge} from "./interfaces/IL2ERC20Bridge.sol"; | ||
|
||
import {BridgingManager} from "../BridgingManager.sol"; | ||
import {BridgeableTokens} from "../BridgeableTokens.sol"; | ||
import {CrossDomainEnabled} from "./CrossDomainEnabled.sol"; | ||
|
||
/// @author psirex | ||
/// @notice The L1 ERC20 token bridge locks bridged tokens on the L1 side, sends deposit messages | ||
/// on the L2 side, and finalizes token withdrawals from L2. Additionally, adds the methods for | ||
/// bridging management: enabling and disabling withdrawals/deposits | ||
contract L1ERC20TokenBridge is | ||
IL1ERC20Bridge, | ||
BridgingManager, | ||
BridgeableTokens, | ||
CrossDomainEnabled | ||
{ | ||
using SafeERC20 for IERC20; | ||
|
||
/// @inheritdoc IL1ERC20Bridge | ||
address public immutable l2TokenBridge; | ||
|
||
/// @param messenger_ L1 messenger address being used for cross-chain communications | ||
/// @param l2TokenBridge_ Address of the corresponding L2 bridge | ||
/// @param l1Token_ Address of the bridged token in the L1 chain | ||
/// @param l2Token_ Address of the token minted on the L2 chain when token bridged | ||
constructor( | ||
address messenger_, | ||
address l2TokenBridge_, | ||
address l1Token_, | ||
address l2Token_ | ||
) CrossDomainEnabled(messenger_) BridgeableTokens(l1Token_, l2Token_) { | ||
l2TokenBridge = l2TokenBridge_; | ||
} | ||
|
||
/// @inheritdoc IL1ERC20Bridge | ||
function depositERC20( | ||
address l1Token_, | ||
address l2Token_, | ||
uint256 amount_, | ||
uint32 l2Gas_, | ||
bytes calldata data_ | ||
) | ||
external | ||
whenDepositsEnabled | ||
onlySupportedL1Token(l1Token_) | ||
onlySupportedL2Token(l2Token_) | ||
{ | ||
if (Address.isContract(msg.sender)) { | ||
revert ErrorSenderNotEOA(); | ||
} | ||
_initiateERC20Deposit(msg.sender, msg.sender, amount_, l2Gas_, data_); | ||
} | ||
|
||
/// @inheritdoc IL1ERC20Bridge | ||
function depositERC20To( | ||
address l1Token_, | ||
address l2Token_, | ||
address to_, | ||
uint256 amount_, | ||
uint32 l2Gas_, | ||
bytes calldata data_ | ||
) | ||
external | ||
whenDepositsEnabled | ||
onlyNonZeroAccount(to_) | ||
onlySupportedL1Token(l1Token_) | ||
onlySupportedL2Token(l2Token_) | ||
{ | ||
_initiateERC20Deposit(msg.sender, to_, amount_, l2Gas_, data_); | ||
} | ||
|
||
/// @inheritdoc IL1ERC20Bridge | ||
function finalizeERC20Withdrawal( | ||
address l1Token_, | ||
address l2Token_, | ||
address from_, | ||
address to_, | ||
uint256 amount_, | ||
bytes calldata data_ | ||
) | ||
external | ||
whenWithdrawalsEnabled | ||
onlySupportedL1Token(l1Token_) | ||
onlySupportedL2Token(l2Token_) | ||
onlyFromCrossDomainAccount(l2TokenBridge) | ||
{ | ||
IERC20(l1Token_).safeTransfer(to_, amount_); | ||
|
||
emit ERC20WithdrawalFinalized( | ||
l1Token_, | ||
l2Token_, | ||
from_, | ||
to_, | ||
amount_, | ||
data_ | ||
); | ||
} | ||
|
||
/// @dev Performs the logic for deposits by informing the L2 token bridge contract | ||
/// of the deposit and calling safeTransferFrom to lock the L1 funds. | ||
/// @param from_ Account to pull the deposit from on L1 | ||
/// @param to_ Account to give the deposit to on L2 | ||
/// @param amount_ Amount of the ERC20 to deposit. | ||
/// @param l2Gas_ Gas limit required to complete the deposit on L2. | ||
/// @param data_ Optional data to forward to L2. This data is provided | ||
/// solely as a convenience for external contracts. Aside from enforcing a maximum | ||
/// length, these contracts provide no guarantees about its content. | ||
function _initiateERC20Deposit( | ||
address from_, | ||
address to_, | ||
uint256 amount_, | ||
uint32 l2Gas_, | ||
bytes calldata data_ | ||
) internal { | ||
IERC20(l1Token).safeTransferFrom(from_, address(this), amount_); | ||
|
||
bytes memory message = abi.encodeWithSelector( | ||
IL2ERC20Bridge.finalizeDeposit.selector, | ||
l1Token, | ||
l2Token, | ||
from_, | ||
to_, | ||
amount_, | ||
data_ | ||
); | ||
|
||
sendCrossDomainMessage(l2TokenBridge, l2Gas_, message); | ||
|
||
emit ERC20DepositInitiated( | ||
l1Token, | ||
l2Token, | ||
from_, | ||
to_, | ||
amount_, | ||
data_ | ||
); | ||
} | ||
|
||
error ErrorSenderNotEOA(); | ||
} | ||
Comment on lines
+21
to
+150
Check failure Code scanning / Slither Name reused High |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should remove the dev msig