# vETH

[#l1-greater-than-l2-minting-usdveth-with-usdeth](#l1-greater-than-l2-minting-usdveth-with-usdeth "mention")

[#l2-greater-than-l1-withdrawing-usdeth-from-usdveth](#l2-greater-than-l1-withdrawing-usdeth-from-usdveth "mention")

***

## \[L1 -> L2] Minting $vETH with $ETH

*From Ethereum mainnet (L1) to Cronos zkEVM mainnet (L2)*

{% hint style="info" %}
For bridging $ETH (Ethereum Mainnet) to $vETH (Cronos zkEVM Mainnet), we would need to:

1. Mint and bridge $ybETH from Ethereum to Cronos zkEVM Mainnet with $ETH;
2. Mint $vETH with $ybETH on Cronos zkEVM Mainnet.
   {% endhint %}

To bridge $ETH from `Ethereum mainnet -> Cronos zkEVM mainnet`, and obtain $vETH, we would need to interact with:

* `ybETHBridge`&#x20;
  * Ethereum: [0xDED4Dd6E03A7CaA6278Ee453BE2C26363f50643D](https://etherscan.io/address/0xDED4Dd6E03A7CaA6278Ee453BE2C26363f50643D)
* $ybETH token contract
  * Ethereum: [0x76bf2D1e6dFda645c0c17440B17Eccc181dfC351](https://etherscan.io/address/0x76bf2D1e6dFda645c0c17440B17Eccc181dfC351)
  * Cronos zkEVM: [`0xf226a595b83056ff3D26b827e3d5b0896E4392a9`](https://explorer.zkevm.cronos.org/address/0xf226a595b83056ff3D26b827e3d5b0896E4392a9)
* $vETH token contract
  * Cronos zkEVM: [`0x271602A97027ee1dd03b1E6e5dB153eB659A80b1`](https://explorer.zkevm.cronos.org/address/0x271602A97027ee1dd03b1E6e5dB153eB659A80b1)

### Step 1) Calculating the amount of $ybETH to Bridge

On Ethereum, use [ ybETH contract](https://etherscan.io/address/0x76bf2D1e6dFda645c0c17440B17Eccc181dfC351#code) to call the `convertToShare` function:

```
ybETH.convertToShare(ethAmount)
```

| Parameters  | Comments                                                         |
| ----------- | ---------------------------------------------------------------- |
| `ethAmount` | The amount of $ETH (with 18 decimals) to be used to mint $ybETH. |

Keep this amount for later steps.

### Step 2) Minting And Bridging **$ybETH**

On Ethereum, call the `mintAndBridge` function on the [ybETHBridge](https://etherscan.io/address/0xDED4Dd6E03A7CaA6278Ee453BE2C26363f50643D) contract:

```
function mintAndBridge(
        address _l2Receiver,
        uint256 _amount,
        uint256 _l2GasLimit,
        uint256 _l2GasPerPubdataByteLimit,
        address _refundRecipient
    )
```

| Parameters                  | Comments                                                                                                                |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `_l2Receiver`               | The address on Cronos zkEVM that will receive $ybETH                                                                    |
| `_amount`                   | The amount of $ETH to mint and bridge $ybETH, as calculate in Step 1                                                    |
| `_l2Gaslimit`               | Maximum amount of L2 gas that transaction can consume during execution on L2. Reference value: `500,000`                |
| `_l2GasPerPubdataByteLimit` | The maximum amount of L2 gas that the operator may charge the user for a single byte of pubdata. Reference value: `800` |
| `_refundRecipient`          | Address to collect refund, if bridging is unsuccessful.                                                                 |

This will mint $ybETH on Ethereum and bridge it to the `_l2Receiver` address.

### Step 3) Approving $ybETH to be spend by $vETH contract

On Cronos zkEVM, call `approve` on the $ybETH contract to approve $vETH to spend $ybETH with appropriate amount.

### Step 4) Minting of $vETH

On Cronos zkEVM, call `mint` on $vETH contract , to mint $vETH

```
function mint(
         address _receiver,
         uint256 _ybEthAmount
         )
```

| Parameters     | Comments                                   |
| -------------- | ------------------------------------------ |
| `_receiver`    | Address to receive the minted $vETH tokens |
| `_ybEthAmount` | Amount of $ybETH to be used to mint $vETH  |

This will mint $vETH into the `_receiver` address.

***

## \[L2 -> L1] Withdrawing $ETH from $vETH

*From Cronos zkEVM mainnet (L2) -> Ethereum mainnet (L1)*

{% hint style="info" %}
For withdrawing $vETH (Cronos zkEVM Mainnet) and get $ETH (Ethereum Mainnet) , we would need to:

1. \[On Cronos zkEVM] Use $vETH to redeem $ybETH;
2. \[On Cronos zkEVM] Bridge $ybETH to Ethereum;
3. \[On Ethereum] Obtain `vnoNFT` by burning $ybETH
4. \[On Ethereum] Withdraw $ETH by buring`vnoNFT`.
   {% endhint %}

To redeem  $vETH from `Cronos zkEVM mainnet`, and withdraw $ETH on `Ethereum mainnet` we would need to interact with the following contracts: &#x20;

* vETH&#x20;
  * Cronos zkEVM: [`0x271602A97027ee1dd03b1E6e5dB153eB659A80b1`](https://explorer.zkevm.cronos.org/address/0x271602A97027ee1dd03b1E6e5dB153eB659A80b1)
* l2Bridge&#x20;
  * Cronos zkEVM: [0x309429DE3621992Cb0ab8982A448c9Cc5c38405b](https://explorer.zkevm.cronos.org/address/0x309429DE3621992Cb0ab8982A448c9Cc5c38405b)
* zk Chain Shared Bridge
  * Ethereum: [0xD7f9f54194C633F36CCD5F3da84ad4a1c38cB2cB](https://etherscan.io/address/0xD7f9f54194C633F36CCD5F3da84ad4a1c38cB2cB)
* ybETH
  * Ethereum: [0x76bf2D1e6dFda645c0c17440B17Eccc181dfC351](https://etherscan.io/address/0x76bf2D1e6dFda645c0c17440B17Eccc181dfC351)
  * Cronos zkEVM: [`0xf226a595b83056ff3D26b827e3d5b0896E4392a9`](https://explorer.zkevm.cronos.org/address/0xf226a595b83056ff3D26b827e3d5b0896E4392a9)
* vnoNFT
  * Ethereum: [0x8f6b0512e63a644631694178b83419fecd90762d](https://etherscan.io/token/0x8f6b0512e63a644631694178b83419fecd90762d)

### Step 1) Approving $vETH to be spend by vETH contract

On Cronos zkEVM, call `approve` on the $vETH contract  to approve $vETH spend with appropriate amount.&#x20;

### Step 2)  Redeeming $vETH for $ybETH&#x20;

On Cronos zkEVM,  call `redeem` on the vETH contract, to burn $vETH and redeem $ybETH

```
function redeem(
        address _receiver,
        uint256 _vethAmount
    )
```

| Parameters    | Comments                                           |
| ------------- | -------------------------------------------------- |
| `_receiver`   | Address to receive $ybETH on Cronos zkEVM          |
| `_vethAmount` | Amount of vETH that will be burned to redeem ybETH |

Once done, corresponding $ybETH will be transfer to the `_reciever` address

### Step 3) Approving $ybETH to be spend by the L2Bridge

On Cronos zkEVM, call `approve` on the ybETH contract, to approve `L2Bridge` to spend $ybETH.

### Step 4) Withdrawing $ybETH and store withdrawal hash

On Cronos zkEVM, call withdraw on the L2Bridge contract

```
function withdraw(
        address _l1Receiver, 
        address _l2Token, 
        uint256 _amount)
```

| Parameters    | Comments                                                                          |
| ------------- | --------------------------------------------------------------------------------- |
| `_l1Receiver` | Address on Ethereum to receive the token                                          |
| `_l2Token`    | The token to be withdrawn, the Cronos zkEVM contract address $ybETH in this case. |
| `_amount`     | amount of tokens to be withdrawn, note $ybETH has `18` decimals                   |

Keep the transaction hash for later use in Step 5. This withdraws $ybETH from Cronos zkEVM to Ethereum. It takes at least 24 hours before the withdrawal can be finalized on Ethereum. Store the transaction hash from the withdrawal transaction; you will need it to finalize the withdrawal.

### Step 5) Gathering information for $ybETH withdrawal on L1

Extra information for the L2 -> L1 transaction is required for the next step in claiming the $ybETH on L1. This information can be gathered by [finalizeWithdrawalParams](https://docs.zksync.io/sdk/js/ethers/api/v5/accounts/wallet#finalizewithdrawalparams), using `zksync-ethers` package

```
finalizeWithdrawalParams(withdrawalHash)
```

This takes the L2 withdrawal hash as parameters and returns the parameters required for finalizing a withdrawal in the next step.

Example outputs:

```
{
  l1BatchNumber: 18,
  l2MessageIndex: 59,
  l2TxNumberInBlock: 2919,
  message: '0x6c0960f935f448644c86dbda241ecb57f18a15c80f35a066000000000000000000000000000000000000000000000a2a15d09519be000000',
  sender: '0x000000000000000000000000000000000000800a',
  proof: [
    '0x23ff0fb003a6a6e111f87cff02afc8680944c711abbe792f07ab4206e9efb9a3',
    '0x09fece9c46307f2a0976a3a9b57873e453cf0f4773c2377dcd19f054166aef22',
    '0x33c106ae5601983b53c751129d1921c17e40b69aa3fdbfaf07b7a0e0750d35e4',
    '0x952ffa5de22d99815d9513dd7454949edb2a1cbcf86008f6fa8b169ffe9b4aee',
    '0x8f10560a0b5412ca2e0578fb9266f55411f357d52c8fc3b2cad43b9877a559a6',
    '0x8e70b93d3c90798df26473a3ad32a86170e8d52023a4044cf1d4c2d645471b14',
    '0xdfaacb39891bbbf4509af408239b97a6f5ef715a5c299ba1f3625c20aec4ef8f',
    '0xb04e5ee349086985f74b73971ce9dfe76bbed95c84906c5dffd96504e1e5396c',
    '0xac506ecb5465659b3a927143f6d724f91d8d9c4bdb2463aee111d9aa869874db',
    '0x124b05ec272cecd7538fdafe53b6628d31188ffb6f345139aac3c3c1fd2e470f',
    '0xc3be9cbd19304d84cca3d045e06b8db3acd68c304fc9cd4cbffe6d18036cb13f',
    '0xfef7bd9f889811e59e4076a0174087135f080177302763019adaf531257e3a87',
    '0xa707d1c62d8be699d34cb74804fdd7b4c568b6c1a821066f126c680d4b83e00b',
    '0xf6e093070e0389d2e529d60fadb855fdded54976ec50ac709e3a36ceaa64c291'
  ]
}
```

### Step 6) Claiming the $ybETH on L1

Once the transaction in Step 4 has been finalized on L1, we can claim the withdrawn $ybETH from the  Shared Bridge contract by calling its `finalizeWithdrawal` function. The inputs can be found in Step 5,

```
    function finalizeWithdrawal(
            uint256   _chainId,
            uint256   _l2BatchNumber,
            uint256   _l2MessageIndex,
            uint16    _l2TxNumberInBatch,
            bytes calldata _message,
            bytes32 calldata _merkleProof
        )
```

| Parameters           | Comments                                                                                                 |
| -------------------- | -------------------------------------------------------------------------------------------------------- |
| `_chainId`           | Chain id for Cronos zkEVM, which is `388`                                                                |
| `_l2BatchNumber`     | The L2 batch number where the withdrawal was processed, obtained in Step 5.                              |
| `_l2MessageIndex`    | The position in the L2 logs Merkle tree of the l2Log that was sent with the message, obtained in Step 5. |
| `_l2TxNumberInBatch` | The L2 transaction number in the batch, in which the log was sent, obtained in Step 5.                   |
| `_message`           | The L2 withdraw data, stored in an L2 -> L1 message, obtained in Step 5.                                 |
| `_merkleProof`       | The Merkle Proof, obtained in Step 5.                                                                    |

Once `finalizeWithdrawal` is completed, the withdrawn amount of $ybETH will go into the receiver's wallet on Ethereum.

We can use `zksync-ethers` package  [`isWithdrawalFinalized`](https://docs.zksync.io/sdk/js/ethers/api/v5/accounts/wallet#iswithdrawalfinalized) call to confirm whether the withdrawal transaction is finalized on the L1 network.

```
isWithdrawalFinalized(withdrawalHash)
```

| Parameters       | Comments                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------ |
| `withdrawalHash` | The transaction hash of the L2 transaction includes the withdrawal transaction from Step 4 |

### Step 7)  Approving $ybETH to be spend by ybETH contract

On Ethereum, call `approve` on the $ybETH contract, to approve the contract to spend $ybETH.

### Step 8) Requesting $ETH withdrawal

On Ethereum, call `requestUnbond` to request a unbonding of the staked $ETH.

```
function requestUnbond(
        uint256 _shareAmount, 
        address _receiver
        )
```

| Parameters     | Comments                                                                                                                            |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `_shareAmount` | The amount of $ybETH that is to be burned to unbond $ETH                                                                            |
| `_receiver`    | The wallet address on ethereum to receive the receipt NFT. This NFT is needed to withdraw the $ETH once the unbond period has ended |

This will burn $ybETH and mint a receipt NFT  - Veno Unstaked ETH (vnoNFT) to the `_receiver` address. The unbonding procress takes 1\~10 days, hold on to the NFT to claim the $ETH once it's ready. Store the tokenId of the received NFT; it is needed to withdraw the $ETH in the next steps.

### Step 9) Approving NFT to be spend by ybETH contract

On Ethereum, call `setApprovalForAll` on the vnoNFT contract, to approve $ybETH to transfer your vnoNFT obtained in Step 8).&#x20;

```
setApprovalForAll(address operator, bool _approved)
```

| Parameters  | Comments                            |
| ----------- | ----------------------------------- |
| `operator`  | $ybETH contract address on Ethereum |
| `_approved` | Set to "True" to grant approval.    |

### Step 10) Withdrawing $ETH

On Ethereum, call `unbond`function on the ybETH contract to burn the receipt NFT and receive the underlying unstaked $ETH.

```
 function unbond(
        uint256 _tokenId, 
        address _receiver
        )
```

| Parameters  | Comments                                           |
| ----------- | -------------------------------------------------- |
| `_tokenId`  | The tokenId of the receipt NFT, recieved in Step 7 |
| `_receiver` | The address on Ethereum to receive $ETH            |

This transaction burns the receipt NFT and sends the unstaked $ETH to the specified receiver.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-zkevm.cronos.org/for-developers/using-zkcro-veth-and-vusd/veth.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
