-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
697 additions
and
408 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.24; | ||
|
||
/** | ||
|
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,20 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.20; | ||
|
||
error InvalidCaller(address); | ||
error InvalidInput(); | ||
error InsufficientAllowance(uint256 providedAllowance, uint256 requiredAmount); | ||
error FailedToTransferTokens(address tokenContract, address to, uint256 amount); | ||
error UnsupportedPaymasterFlow(); | ||
error EmptyAddress(); | ||
error EmptyBytes32(); | ||
error AddressMismatch(address expected, address supplied); | ||
error AmountMustBeGreaterThanZero(); | ||
error DeployFailed(); | ||
error Unauthorized(); | ||
error NonSequentialVersion(); | ||
error Unimplemented(); | ||
error UnimplementedMessage(string); | ||
error WithdrawFailed(); | ||
|
||
string constant BRIDGE_MINT_NOT_IMPLEMENTED = "bridgeMint is not implemented! Use deposit/depositTo methods instead."; |
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 |
---|---|---|
|
@@ -15,6 +15,8 @@ import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol"; | |
import {L2ContractHelper, DEPLOYER_SYSTEM_CONTRACT, IContractDeployer} from "../L2ContractHelper.sol"; | ||
import {SystemContractsCaller} from "../SystemContractsCaller.sol"; | ||
|
||
import {EmptyAddress, EmptyBytes32, InvalidCaller, AddressMismatch, AmountMustBeGreaterThanZero, DeployFailed} from "../L2ContractErrors.sol"; | ||
|
||
/// @author Matter Labs | ||
/// @custom:security-contact [email protected] | ||
/// @notice The "default" bridge implementation for the ERC20 tokens. Note, that it does not | ||
|
@@ -35,10 +37,10 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { | |
|
||
address private l1LegacyBridge; | ||
|
||
uint256 internal immutable ERA_CHAIN_ID; | ||
|
||
/// @dev Contract is expected to be used as proxy implementation. | ||
/// @dev Disable the initialization to prevent Parity hack. | ||
uint256 immutable ERA_CHAIN_ID; | ||
|
||
constructor(uint256 _eraChainId) { | ||
ERA_CHAIN_ID = _eraChainId; | ||
_disableInitializers(); | ||
|
@@ -54,9 +56,17 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { | |
bytes32 _l2TokenProxyBytecodeHash, | ||
address _aliasedOwner | ||
) external reinitializer(2) { | ||
require(_l1Bridge != address(0), "bf"); | ||
require(_l2TokenProxyBytecodeHash != bytes32(0), "df"); | ||
require(_aliasedOwner != address(0), "sf"); | ||
if (_l1Bridge == address(0)) { | ||
revert EmptyAddress(); | ||
} | ||
|
||
if (_l2TokenProxyBytecodeHash == bytes32(0)) { | ||
revert EmptyBytes32(); | ||
} | ||
|
||
if (_aliasedOwner == address(0)) { | ||
revert EmptyAddress(); | ||
} | ||
|
||
l1Bridge = _l1Bridge; | ||
|
||
|
@@ -66,7 +76,9 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { | |
l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash; | ||
l2TokenBeacon.transferOwnership(_aliasedOwner); | ||
} else { | ||
require(_l1LegacyBridge != address(0), "bf2"); | ||
if (_l1LegacyBridge == address(0)) { | ||
revert EmptyAddress(); | ||
} | ||
l1LegacyBridge = _l1LegacyBridge; | ||
// l2StandardToken and l2TokenBeacon are already deployed on ERA, and stored in the proxy | ||
} | ||
|
@@ -86,20 +98,26 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { | |
bytes calldata _data | ||
) external override { | ||
// Only the L1 bridge counterpart can initiate and finalize the deposit. | ||
require( | ||
AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1Bridge || | ||
AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1LegacyBridge, | ||
"mq" | ||
); | ||
if ( | ||
AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1Bridge && | ||
AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1LegacyBridge | ||
) { | ||
revert InvalidCaller(msg.sender); | ||
} | ||
|
||
address expectedL2Token = l2TokenAddress(_l1Token); | ||
address currentL1Token = l1TokenAddress[expectedL2Token]; | ||
if (currentL1Token == address(0)) { | ||
address deployedToken = _deployL2Token(_l1Token, _data); | ||
require(deployedToken == expectedL2Token, "mt"); | ||
if (deployedToken != expectedL2Token) { | ||
revert AddressMismatch(expectedL2Token, deployedToken); | ||
} | ||
|
||
l1TokenAddress[expectedL2Token] = _l1Token; | ||
} else { | ||
require(currentL1Token == _l1Token, "gg"); // Double check that the expected value equal to real one | ||
if (currentL1Token != _l1Token) { | ||
revert AddressMismatch(_l1Token, currentL1Token); | ||
} | ||
} | ||
|
||
IL2StandardToken(expectedL2Token).bridgeMint(_l2Receiver, _amount); | ||
|
@@ -122,12 +140,16 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { | |
/// @param _l2Token The L2 token address which is withdrawn | ||
/// @param _amount The total amount of tokens to be withdrawn | ||
function withdraw(address _l1Receiver, address _l2Token, uint256 _amount) external override { | ||
require(_amount > 0, "Amount cannot be zero"); | ||
if (_amount == 0) { | ||
revert AmountMustBeGreaterThanZero(); | ||
} | ||
|
||
IL2StandardToken(_l2Token).bridgeBurn(msg.sender, _amount); | ||
|
||
address l1Token = l1TokenAddress[_l2Token]; | ||
require(l1Token != address(0), "yh"); | ||
if (l1Token == address(0)) { | ||
revert EmptyAddress(); | ||
} | ||
|
||
bytes memory message = _getL1WithdrawMessage(_l1Receiver, l1Token, _amount); | ||
L2ContractHelper.sendMessageToL1(message); | ||
|
@@ -174,7 +196,9 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { | |
); | ||
|
||
// The deployment should be successful and return the address of the proxy | ||
require(success, "mk"); | ||
if (!success) { | ||
revert DeployFailed(); | ||
} | ||
proxy = BeaconProxy(abi.decode(returndata, (address))); | ||
} | ||
} |
Oops, something went wrong.