vETH
On this page, you can find the contracts and their interactions involved when bridging to and from Ethereum (L1 - $ETH) and Cronos zkEVM (L2 - $vETH ), it includes:
[L1 -> L2] Minting $vETH with $ETH
[L2 -> L1] Withdrawing $ETH from $vETH
[L1 -> L2] Minting $vETH with $ETH
From Ethereum mainnet (L1) to Cronos zkEVM mainnet (L2)
To bridge $ETH from Ethereum mainnet -> Cronos zkEVM mainnet, and obtain $vETH, we would need to interact with:
ybETHBridge$ybETH token contract
Cronos zkEVM:
0xf226a595b83056ff3D26b827e3d5b0896E4392a9
$vETH token contract
Cronos zkEVM:
0x271602A97027ee1dd03b1E6e5dB153eB659A80b1
Step 1) Calculating the amount of $ybETH to Bridge
On Ethereum, use ybETH contract to call the convertToShare function:
ybETH.convertToShare(ethAmount)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 contract:
function mintAndBridge(
address _l2Receiver,
uint256 _amount,
uint256 _l2GasLimit,
uint256 _l2GasPerPubdataByteLimit,
address _refundRecipient
)_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
)_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)
To redeem $vETH from Cronos zkEVM mainnet, and withdraw $ETH on Ethereum mainnet we would need to interact with the following contracts:
vETH
Cronos zkEVM:
0x271602A97027ee1dd03b1E6e5dB153eB659A80b1
l2Bridge
Cronos zkEVM: 0x309429DE3621992Cb0ab8982A448c9Cc5c38405b
zk Chain Shared Bridge
ybETH
Cronos zkEVM:
0xf226a595b83056ff3D26b827e3d5b0896E4392a9
vnoNFT
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.
Step 2) Redeeming $vETH for $ybETH
On Cronos zkEVM, call redeem on the vETH contract, to burn $vETH and redeem $ybETH
function redeem(
address _receiver,
uint256 _vethAmount
)_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)_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, 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
)_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 call to confirm whether the withdrawal transaction is finalized on the L1 network.
isWithdrawalFinalized(withdrawalHash)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
)_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).
setApprovalForAll(address operator, bool _approved)operator
$ybETH contract address on Ethereum
_approved
Set to "True" to grant approval.
Step 10) Withdrawing $ETH
On Ethereum, call unbondfunction on the ybETH contract to burn the receipt NFT and receive the underlying unstaked $ETH.
function unbond(
uint256 _tokenId,
address _receiver
)_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.
Last updated