This method of integration is more involved and is not recommended by the Treasure core team. For a more seamless integration leveraging APIs and SDKs, consider leveraging the Treasure Development Kit (TDK) instead. Little to no developer support will be provided.

Contract Addresses

Click here to view the latest contract addresses.

Contract Calls Samples

Create Vault

1

Navigate to the NftVaultFactory's createVault function

2

Enter an array of CollectionData type objects

enum NftType {
    ERC-721,
    ERC-1155
}

struct CollectionData {
    address addr;
    NftType nftType;
    bool allowAllIds;
    uint256[] tokenIds;
}
  • For example, if you want to create a vault for Zeeverse Zee Items (ERC-1155), the function param would be:
[["0xfaad5aa3209ab1b25ede22ed4da5521538b649fa",1,true,[]]]
  • The vault can also be restricted to specific token IDs. For example, a vault only for the Gloop Zee Item would be created with the following param:
[["0xfaad5aa3209ab1b25ede22ed4da5521538b649fa",1,false,[100920002]]]
  • The resulting transaction will emit a VaultCreated event, and the value in Topics[0] is the newly created vault’s contract address. For the examples below, we will use the Common Zee Items vault created at 0x8D5d711340047f9e855BBe86Ee0D8d7e7412585a

Add Liquidity

Creating a liquidity pool

If you are the first one adding liquidity for a specific pair, you get to set the price. For this example, we’ll create a Zee Items-MAGIC pool:

1

Mint 1,000 MAGIC

2

Approve the MagicswapV2Router address as a spender of 1,000 MAGIC

3

Approve the MagicswapV2Router address as an operator on the Zeeverse Zee Items

4

Navigate to the MagicswapV2Router's addLiquidityNFT function and enter the following parameters:

["vault address from previous step",["0xfaad5aa3209ab1b25ede22ed4da5521538b649fa","0xfaad5aa3209ab1b25ede22ed4da5521538b649fa","0xfaad5aa3209ab1b25ede22ed4da5521538b649fa"],[100120006,100120007,100120008],[5,5,5]]
_tokenB: 0x55d0cf68a1afe0932aff6f36c87efa703508191c
_amountBDesired: 1000000000000000000000
_amountBMin: 1000000000000000000000
_to: <your address>
_deadline: <future timestamp>

This will deposit 15 Zee Items and 1,000 MAGIC into the pool, meaning each Zee Item will be worth ~66 MAGIC at pool creation

Adding to an existing liquidity pool

If a liquidity pool for your desired pair has already been created, then the price is already set and your deposit must conform to the current pool pricing. The two sides of the pool are always balanced, so you need to deposit equal value amounts on both sides. To do so, you first need to determine the value of each side of the pool.

For the examples below, we will use the VEE-Common Zee Items pool created at 0x77d3d38ef24a2179b5147d8ebdab84b26012b210. If the contract is not verified on Arbiscan, you can use the UniswapV2Pair ABI to make read contract calls.

1

Price the assets

  1. If you don’t know which tokens are token0 and token1, call those read functions to get their addresses as results:
    • token0: 0x23BE0504127475387A459FE4b01E54f1E336fFae (VEE)
    • token1: 0x8D5d711340047f9e855BBe86Ee0D8d7e7412585a (Common Zee Items Vault)
  2. Fetch the pair’s reserves with the getReserves function, and get a response like:
[ "91014278791430471188848", "89000000000000000000", "1719379919" ]

This means that ~91,014 VEE and 89 Common Zee Items are deposited in the pool right now. Since we know both sides are equal, we can calculate the price of 1 Common Zee Item:

1000000000000000000 * 91014278791430471188848 / 89000000000000000000 = 1022632345971128889762

1 Common Zee Item = ~1022.63 VEE

2

Approve the assets for transfer

On the VEE contract, call approve with the MagicswapV2Router (0xd0A4FbCc5cDe863A2BE50C75b564Efd942b03154) as spender and an amount of 1022632345971128889762

On the Vee Items contract, call setApprovalForAll with the MagicswapV2Router (0xd0A4FbCc5cDe863A2BE50C75b564Efd942b03154) as operator and approved with a value of true”>

3

Add liquidity

On the MagicswapV2Router contract, call addLiquidityNFT with the following params:

struct NftVaultLiquidityData {
INftVault token;
address[] collection;
uint256[] tokenId;
uint256[] amount;
}
  • token is the NFT’s vault address
  • collection is a list of the NFT addresses
  • tokenId is a list of the NFT token IDs
  • amount is a list of the number of NFT tokens. The lists all need to have the same lengths for a transaction to be valid
  • _tokenB is the ERC-20 token address
  • _amountBDesired is the amount of _tokenB that we are expecting to deposit to the pool
  • _amountBMin is the minimum amount of _tokenB we are willing to deposit after slippage
_amountBMin = _amountBDesired - (_amountBDesired * slippage)

Assuming a slippage setting of 0.5%:

