ERC20 Wrapper

The ERC20 Wrapper contract allows for the wrapping of ERC20s and ETH as Items, and for the burning of Item-wrapped ERC20s and ETH to retrieve the original tokens.

Wrapped Item name and symbol

A wrapped ERC20 Item has the following metadata:

  • Name -> "ERC20 token wrapped name" + item

  • Symbol -> i"ERC20 token wrapped symbol"

Example

Wrapped USDC:

  • name -> USDC item

  • symbol -> iUSDC

Wrapped ETH:

  • name -> Ethereum item

  • symbol -> iETH

Wrapped DAI:

  • name -> DAI item

  • symbol -> iDAI

Decimals

All Item-wrapped ERC20s and ETH always have 18 decimals, both as ERC1155 (using the Item Main Interface) and as ERC20 (using the Item Interoperable Interface).

It is possible to wrap ERC20s that have decimals different from 18, but their Item-wrapped versions will always have 18.

The amount conversion follows this rule:

Wrapped Item amount = ERC20 amount*10^(18-ERC20 decimals)

Example

1)

If you wrap 1000 USDC (which has 6 decimals), it becomes 1000000000000000 iUSDC.

Unwrapping 1000000000000000iUSDC gives you back 1000 USDC.

2)

If you wrap 350 HEX (which has 8 decimals), it becomes 3500000000000 iHEX.

Unwrapping 3500000000000 iHEX gives you back 350 HEX.

Deflationary Tokens

It is also possible to Item-wrap deflationary ERC20s—that is, tokens that burn some of their supply whenever an amount of the token is transferred.

For example, imagine there is the deflationary token $JPN. You wrap 10 $JPN as Items, but 1 is burned in the process, so you end up with only 9 wrapped Item $JPN.

However, while your $JPN is Item-wrapped, none will be burned when transferred.

Only one token address per transaction can be wrapped, this means that batch wraps cannot be performed using deflationary tokens.

Wrap an ERC20/ETH

mintItems

function mintItems(CreateItem[] calldata createItemsInput) virtual override(Item, ItemProjection) external returns(uint256[] memory) 

The function takes as input:

  • struct CreateItem -> data for wrapping the ERC20

For each ERC20 you're wrapping, a CreateItem must be passed as follows:

  • struct Header -> composed of address host, string name, string symbol and string uri pass empty. These parameters are automatically populated by the contract. Look here for more info

  • bytes32 collection -> encoded ERC20 address of the token being wrapped. Pass 0x000... for ETH.

  • uint256 id -> pass empty

  • address[] accounts -> address receiver of the Wrapped Item. Pass address(0) to set receiver as msg.sender. It can even be an address different from the msg.sender

  • uint256[] amounts -> amounts being wrapped

The amounts[] array can specify the different amounts of the created wrapped Item to send to the receivers' addresses represented by the accounts[] array. Each position of the amounts array corresponds to the respective position of the accounts array and so the amounts[] and accounts[] arrays must have the same length. If an address in the accounts[] is passed as address(0), it automatically corresponds to the msg.sender address.

The amount(s) value(s) must be expressed in the decimals of the original ERC20 token.

The output of the function represents the id(s) of the newly created wrapped Item(s).

Using the mintItems functions, different ERC20 tokens can be wrapped in a single transaction since you can pass multiple CreateItem structs.

mintItems with Permit

 function mintItemsWithPermit(CreateItem[] calldata createItemsInput, bytes[] memory permitSignatures) public override payable returns(uint256[] memory itemIds) {

This version of the mintItems function can be used to wrap ERC20s that support the Permit approval. In this way you don't have to execute the approve of your ERC20s and so pay the gas fee.

The function takes as input:

  • struct CreateItem -> data for wrapping the ERC20. Same as the previous mintItems function

  • bytes[] permitSignatures -> it can contain the bytes data representing the permit signature to perform the off-chain sign. If the permitSignatures is passed as 0x, the classic on-chain approve is required.

Each position of the CreateItem array corresponds to the respective position of the permitSignatures array and so the CreateItem and permitSignatures arrays must have the same length.

Unwrap Items

Burn

function burn(address account, uint256 itemId, uint256 amount, bytes calldata data) external;

The burn function can be used to burn a wrapped ERC20/ETH Item amount and retrieve the relative amount of the original ERC20 token or ETH.

The function takes as input:

  • address account -> represents the address that holds the Item to burn. The address account can correspond to the msg.sender or not if the burn function is called from an approved operator address.

  • uint256 itemId -> represents the id of the wrapped Item to burn

  • uint256 amount ->represents the wrapped Item amount to burn

  • bytes data -> it is an encoded value and represents two parameters:

    • address tokenAddress -> original ERC20 token address to retrieve

    • address receiver -> address receiver of the original ERC20 token once the Item is burned. Pass address(0) to set receiver as msg.sender. It can even be an address different from the msg.sender:

(address tokenAddress, address receiver) = abi.decode(data, (address, address));

Burn Batch

function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts, bytes calldata data) external;

The burnBatch function can be used to burn multiple wrapped ERC20/ETH Items amounts and retrieve the relative amounts of the original ERC20 tokens or ETHs.

The function parameters are the same of the burn function with the following differences:

  • uint256[] itemId and uint256[] amount-> are arrays of values since you can unwrap multiple tokens at once

  • bytes data ->The data parameter in bytes format is an encoded value and represents a bytes[] (one for each Item involved in the operation) containing the six parameters explained above in the burn section:

bytes[] memory datas = abi.decode(data, (bytes[]));
(address tokenAddress, address receiver) = abi.decode(data, (address, address));

Last updated