# zkCRO

[#l1-greater-than-l2-minting-usdzkcro-with-usdcro](#l1-greater-than-l2-minting-usdzkcro-with-usdcro "mention")

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

[#l2-greater-than-l1-withdraw-eth-from-veth](#l2-greater-than-l1-withdraw-eth-from-veth "mention")

***

## \[L1 -> L2] Minting $zkCRO with $CRO

{% hint style="info" %}
Before we begin, please note that the decimals of $CRO on Ethereum is `8`
{% endhint %}

{% hint style="success" %}
Developers can refer to [this repository](https://github.com/kentimsit/ethereum-cro-to-cronos-zkevm-zkcro) for an example script on converting $CRO (on L1 - Ethereum mainnet) to $zkCRO (on L2 - Cronos zkEVM mainnet).
{% endhint %}

To bridge $CRO `Ethereum mainnet (L1) -> Cronos zkEVM mainnet(L2)`, and obtain $zkCRO on L2, we would need to interact with:&#x20;

* $CRO token contract&#x20;
  * Ethereum: [0xa0b73e1ff0b80914ab6fe0444e65848c4c34450b](https://etherscan.io/address/0xa0b73e1ff0b80914ab6fe0444e65848c4c34450b)
* $zkCRO token contract
  * Ethereum: [0x28ff2e4dd1b58efeb0fc138602a28d5ae81e44e2](https://etherscan.io/address/0x28ff2e4dd1b58efeb0fc138602a28d5ae81e44e2)
* `ZkCroMintAndBridge`
  * Ethereum: [0xe69a535730858fd8dc386b448972a9f801ab4e12](https://etherscan.io/address/0xe69a535730858fd8dc386b448972a9f801ab4e12#code)

### Step 1) **Calculating the $CRO amount to bridge**

On Ethereum - Using the [$zkCRO contract](https://etherscan.io/address/0x28ff2e4dd1b58efeb0fc138602a28d5ae81e44e2), call the`convertToShare` function to calculating the $CRO amount to bridge:

```
zkCro.convertToShare(_tokenAmount)
```

| Parameters     | Comments                                                                                                                                                                    |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `_tokenAmount` | The amount of $CRO to bridge, in `8` decimals. Note that additional $CRO to pay for gas on L2, We suggest to put at least 1 $CRO (i.e. adding `10^8` base unit as a buffer) |

Keep this output amount for use in later steps.

### Step 2) Approving the `zkCROBridge` to spend $CRO

On Ethereum - Using the  [$CRO contract](https://etherscan.io/address/0xa0b73e1ff0b80914ab6fe0444e65848c4c34450b) to `approve` [zkCROBridge](https://etherscan.io/address/0xe69a535730858fd8dc386b448972a9f801ab4e12#code) contract for the amount you want to bridge to zkEVM. Note that the decimals of $CRO on Ethereum is `8`.

### Step 3) Minting and Bridging $CRO to L2

On Ethereum - Using the [ZkCroMintAndBridge](https://etherscan.io/address/0xe69a535730858fd8dc386b448972a9f801ab4e12#readContract) contract, call the `mintAndBridge` function:

```
function mintAndBridge(
   address _l2Receiver,
   uint256 _zkCroBridgeAmount,
   uint256 _l2GasLimit,
   uint256 _totalCro
)
```

<table><thead><tr><th width="253">Parameters</th><th>Comments</th></tr></thead><tbody><tr><td><code>_l2Receiver</code></td><td>The address on Cronos zkEVM to receive $zkCRO</td></tr><tr><td><code>_zkCroBridgeAmount</code></td><td>Amount of $zkCRO to bridge (as calculated in Step 1)</td></tr><tr><td><code>_l2GasLimit</code></td><td>The maximum amount of gas to be used on L2. Set the value high enough or the transaction will fail</td></tr><tr><td><code>_totalCro</code></td><td>This value is the sum of $CRO the user wants to bridge, plus the gas fee in $zkCRO. Please include a small buffer. The contract throws an error if the buffer is zero. We suggest to put at least 1 $CRO (i.e. adding <code>10^8</code> base unit as a buffer)</td></tr></tbody></table>

Once done, it mints $zkCRO and bridges it to Cronos zkEVM, some of the $CRO on the Ethereum side will be consumed in the buffer range set to pay for the gas on Cronos zkEVM.<br>

***

## \[L2 -> L1] Withdrawing $zkCRO from L2

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

To withdraw $zkCRO from`Cronos zkEVM mainnet -> Ethereum mainnet`, we would need to interact with the following contract:

* $zkCRO token contract:
  * Cronos zkEVM: [`0x000000000000000000000000000000000000800a`](https://explorer.zkevm.cronos.org/address/0x000000000000000000000000000000000000800a)
* zkChain Shared Bridge:
  * Ethereum : [0xD7f9f54194C633F36CCD5F3da84ad4a1c38cB2cB](https://etherscan.io/address/0xD7f9f54194C633F36CCD5F3da84ad4a1c38cB2cB)

### Step 1) Initiating a withdrawal transaction

On Cronos zkEvm, call the `withdraw` function of zkCRO token contract:

```
function withdraw(address _l1Receiver) external payable;
```

| Parameters    | Comments                                         |
| ------------- | ------------------------------------------------ |
| `_l1Receiver` | The address to recieve zkCRO on Ethereum mainnet |
| `payable`     | The amount of $zkCRO to be transfer.             |

It will take at least 24 hours before the withdrawal can be finalized on Ethereum. Store the transaction hash from the withdrawal transaction for later steps.

### Step 2) Gathering information for $zkCRO withdrawal on L1

Extra information for the L2 -> L1 transaction is required for the next step in claiming the $zkCRO 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 3) Claiming the $zkCRO on L1

Once the transaction in Step 1 has been finalized on L1, we can claim the withdrawn $zkCRO from the zk Chain Shared Bridge contract by calling its `finalizeWithdrawal` function. The inputs can be found in Step 2,

```
    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 2.                              |
| `_l2MessageIndex`    | The position in the L2 logs Merkle tree of the l2Log that was sent with the message, obtained in Step 2. |
| `_l2TxNumberInBatch` | The L2 transaction number in the batch, in which the log was sent, obtained in Step 2.                   |
| `_message`           | The L2 withdraw data, stored in an L2 -> L1 message, obtained in Step 2.                                 |
| `_merkleProof`       | The Merkle Proof, obtained in Step 2.                                                                    |

Once `finalizeWithdrawal` is completed, the withdrawn amount of $zkCRO 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 1. |

{% hint style="info" %}
Note - If you would like to convert $zkCRO on Ethereum to $CRO, you can do so by unstaking it to obtain the underlying $CRO staked and receive the $CRO on "Cronos EVM Mainnet" . Please refer to the following guide [#l2-greater-than-l1-withdraw-eth-from-veth](#l2-greater-than-l1-withdraw-eth-from-veth "mention") to complete the process.
{% endhint %}

***

## Unstaking $zkCRO for $CRO <a href="#l2-greater-than-l1-withdraw-eth-from-veth" id="l2-greater-than-l1-withdraw-eth-from-veth"></a>

To redeem $zkCRO from`Ethereum mainnet` and receive the underlying unstaked $CRO ( on "[Cronos EVM Mainnet](https://docs.cronos.org/)"), we would need to interact with the following contracts:

* $zkCRO token contract
  * Ethereum: [0x28ff2e4dd1b58efeb0fc138602a28d5ae81e44e2](https://etherscan.io/address/0x28ff2e4dd1b58efeb0fc138602a28d5ae81e44e2)
* &#x20;$LCRO token contract
  * Cronos EVM Mainnet: [0x9fae23a2700feecd5b93e43fdbc03c76aa7c08a6](https://cronoscan.com/address/0x9fae23a2700feecd5b93e43fdbc03c76aa7c08a6)
* `vnoNFT`
  * Cronos EVM Mainnet: [0xb15533a0bc7c530d692a9660785226dfd3633965](https://cronoscan.com/address/0xb15533a0bc7c530d692a9660785226dfd3633965)

### Step 1) Approving $zkCRO to be spend by zkCRO token contract

On Ethereum, approve $zkCRO to be spent by zkCRO contract with appropriate amount.

### Step 2) Unstaking $zkCRO to recieve $LCRO

On Ethereum, call the `unstake` function on the zkCRO token contract:&#x20;

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

| Parameters     | Comments                                         |
| -------------- | ------------------------------------------------ |
| `_receiver`    | The Cronos EVM mainnet address to receive $LCRO. |
| `_shareAmount` | The amount of $zkCRO to unstake.                 |

Once done, $LCRO token will be automatically released within 24 hours and transfer to the `_receiver` address of "**Cronos EVM mainnet".**&#x20;

### Step 3) Approving $LCRO spent

On Cronos EVM mainnet, approve $LCRO to be spent by $LCRO contract with appropriate amount

### Step 4) Unbonding $LCRO

On Cronos EVM mainnet, call `requestUnbond` on the LCRO token contract,

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

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

Once done you will receive an NFT (`vnoNFT`) in return. Wait for batch of unbonding to be processed which takes 28-32 days.

### Step 5) Approving NFT to be spend by LCRO contract

On Cronos EVM mainnet, call `setApprovalForAll` on the [vnoNFT contract](https://cronoscan.com/address/0xb15533a0bc7c530d692a9660785226dfd3633965#writeProxyContract), to approve to transfer  of the vnoNFT obtained in Step 4)

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

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

### Step 6) Withdrawing $CRO

On Cronos EVM mainnet, call `unbond` function on the  LCRO token contract to burn the receipt NFT and receive the underlying unstaked $CRO.

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

| Parameters  | Comments                                           |
| ----------- | -------------------------------------------------- |
| `_tokenId`  | The tokenId of the receipt NFT, recieved in Step 4 |
| `_receiver` | The address on Cronos EVM mainnet to receive $CRO  |

This transaction burns the receipt NFT and sends the unstaked $CRO 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/zkcro.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.
