> For the complete documentation index, see [llms.txt](https://docs-zkevm.cronos.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs-zkevm.cronos.com/for-developers/using-zkcro-veth-and-vusd/veth.md).

# vETH

{% hint style="danger" %}
**Notice: Cronos zkEVM is being sunset, please** [**bridge out your assets**](/for-developers/using-zkcro-veth-and-vusd/veth.md#l2-greater-than-l1-withdrawing-usdeth-from-usdveth) **before the network is fully decommissioned.**
{% endhint %}

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

***

## \[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.
