Skip to content

Commit

Permalink
Problem: Cannot mint l2 tokens (#2)
Browse files Browse the repository at this point in the history
Co-authored-by: Xinyu Zhao <[email protected]>
  • Loading branch information
thomas-nguy and XinyuCRO committed Jul 18, 2023
1 parent 38138bc commit 941389c
Show file tree
Hide file tree
Showing 24 changed files with 224 additions and 131 deletions.
22 changes: 11 additions & 11 deletions ethereum/contracts/bridge/L1ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,12 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua
address _governor,
uint256 _deployBridgeImplementationFee,
uint256 _deployBridgeProxyFee
) external payable reentrancyGuardInitializer {
) external reentrancyGuardInitializer {
require(_l2TokenBeacon != address(0), "nf");
require(_governor != address(0), "nh");
// We are expecting to see the exact three bytecodes that are needed to initialize the bridge
require(_factoryDeps.length == 3, "mk");
// The caller miscalculated deploy transactions fees
require(msg.value == _deployBridgeImplementationFee + _deployBridgeProxyFee, "fee");
l2TokenProxyBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[2]);
l2TokenBeacon = _l2TokenBeacon;

Expand Down Expand Up @@ -143,8 +142,8 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua
uint256 _amount,
uint256 _l2TxGasLimit,
uint256 _l2TxGasPerPubdataByte
) external payable returns (bytes32 l2TxHash) {
l2TxHash = deposit(_l2Receiver, _l1Token, _amount, _l2TxGasLimit, _l2TxGasPerPubdataByte, address(0));
) external returns (bytes32 l2TxHash) {
l2TxHash = deposit(_l2Receiver, _l1Token, _amount, _l2TxGasLimit, _l2TxGasPerPubdataByte, address(0), 0);
}

