|
| 1 | +# Multiwrap design document. |
| 2 | + |
| 3 | +This is a live document that explains what the [thirdweb](https://thirdweb.com/) `Multiwrap` smart contract is, how it works and can be used, and why it is written the way it is. |
| 4 | + |
| 5 | +The document is written for technical and non-technical readers. To ask further questions about thirdweb’s `Multiwrap`, please join the [thirdweb discord](https://discord.gg/thirdweb) or create a github issue. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Background |
| 10 | + |
| 11 | +The thirdweb Multiwrap contract lets you wrap arbitrary ERC20, ERC721 and ERC1155 tokens you own into a single wrapped token / NFT. |
| 12 | + |
| 13 | +The `Multiwrap` contract is meant to be used for bundling up multiple assets (ERC20 / ERC721 / ERC1155) into a single wrapped token, which can then |
| 14 | +be unwrapped in exchange for the underlying tokens. |
| 15 | + |
| 16 | +The single wrapped token received on bundling up multiple assets, as mentioned above, is an ERC721 NFT. It can be transferred, sold on any NFT Marketplace, and |
| 17 | +generate royalties just like any other NFTs. |
| 18 | + |
| 19 | +### Why we’re building `Multiwrap` |
| 20 | + |
| 21 | +We're building `Multiwrap` for cases where an application wishes to bundle up / distribute / transact over *n* independent tokens all at once, as a single asset. This opens |
| 22 | +up several novel NFT use cases. |
| 23 | + |
| 24 | +For example, consider a lending service where people can take out a loan while putting up an NFT as a collateral. Using `Multiwrap`, a borrower can wrap their NFT with |
| 25 | +some ether, and put up the resultant wrapped ERC721 NFT as collateral on the lending service. Now, the bowwoer's NFT, as collateral, has a floor value. |
| 26 | + |
| 27 | +## Technical Details |
| 28 | + |
| 29 | +The `Multiwrap` contract itself is an ERC721 contract. It lets you wrap arbitrary ERC20, ERC721 and ERC1155 tokens you own into a single wrapped token / NFT. This means |
| 30 | +escrowing the relevant ERC20, ERC721 and ERC1155 tokens into the `Multiwrap` contract, and receiving the wrapped NFT in exchange. This wrapped NFT can later be 'unwrapped' |
| 31 | +i.e. burned in exchange for the underlying tokens. |
| 32 | + |
| 33 | +### Wrapping tokens |
| 34 | + |
| 35 | +To wrap multiple ERC20, ERC721 or ERC1155 tokens as a single wrapped NFT, a token owner must first approve the relevant tokens to be transfered by the `Multiwrap` contract, and the token owner must then specify the tokens to wrapped into a single wrapped NFT. The following is the format in which each token to be wrapped must be specified: |
| 36 | + |
| 37 | +```solidity |
| 38 | +/// @notice The type of assets that can be wrapped. |
| 39 | +enum TokenType { ERC20, ERC721, ERC1155 } |
| 40 | +
|
| 41 | +struct Token { |
| 42 | + address assetContract; |
| 43 | + TokenType tokenType; |
| 44 | + uint256 tokenId; |
| 45 | + uint256 amount; |
| 46 | +} |
| 47 | +``` |
| 48 | + |
| 49 | +| Parameters | Type | Description | |
| 50 | +| --- | --- | --- | |
| 51 | +| assetContract | address | The contract address of the asset to wrap. | |
| 52 | +| tokenType | TokenType | The token type (ERC20 / ERC721 / ERC1155) of the asset to wrap. | |
| 53 | +| tokenId | uint256 | The token Id of the asset to wrap, if the asset is an ERC721 / ERC1155 NFT. | |
| 54 | +| amount | uint256 | The amount of the asset to wrap, if the asset is an ERC20 / ERC1155 fungible token. | |
| 55 | + |
| 56 | +Each token in the bundle of tokens to be wrapped as a single wrapped NFT must be specified to the `Multiwrap` contract in the form of the `Token` struct. The contract handles the respective token based on the value of `tokenType` provided. Any incorrect values passed (e.g. the `amount` specified to be wrapped exceeds the token owner's token balance) will cause the wrapping transaction to revert. |
| 57 | + |
| 58 | +Multiple tokens can be wrapped as a single wrapped NFT by calling the following function: |
| 59 | + |
| 60 | +```solidity |
| 61 | +function wrap( |
| 62 | + Token[] memory wrappedContents, |
| 63 | + string calldata uriForWrappedToken, |
| 64 | + address recipient |
| 65 | +) external payable returns (uint256 tokenId); |
| 66 | +``` |
| 67 | + |
| 68 | +| Parameters | Type | Description | |
| 69 | +| --- | --- | --- | |
| 70 | +| wrappedContents | Token[] | The tokens to wrap. | |
| 71 | +| uriForWrappedToken | string | The metadata URI for the wrapped NFT. | |
| 72 | +| recipient | address | The recipient of the wrapped NFT. | |
| 73 | + |
| 74 | +When wrapping multiple assets into a single wrapped NFT, the assets are escrowed in the `Multiwrap` contract until the wrapped NFT is unwrapped. |
| 75 | + |
| 76 | +### Unwrapping the wrapped NFT |
| 77 | + |
| 78 | +The single wrapped NFT, received on wrapping multiple assets as explained in the previous section, can be unwrapped in exchange for the underlying assets. To unwrap a wrapped NFT, the wrapped NFT owner must specify the wrapped NFT's tokenId, and a recipient who shall receive the wrapped NFT's underlying assets. |
| 79 | + |
| 80 | +```solidity |
| 81 | +function unwrap( |
| 82 | + uint256 tokenId, |
| 83 | + address recipient |
| 84 | +) external; |
| 85 | +``` |
| 86 | + |
| 87 | +| Parameters | Type | Description | |
| 88 | +| --- | --- | --- | |
| 89 | +| tokenId | Token[] | The token Id of the wrapped NFT to unwrap.. | |
| 90 | +| recipient | address | The recipient of the underlying ERC1155, ERC721, ERC20 tokens of the wrapped NFT. | |
| 91 | + |
| 92 | +When unwrapping the single wrapped NFT, the wrapped NFT is burned. |
| 93 | + |
| 94 | +### EIPs supported / implemented |
| 95 | + |
| 96 | +The `Multiwrap` contract itself is an ERC721 contract i.e. it implements the [ERC721 standard](https://eips.ethereum.org/EIPS/eip-721). The contract also implements receiver interfaces for ERC721 and ERC1155 so it can receive, and thus, escrow ERC721 and ERC1155 tokens. |
| 97 | + |
| 98 | +The contract also implements the [ERC2981](https://eips.ethereum.org/EIPS/eip-2981) royalty standard. That means the single wrapped token received on bundling up multiple assets can generate royalties just like any other NFTs. |
| 99 | + |
| 100 | + |
| 101 | +## Limitations |
| 102 | + |
| 103 | +Given the same interface for `wrap` and `unwrap`, the contract needs to be optimized for gas i.e. consume as much less gas as possible. |
| 104 | + |
| 105 | +## Authors |
| 106 | +- [nkrishang](https://github.com/nkrishang) |
| 107 | +- [thirdweb team](https://github.com/thirdweb-dev) |
0 commit comments