Skip to content

Commit

Permalink
Merge pull request #111 from zkLinkProtocol/issue_109
Browse files Browse the repository at this point in the history
add txNonce to bridge message
  • Loading branch information
zkbenny authored Dec 5, 2023
2 parents 1217d7a + a0505a8 commit 4e58e93
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 16 deletions.
16 changes: 9 additions & 7 deletions contracts/gateway/LineaL1Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ contract LineaL1Gateway is ZkLinkAcceptor, LineaGateway, ILineaL1Gateway {
uint64 public fee;

/// @notice Used to prevent off-chain monitoring events from being lost
uint192 public txNonce;
uint32 public txNonce;

function depositETH(bytes32 _zkLinkAddress, uint8 _subAccountId) external payable override nonReentrant whenNotPaused {
// ensure amount bridged is not zero
require(msg.value > fee, "Value too low");
uint256 amount = msg.value - fee;

bytes memory callData = abi.encodeCall(ILineaL2Gateway.claimETHCallback, (_zkLinkAddress, _subAccountId, amount));
uint32 _txNonce = txNonce;
bytes memory callData = abi.encodeCall(ILineaL2Gateway.claimETHCallback, (_txNonce, _zkLinkAddress, _subAccountId, amount));
// transfer no fee to Linea
messageService.sendMessage{value: amount}(remoteGateway, 0, callData);

emit Deposit(txNonce, ETH_ADDRESS, amount, _zkLinkAddress, _subAccountId, false);
txNonce++;
emit Deposit(_txNonce, ETH_ADDRESS, amount, _zkLinkAddress, _subAccountId, false);
txNonce = _txNonce + 1;
}

function depositERC20(address _token, uint256 _amount, bytes32 _zkLinkAddress, uint8 _subAccountId, bool _mapping) external payable override nonReentrant whenNotPaused {
Expand All @@ -47,11 +48,12 @@ contract LineaL1Gateway is ZkLinkAcceptor, LineaGateway, ILineaL1Gateway {
(bool isUSDC, address nativeToken) = bridgeERC20ToRemoteGateway(_token, _amount, 0);

// send depositERC20 command to LineaL2Gateway(the second message send to Linea)
bytes memory executeData = abi.encodeCall(ILineaL2Gateway.claimERC20Callback, (isUSDC, nativeToken, _amount, _zkLinkAddress, _subAccountId, _mapping));
uint32 _txNonce = txNonce;
bytes memory executeData = abi.encodeCall(ILineaL2Gateway.claimERC20Callback, (_txNonce, isUSDC, nativeToken, _amount, _zkLinkAddress, _subAccountId, _mapping));
messageService.sendMessage(remoteGateway, 0, executeData);

emit Deposit(txNonce, _token, _amount, _zkLinkAddress, _subAccountId, _mapping);
txNonce++;
emit Deposit(_txNonce, _token, _amount, _zkLinkAddress, _subAccountId, _mapping);
txNonce = _txNonce + 1;
}

function claimETHCallback(address _owner, uint128 _amount, uint32 _accountIdOfNonce, uint8 _subAccountIdOfNonce, uint32 _nonce, uint16 _fastWithdrawFeeRate) external payable override onlyMessageService onlyRemoteGateway {
Expand Down
8 changes: 4 additions & 4 deletions contracts/gateway/LineaL2Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ contract LineaL2Gateway is LineaGateway, ILineaL2Gateway {
_;
}

function claimETHCallback(bytes32 _zkLinkAddress, uint8 _subAccountId, uint256 _amount) external payable onlyMessageService onlyRemoteGateway {
function claimETHCallback(uint32 _txNonce, bytes32 _zkLinkAddress, uint8 _subAccountId, uint256 _amount) external payable onlyMessageService onlyRemoteGateway {
require(msg.value == _amount, "Claim eth value not match");

zkLink.depositETH{value: _amount}(_zkLinkAddress, _subAccountId);
emit ClaimedDepositETH(_zkLinkAddress, _subAccountId, _amount);
emit ClaimedDeposit(_txNonce);
}

function claimERC20Callback(bool _isUSDC, address _nativeToken, uint256 _amount, bytes32 _zkLinkAddress, uint8 _subAccountId, bool _mapping) external override onlyMessageService onlyRemoteGateway {
function claimERC20Callback(uint32 _txNonce, bool _isUSDC, address _nativeToken, uint256 _amount, bytes32 _zkLinkAddress, uint8 _subAccountId, bool _mapping) external override onlyMessageService onlyRemoteGateway {
// find target token on Linea
address targetToken = getTargetToken(_isUSDC, _nativeToken);
// approve token to zkLink
IERC20(targetToken).safeApprove(address(zkLink), _amount);
// deposit erc20 to zkLink
uint104 amount = uint104(_amount);
zkLink.depositERC20(IERC20(targetToken), amount, _zkLinkAddress, _subAccountId, _mapping);
emit ClaimedDepositERC20(targetToken, amount, _zkLinkAddress, _subAccountId, _mapping);
emit ClaimedDeposit(_txNonce);
}

function withdrawETH(address _owner, uint128 _amount, uint32 _accountIdOfNonce, uint8 _subAccountIdOfNonce, uint32 _nonce, uint16 _fastWithdrawFeeRate) external payable override onlyZkLink whenNotPaused {
Expand Down
2 changes: 1 addition & 1 deletion contracts/interfaces/ILineaL1Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
import {ILineaGateway} from "./ILineaGateway.sol";

interface ILineaL1Gateway is ILineaGateway {
event Deposit(uint192 indexed txNonce, address token, uint256 amount, bytes32 zklinkAddress, uint8 subAccountId, bool _mapping);
event Deposit(uint32 indexed txNonce, address token, uint256 amount, bytes32 zklinkAddress, uint8 subAccountId, bool _mapping);
event ClaimedWithdrawETH(address _receiver, uint256 _amount);
event ClaimedWithdrawERC20(address _receiver, address _token, uint256 _amount);
event SetFee(uint64 fee);
Expand Down
9 changes: 5 additions & 4 deletions contracts/interfaces/ILineaL2Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@ import {IL2Gateway} from "./IL2Gateway.sol";
import {ILineaGateway} from "./ILineaGateway.sol";

interface ILineaL2Gateway is ILineaGateway, IL2Gateway {
event ClaimedDepositETH(bytes32 _zkLinkAddress, uint8 _subAccountId, uint256 _amount);
event ClaimedDepositERC20(address _token, uint104 _amount, bytes32 _zkLinkAddress, uint8 _subAccountId, bool _mapping);
event ClaimedDeposit(uint32 indexed _txNonce);
event SetZkLink(address _zkLink);

/// @notice Claim ETH callback from message service
/// @param _txNonce The deposit sequence of L1 gateway
/// @param _zkLinkAddress The zkLink address deposited to
/// @param _subAccountId The sub account id
/// @param _amount The eth amount to deposit
function claimETHCallback(bytes32 _zkLinkAddress, uint8 _subAccountId, uint256 _amount) external payable;
function claimETHCallback(uint32 _txNonce, bytes32 _zkLinkAddress, uint8 _subAccountId, uint256 _amount) external payable;

/// @notice Claim ERC20 callback from message service
/// @param _txNonce The deposit sequence of L1 gateway
/// @param _isUSDC True when the native token is usdc
/// @param _nativeToken The native token
/// @param _amount The amount to deposit
/// @param _zkLinkAddress The zkLink address deposited to
/// @param _subAccountId The sub account id
/// @param _mapping If receive a mapping token on zkLink
function claimERC20Callback(bool _isUSDC, address _nativeToken, uint256 _amount, bytes32 _zkLinkAddress, uint8 _subAccountId, bool _mapping) external;
function claimERC20Callback(uint32 _txNonce, bool _isUSDC, address _nativeToken, uint256 _amount, bytes32 _zkLinkAddress, uint8 _subAccountId, bool _mapping) external;
}

0 comments on commit 4e58e93

Please sign in to comment.