matter-labs / zksync-v2-issues

Report issues encountered when using the zkSync 2.0 testnet.
10 stars 6 forks source link

ETH value not passed from L1 to L2 via requestL2Transaction #10

Open turbowizardry opened 1 year ago

turbowizardry commented 1 year ago

Describe the issue When making a call to a contract on L1 that invokes the requestL2Transaction function of IZKSync, the value of ETH specified in param _l2Value of requestL2Transaction does not seem to be passed to the L2 contract function. The ETH value gets stuck in the ZKSync contract, and never makes it to the L2 contract.

Expected behavior The ETH value passed in requestL2Transaction should be passed to the called L2 contract function.

Minimal Reproducible Example Code I have included a cloned repo of the zkSync Governance example here: https://github.com/turbowizardry/zksync-l1-l2-payable-issue

The Governance.sol contract:

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "@matterlabs/zksync-contracts/l1/contracts/zksync/interfaces/IZkSync.sol";

contract Governance {
  address public governor;

  constructor() {
    governor = msg.sender;
  }

  function testTransfer(
    address zkSyncAddress,
    address contractAddr,
    uint256 tipAmount,
    uint64 ergsLimit
  ) external payable {
    require(msg.value > tipAmount, "wrong amounts");

    callZkSync(
      zkSyncAddress, 
      contractAddr, 
      msg.value,
      tipAmount,
      abi.encodeWithSignature(
        "increment()"
      ),
      ergsLimit
    );
  }

  function callZkSync(
    address zkSyncAddress, 
    address contractAddr,
    uint256 totalAmount,
    uint256 tipAmount,
    bytes memory data,
    uint64 ergsLimit
  ) private {
    IZkSync zksync = IZkSync(zkSyncAddress);

    zksync.requestL2Transaction{value: totalAmount}(
      contractAddr, 
      totalAmount - tipAmount,
      data, 
      ergsLimit, 
      new bytes[](0)
    );
  }
}

The Counter.sol contract:

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

contract Counter {
    uint256 public value = 0;

    address public governance;

    constructor(address newGovernance) {
        governance = newGovernance;
    }

    function increment() public payable {
        require(msg.sender == governance, "not gov");
        require(msg.value > 0, "no eth");

        value += 1;
    }
}

To Reproduce

  1. In /counter, ensure .env variables are populated
  2. Run yarn ts-node ./scripts/increment-counter.ts to execute on the contracts I've already deployed.
bxpana commented 1 year ago

@turbowizardry thanks! Seeing the same thing on my end and we'll start looking into what's going on

bxpana commented 1 year ago

@turbowizardry the cross-chain tutorial has been updated and should now work correctly. Can you please try again and let us know if it works for you? https://v2-docs.zksync.io/dev/tutorials/cross-chain-tutorial.html