vUSD
On this page, you can find the contracts and their interactions involved when bridging to and from Ethereum (L1 - $DAI/$USDC/$USDT) and Cronos zkEVM (L2 - $vUSD ), it includes:
[L1 -> L2] Minting $vUSD with $DAI/$USDC/$USDT
[L2 -> L1] Withdrawing $DAI from $vUSD
[L1 -> L2] Minting $vUSD with $DAI/$USDC/$USDT
From Ethereum mainnet (L1) to Cronos zkEVM mainnet (L2)
To bridge $DAI/$USDC/$USDT from Ethereum mainnet -> Cronos zkEVM mainnet
, and obtain $vUSD we would need to interact with:
ybUSDBridge
$ybUSD token contract
Cronos zkEVM:
0xb1Ece5b548766215272BAFCfa36396B06Cd9e4C9
$vUSD token contract
Cronos zkEVM:
0x5b91e29Ae5A71d9052620Acb813d5aC25eC7a4A2
Step 1) Calculating the amount of $ybUSD to Bridge
On Ethereum, use ybUSD
token contract to call the convertToShares
function:
ybUSD.convertToShares(daiAmount)
daiAmount
The amount of $DAI (with 18 decimals) to be used to mint $ybUSD.
Keep this amount for later steps.
Step 2) Minting And Bridging $ybUSD
On Ethereum, call the mintAndBridge
function on the ybUSDBridge
contract:
function mintAndBridge(
address _l2Receiver,
uint256 _amount,
uint128 _stableCoinType,
uint256 _minAmountAccepted,
uint256 _l2GasLimit,
uint256 _l2GasPerPubdataByteLimit,
address _refundRecipient
)
_l2Receiver
The address on Cronos zkEVM that will receive $ybUSD
_amount
The amount of DAI/(USDC/USDT will be swapped to DAI) to deposit into the $ybUSD contract, in their corresponding decimals ( 18
for $DAI, 6
for $USDC and USDT )
_stableCoinType
Set 0
for $DAI, 1
for $USDC, 2
for $USDT
_minAmountAccepted
Minimum amount accepted when swapping USDC/USDT to DAI
_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 $ybUSD on Ethereum and bridge it to the _l2Receiver
address on L2.
Step 3) Approving $ybUSD to be spend by $vUSD contract
On Cronos zkEVM, call approve
on the ybUSD contract to approve $vUSD contract to spend $ybUSD with appropriate amount.
Step 4) Minting of $vUSD
On Cronos zkEVM, call mint
on $vUSD contract , to mint $vUSD
function mint(
address _receiver,
uint256 _ybUsdAmount
)
_receiver
Address to receive the minted $vUSD tokens
_ybUsdAmount
Amount of $ybUSD to be used to mint $vUSD
This will mint $vUSD into the _receiver
address.
[L2 -> L1] Withdrawing $DAI from $vUSD
From Cronos zkEVM mainnet (L2) -> Ethereum mainnet (L1)
To redeem $vUSD from Cronos zkEVM mainnet -> Ethereum mainnet
, and withdraw $DAI we would need to interact with the following contracts:
$vUSD token contract
Cronos zkEVM:
0x5b91e29Ae5A71d9052620Acb813d5aC25eC7a4A2
L2Bridge
Cronos zkEVM: 0x309429DE3621992Cb0ab8982A448c9Cc5c38405b
zk Chain Shared Bridge
$ybUSD token contract
Cronos zkEVM:
0xb1Ece5b548766215272BAFCfa36396B06Cd9e4C9
Step 1) Approving $vUSD to be spend by vUSD contract
On Cronos zkEVM, call approve
on the $vUSD contract to approve $vUSD spend with appropriate amount.
Step 2) Redeeming $vUSD for $ybUSD
On Cronos zkEVM, call redeem
on the vUSD contract, to burn $vUSD and redeem $ybUSD
function redeem(
address _receiver,
uint256 _vUsdAmount
)
_receiver
Address to receive $ybUSD on Cronos zkEVM
_vUsdAmount
Amount of vUSD that will be burned to redeem $ybUSD
Once done, corresponding $ybUSD will be transfer to the _reciever
address
Step 3) Approving $ybUSD to be spend by the L2Bridge
On Cronos zkEVM, call approve
on the ybUSD contract, to approve L2Bridge contract to spend $ybUSD.
Step 4) Withdrawing $ybUSD 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 $ybUSD in this case.
_amount
amount of tokens to be withdrawn, note $ybUSD has 18
decimals
Keep the transaction hash for later use in Step 5. This withdraws $ybUSD from Cronos zkEVM to Ethereum. It takes 24 hours before the withdrawal can be finalized on Ethereum. Store the transaction hash from the withdrawal transaction; it will be needed to finalize the withdrawal.
Step 5) Gathering information for $ybUSD withdrawal on L1
Extra information for the L2 -> L1 transaction is required for the next step in claiming the $ybUSD. 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 $ybUSD on L1
Once the transaction in Step 4 has been finalized, we can claim the withdrawn $ybUSD from the L2Bridge 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 $ybUSD will go into the receiver's wallet on Ethereum.
We can use zksync-ethers
package isWithdrawalFinalized
call to 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 $ybUSD to be spend by ybUSD contract
On Ethereum, call approve
on the $ybUSD contract, to approve the contract to spend $ybUSD
Step 8) Redeem $ybUSD for $DAI
On Ethereum, call redeem
on the the $ybUSD contract
function redeem(
uint256 _amount
)
_amount
The amount of $ybUSD tokens to redeem for $DAI
Once redeem
is completed, the withdrawn amount of $DAI will go into the receiver's wallet on Ethereum.
Last updated