1022632345971128889762 - (1022632345971128889762 * 0.005 * 1000) / 1000 = 1017519184241273245314
  • _to is the address that should receive the resulting LP tokens
  • _deadline is any future timestamp, in seconds
_vault: ["0x8D5d711340047f9e855BBe86Ee0D8d7e7412585a",["0xfaad5aa3209ab1b25ede22ed4da5521538b649fa"],[100220071],[1]]
_tokenB: 0x23BE0504127475387A459FE4b01E54f1E336fFae
_amountBDesired: 1022632345971128889762
_amountBMin: 1017519184241273245314
_to: <your address>
_deadline: <future timestamp>

Remove Liquidity

When you add liquidity by depositing ERC-20 and ERC-1155 tokens, you are minted LP tokens (ERC-20) to represent your holdings. When you want to remove liquidity, you burn those LP tokens in exchange for equal amounts of the ERC-20 and ERC-1155 tokens.

1

On the LP token contract

  1. Call approve with the MagicswapV2Router (0xd0A4FbCc5cDe863A2BE50C75b564Efd942b03154) as spender and the amount of tokeLP ns you will remoburnl getReserves to get the latest reserve info
  2. Call totalSupply to get the latest total supply info

The amount of NFTs you can withdraw depends on the amount of LP tokens you are going to burn, rounded down to the nearest whole number:

nftAmount = floor(lpAmount * nftReserve / lpTotalSupply)
2

On the MagicswapV2Router contract, call removeLiquidityNFT with the following params:

  • _vault follows the same format as _addLiquidityNFT
  • _tokenB is the ERC-20 token address
  • _lpAmount is the amount of LP token to burn
  • _amountAMin the amount of NFTs we want to receive
  • _amountBMin is the minimum amount of _tokenB we are willing to receive after slippage
amountBDesired = lpAmount * reserveB / lpTotalSupply
amountBMin = _amountBDesired - (_amountBDesired * slippage)
  • _to is the address that should receive the resulting LP tokens
  • _deadline is any future timestamp, in seconds
  • _swapLeftover is true if we want to swap any leftover NFT dust into _tokenB instead of receiving a fractional NFT Vault token
_vault: ["0x8D5d711340047f9e855BBe86Ee0D8d7e7412585a",["0xfaad5aa3209ab1b25ede22ed4da5521538b649fa","0xfaad5aa3209ab1b25ede22ed4da5521538b649fa","0xfaad5aa3209ab1b25ede22ed4da5521538b649fa","0xfaad5aa3209ab1b25ede22ed4da5521538b649fa"],[100420001,100420018,100220043,100220074],[10,10,10,1]]
_tokenB: 0x23BE0504127475387A459FE4b01E54f1E336fFae
_lpAmount: 1000000000000000000000
_amountAMin: 31000000000000000000
_amountBMin: 31819262052842768393323
_to: <your address>
_deadline: <future timestamp>
_swapLeftover: true

Swap ERC-20 to NFT

We’ll cover the “exact out” scenario, where a user specifies an exact number of NFTs they want to receive, and calculate the required ERC-20 swap input taking into account current reserves, fees and price impact.

To properly complete a swap, you will need to calculate the value of _amountInMax, the maximum amount of ERC-20 tokens the user is willing to pay for the trade after fees and slippage.

1

Calculate _amountInMax

  1. Fetch the pair’s reserves with the getReserves function
  2. On the UniswapV2Factory contract, call getTotalFee with the pool address as the parameter to receive the total fees set for this pair with base 10,000:
UniswapV2Factory.getTotalFee(0x77d3d38ef24a2179b5147d8ebdab84b26012b210)
// totalFee = 30
// 30 / 10000 = 0.003 = 0.3%

Calculate the amountIn with the following logic:

uint256 numerator = reserveIn.mul(amountOut).mul(10000);
uint256 denominator = reserveOut.sub(amountOut).mul(10000 - totalFee);
amountIn = (numerator / denominator).add(1);

For example, if looking to swap for 1 Common Zee Item:

totalFee = 30n
numerator = 91020424024034239548130n * 1000000000000000000n * 10000n = 910204240240342395481300000000000000000000000n
denominator = (89000000000000000000n - 1000000000000000000n) * (10000n - 30n) = 877360000000000000000000n
amountIn = (910204240240342395481300000000000000000000000n / 877360000000000000000000n) + 1n = 1037435306191691432800n

Calculate the amountInMax with the following logic:

amountInMax = amountIn + (amountIn * slippage)

Assuming a slippage setting of 0.5%:

1037435306191691432800n + (1037435306191691432800n * 5n) / 1000n = 1042622482722649889964n

Price impact is the difference between amountIn and a straight trade based on current reserves:

priceImpact = 1 - amountOut / (amountIn * reserveOut / reserveIn)

1 - 1000000000000000000n / (1037435306191691432800n * 89000000000000000000n / 91014278791430471188848n) =
1 - 1000000000000000000n / 1014475349111420012n =
1 - 1 / 1.014475 = 0.014268 = -1.4%
2

Approve the assets for transfer