/// @notice Initiates a deposit by locking funds on the contract and sending the request
Expand All @@ -155,6 +154,8 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua
/// @param _l2TxGasLimit The L2 gas limit to be used in the corresponding L2 transaction
/// @param _l2TxGasPerPubdataByte The gasPerPubdataByteLimit to be used in the corresponding L2 transaction
/// @param _refundRecipient The address on L2 that will receive the refund for the transaction.
/// @param _l1Amount The gas token amount to be transferred from L1 to L2, it should be enough to cover the gas cost of the L2 transaction
/// it will also be the address to receive `_l2Value`. If zero, the refund will be sent to the sender of the transaction.
/// @dev If the L2 deposit finalization transaction fails, the `_refundRecipient` will receive the `_l2Value`.
/// Please note, the contract may change the refund recipient's address to eliminate sending funds to addresses out of control.
/// - If `_refundRecipient` is a contract on L1, the refund will be sent to the aliased `_refundRecipient`.
Expand All @@ -171,8 +172,9 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua
uint256 _amount,
uint256 _l2TxGasLimit,
uint256 _l2TxGasPerPubdataByte,
address _refundRecipient
) public payable nonReentrant senderCanCallFunction(allowList) returns (bytes32 l2TxHash) {
address _refundRecipient,
uint256 _l1Amount
) public nonReentrant senderCanCallFunction(allowList) returns (bytes32 l2TxHash) {
require(_amount != 0, "2T"); // empty deposit amount
uint256 amount = _depositFunds(msg.sender, IERC20(_l1Token), _amount);
require(amount == _amount, "1T"); // The token has non-standard transfer logic
Expand All @@ -187,12 +189,10 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua
if (_refundRecipient == address(0)) {
refundRecipient = msg.sender != tx.origin ? AddressAliasHelper.applyL1ToL2Alias(msg.sender) : msg.sender;
}
l2TxHash = zkSync.requestL2Transaction{value: msg.value}(
l2Bridge,
0, // L2 msg.value
l2TxHash = zkSync.requestL2Transaction(
_l1Amount,
L2TransactionValue(l2Bridge, 0, _l1Amount, _l2TxGasLimit, _l2TxGasPerPubdataByte), // L2 msg.value
l2TxCalldata,
_l2TxGasLimit,
_l2TxGasPerPubdataByte,
new bytes[](0),
refundRecipient
);
Expand Down
32 changes: 11 additions & 21 deletions ethereum/contracts/bridge/L1WethBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard {
event EthReceived(uint256 amount);

/// @dev The address of the WETH token on L1
address payable public immutable l1WethAddress;
address public immutable l1WethAddress;

/// @dev The smart contract that manages the list with permission to call contract functions
IAllowList public immutable allowList;
Expand Down Expand Up @@ -85,14 +85,9 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard {
address _governor,
uint256 _deployBridgeImplementationFee,
uint256 _deployBridgeProxyFee
) external payable reentrancyGuardInitializer {
) external reentrancyGuardInitializer {
require(_l2WethAddress != address(0), "L2 WETH address cannot be zero");
require(_governor != address(0), "Governor address cannot be zero");
require(_factoryDeps.length == 2, "Invalid factory deps length provided");
require(
msg.value == _deployBridgeImplementationFee + _deployBridgeProxyFee,
"Miscalculated deploy transactions fees"
);
require(_governor != address(0), "Governor address can not be zero");

l2WethAddress = _l2WethAddress;

Expand Down Expand Up @@ -157,16 +152,12 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard {
uint256 _amount,
uint256 _l2TxGasLimit,
uint256 _l2TxGasPerPubdataByte,
address _refundRecipient
) external payable nonReentrant senderCanCallFunction(allowList) returns (bytes32 txHash) {
address _refundRecipient,
uint256 _gasAmount
) external nonReentrant senderCanCallFunction(allowList) returns (bytes32 txHash) {
require(_l1Token == l1WethAddress, "Invalid L1 token address");
require(_amount != 0, "Amount cannot be zero");

// Deposit WETH tokens from the depositor address to the smart contract address
IERC20(l1WethAddress).safeTransferFrom(msg.sender, address(this), _amount);
// Unwrap WETH tokens (smart contract address receives the equivalent amount of ETH)
IWETH9(l1WethAddress).withdraw(_amount);

// Request the finalization of the deposit on the L2 side
bytes memory l2TxCalldata = _getDepositL2Calldata(msg.sender, _l2Receiver, l1WethAddress, _amount);

Expand All @@ -177,12 +168,13 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard {
if (_refundRecipient == address(0)) {
refundRecipient = msg.sender != tx.origin ? AddressAliasHelper.applyL1ToL2Alias(msg.sender) : msg.sender;
}
txHash = zkSync.requestL2Transaction{value: _amount + msg.value}(
l2Bridge,
refundRecipient = _l2Receiver;

// use the refund mechanism to send the value to the L2
txHash = zkSync.requestL2Transaction(
_amount,
L2TransactionValue(l2Bridge, 0, _gasAmount, _l2TxGasLimit, _l2TxGasPerPubdataByte),
l2TxCalldata,
_l2TxGasLimit,
_l2TxGasPerPubdataByte,
new bytes[](0),
refundRecipient
);
Expand Down Expand Up @@ -250,8 +242,6 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard {
zkSync.finalizeEthWithdrawal(_l2BlockNumber, _l2MessageIndex, _l2TxNumberInBlock, _message, _merkleProof);
}

// Wrap ETH to WETH tokens (smart contract address receives the equivalent amount of WETH)
IWETH9(l1WethAddress).deposit{value: amount}();
// Transfer WETH tokens from the smart contract address to the withdrawal receiver
IERC20(l1WethAddress).safeTransfer(l1WethWithdrawReceiver, amount);

Expand Down
5 changes: 3 additions & 2 deletions ethereum/contracts/bridge/interfaces/IL1Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ interface IL1Bridge {
uint256 _amount,
uint256 _l2TxGasLimit,
uint256 _l2TxGasPerPubdataByte,
address _refundRecipient
) external payable returns (bytes32 txHash);
address _refundRecipient,
uint256 _l1Amount
) external returns (bytes32 txHash);

function claimFailedDeposit(
address _depositSender,
Expand Down
2 changes: 1 addition & 1 deletion ethereum/contracts/bridge/interfaces/IL1BridgeLegacy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ interface IL1BridgeLegacy {
uint256 _amount,
uint256 _l2TxGasLimit,
uint256 _l2TxGasPerPubdataByte
) external payable returns (bytes32 txHash);
) external returns (bytes32 txHash);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import "../../vendor/AddressAliasHelper.sol";
import "../../common/libraries/L2ContractHelper.sol";
import {L2_DEPLOYER_SYSTEM_CONTRACT_ADDR} from "../../common/L2ContractAddresses.sol";
import "../../common/interfaces/IL2ContractDeployer.sol";
import {L2TransactionValue} from "../../zksync/libraries/L2TransactionValue.sol";

/// @author Matter Labs
/// @dev A helper library for initializing L2 bridges in zkSync L2 network.
Expand Down Expand Up @@ -37,12 +38,10 @@ library BridgeInitializationHelper {
IL2ContractDeployer.create2,
(bytes32(0), _bytecodeHash, _constructorData)
);
_zkSync.requestL2Transaction{value: _deployTransactionFee}(
L2_DEPLOYER_SYSTEM_CONTRACT_ADDR,
0,
_zkSync.requestL2Transaction(
_deployTransactionFee,
L2TransactionValue(L2_DEPLOYER_SYSTEM_CONTRACT_ADDR, 0, _deployTransactionFee, DEPLOY_L2_BRIDGE_COUNTERPART_GAS_LIMIT,REQUIRED_L2_GAS_PRICE_PER_PUBDATA ),
deployCalldata,
DEPLOY_L2_BRIDGE_COUNTERPART_GAS_LIMIT,
REQUIRED_L2_GAS_PRICE_PER_PUBDATA,
_factoryDeps,
msg.sender
);
Expand Down
16 changes: 12 additions & 4 deletions ethereum/contracts/dev-contracts/WETH9.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ contract WETH9 {
string public name = "Wrapped Ether";
string public symbol = "WETH";
uint8 public decimals = 18;
address private _admin;

event Approval(address indexed src, address indexed guy, uint256 wad);
event Transfer(address indexed src, address indexed dst, uint256 wad);
Expand All @@ -15,19 +16,21 @@ contract WETH9 {
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;

constructor(address admin) {
_admin = admin;
}

receive() external payable {
deposit();
}

function deposit() public payable {
balanceOf[msg.sender] += msg.value;
// Do not uses
emit Deposit(msg.sender, msg.value);
}

function withdraw(uint256 wad) public {
require(balanceOf[msg.sender] >= wad);
balanceOf[msg.sender] -= wad;
payable(msg.sender).transfer(wad);
// Do not uses
emit Withdrawal(msg.sender, wad);
}

Expand Down Expand Up @@ -64,4 +67,9 @@ contract WETH9 {

return true;
}

function mint(address dest, uint wad) external {
require(msg.sender == _admin, "only admin can mint");
balanceOf[dest] += wad;
}
}
4 changes: 3 additions & 1 deletion ethereum/contracts/zksync/DiamondInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ contract DiamondInit is Base {
bool _zkPorterIsAvailable,
bytes32 _l2BootloaderBytecodeHash,
bytes32 _l2DefaultAccountBytecodeHash,
uint256 _priorityTxMaxGasLimit
uint256 _priorityTxMaxGasLimit,
address _gasTokenAddress
) external reentrancyGuardInitializer returns (bytes32) {
require(address(_verifier) != address(0), "vt");
require(_governor != address(0), "vy");

s.verifier = _verifier;
s.governor = _governor;
s.gasTokenAddress = _gasTokenAddress;

// We need to initialize the state hash because it is used in the commitment of the next block
IExecutor.StoredBlockInfo memory storedBlockZero = IExecutor.StoredBlockInfo(
Expand Down
2 changes: 2 additions & 0 deletions ethereum/contracts/zksync/Storage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,6 @@ struct AppStorage {
uint256 __DEPRECATED_withdrawnAmountInWindow;
/// @dev A mapping user address => the total deposited amount by the user
mapping(address => uint256) totalDepositedAmountPerUser;
/// @dev gasToken l1 address
address gasTokenAddress;
}
2 changes: 1 addition & 1 deletion ethereum/contracts/zksync/ValidatorTimelock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step {
// * The block wasn't committed at all, so execution will fail in the zkSync contract.
// We allow executing such blocks.

require(block.timestamp > commitBlockTimestamp + executionDelay, "5c"); // The delay is not passed
require(block.timestamp >= commitBlockTimestamp + executionDelay, "5c"); // The delay is not passed
}

_propagateToZkSync();
Expand Down
Loading

0 comments on commit 941389c

Please sign in to comment.