On the VEE contract, call approve with the MagicswapV2Router (0xd0A4FbCc5cDe863A2BE50C75b564Efd942b03154) as spender and an amount of 1042622482722649889964

3

Swap

On the MagicswapV2Router contract, call swapTokensforNft with the following params:

  • _collection is a list of the NFT addresses
  • _tokenId is a list of the NFT token IDs
  • _amount is a list of the number of NFT tokens
    • The lists all need to have the same lengths for a transaction to be valid
  • _amountInMax from the previous step
  • _path is a list of addresses that this swap route will take. For a single pool, this will just be both sides of the pool (e.g., Common Zee Item to VEE swap will be the Common Zee Items vault and the VEE token address). Specifying more than two addresses in this path allows you to route through multiple pools, for example doing a trade from Common Zee Items to MAGIC, when only the VEE-Common Zee Items and MAGIC-VEE pools exist.
  • _to is the address that should receive the resulting ERC-20 tokens
  • _deadline is any future timestamp, in seconds
_collection: [0xfaad5aa3209ab1b25ede22ed4da5521538b649fa]
_tokenId: [100220071]
_amount: [1]
_amountInMax: 1042622482722649889964
_path: [0x23BE0504127475387A459FE4b01E54f1E336fFae,0x8D5d711340047f9e855BBe86Ee0D8d7e7412585a]
_to: <your address>
_deadline: <future timestamp>

Swap NFT to ERC-20

We’ll cover the “exact in” scenario, where a user specifies an exact number of NFTs they want to trade, and calculate the resulting ERC-20 swap taking into account current reserves, fees and price impact.

1

Approve the assets for transfer

On the Zee Items contract, call setApprovalForAll with the MagicswapV2Router (0xd0A4FbCc5cDe863A2BE50C75b564Efd942b03154) as operator and approved with a value of true

2

Calculate _amountOutMin

To properly complete a swap, you will need to calculate the value of _amountOutMin, the minimum amount of ERC-20 tokens the user is willing to receive for the trade after fees and slippage.

  1. Fetch the pair’s reserves with the getReserves function
  2. On the UniswapV2Factory contract, call getTotalFee with the pool address as the parameter to receive the total fees set for this pair with base 10,000:
UniswapV2Factory.getTotalFee(0x77d3d38ef24a2179b5147d8ebdab84b26012b210)
// totalFee = 30
// 30 / 10000 = 0.003 = 0.3%
  1. Calculate the amountOut with the following logic:
uint256 amountInWithFee = amountIn.mul(10000 - totalFee);
uint256 numerator = amountInWithFee.mul(reserveOut);
uint256 denominator = reserveIn.mul(10000).add(amountInWithFee);
amountOut = numerator / denominator;

For example, if looking to swap 1 Common Zee Item:

totalFee = 30n
amountInWithFee = 1000000000000000000n * (10000n - 30n) = 9970000000000000000000n
numerator = 9970000000000000000000n * 91020424024034239548130n = 907473627519621368294856100000000000000000000n
denominator = 89000000000000000000n * 10000n + 9970000000000000000000n = 899970000000000000000000n
amountOut = 907473627519621368294856100000000000000000000n / 899970000000000000000000n = 1008337641832084812043n

Calculate the amountOutMin with the following logic:

amountOutMin = amountOut - (amountOut * slippage)

Assuming a slippage setting of 0.5%:

1008337641832084812043n - (1008337641832084812043n * 5n) / 1000n = 1003295953622924387983n
  • Price impact is the difference between amountOut and a straight trade based on current reserves:
priceImpact = 1 - amountOut / (amountIn * reserveOut / reserveIn)

1 - 1008337641832084812043n / (1000000000000000000n * 91014278791430471188848n / 89000000000000000000n) =
1 - 1008337641832084812043n / 1022632345971128889762n =
1 - 1008.3376 / 1022.6323 = 0.01397 = -1.4%
3

Swap

On the MagicswapV2Router contract, call swapNftForTokens with the following params:

  • _collection is a list of the NFT addresses
  • _tokenId is a list of the NFT token IDs
  • _amount is a list of the number of NFT tokens
    • The lists all need to have the same lengths for a transaction to be valid _amountOutMin from the previous step
  • _path is a list of addresses that this swap route will take. For a single pool, this will just be both sides of the pool (e.g., Common Zee Item to VEE swap will be the Common Zee Items vault and the VEE token address). Specifying more than two addresses in this path allows you to route through multiple pools, for example doing a trade from Common Zee Items to MAGIC, when only the VEE-Common Zee Items and MAGIC-VEE pools exist.
  • _to is the address that should receive the resulting ERC-20 tokens
  • _deadline is any future timestamp, in seconds
_collection: [0xfaad5aa3209ab1b25ede22ed4da5521538b649fa]
_tokenId: [100220071]
_amount: [1]
_amountOutMin: 1003295953622924387983
_path: [0x8D5d711340047f9e855BBe86Ee0D8d7e7412585a,0x23BE0504127475387A459FE4b01E54f1E336fFae]
_to: <your address>
_deadline: <future timestamp>