# Contracts and Functions

Baskets are pools of NFTs that allow users to swap their NFTs for ERC-20 tokens. Currently, Tangible Baskets only support real estate NFTs. This allows any Tangible Real Estate NFT holder (TNFT) to deposit their NFT into a basket in exchange for basket tokens, as long as their NFT is compatible.

The basket will have a deployer (aka "BasketManager") which allows users to create a unique basket. The BasketManager is the central point of the baskets and keeps an array of all existing baskets. A user can only create a basket if they hold a TNFT of that specific category/subcategory.

Baskets allow any Tangible NFT holders to deposit freely in exchange for basket tokens (as long as the TNFT is compatible). A 0.5% mint fee is applied to all Basket mint transactions.

Basket tokens can be freely redeemed whole property TNFTs, with one randomly-selected TNFT designated for redemption at a time.

## Basket

### Code

[Basket.sol](https://github.com/TangibleTNFT/baskets-foundry/blob/main/src/Basket.sol)

### Create your own

See guide on how to [create your own basket.](/baskets/technical/guides.md#creating-a-basket)

### Read Functions

#### **getQuoteIn**

{% code overflow="wrap" fullWidth="false" %}

```javascript
function getQuoteIn(address _tangibleNFT, uint256 _tokenId) external view returns (uint256 shares);
```

{% endcode %}

Returns an amount of ERC-20 tokens you’d receive if the specified token was deposited into the basket.

* Does NOT include the amount of basket tokens subtracted for deposit fee.

#### **getQuoteOut**

{% code overflow="wrap" %}

```javascript
function getQuoteOut(address _tangibleNFT, uint256 _tokenId) external view returns (uint256 sharesRequired);// Some code
```

{% endcode %}

Returns an amount of ERC-20 tokens required if you were to redeem the specified NFT from the basket.

#### **getRentBal**

{% code overflow="wrap" %}

```javascript
function getRentBal() external view returns (uint256 totalRent);
```

{% endcode %}

Returns the unclaimed rent balance of all TNFTs inside the basket + any rent already claimed and sitting within the basket.

* Returns an amount in USD (stablecoin) with 18 decimal points

#### **getDepositedTnfts**

{% code overflow="wrap" %}

```javascript
function getDepositedTnfts() external view returns (TokenData[] memory);
```

{% endcode %}

Returns the `depositedTnfts` state array. This array contains data for every NFT stored inside the basket.

#### **getTnftsSupported**

{% code overflow="wrap" %}

```javascript
function getTnftsSupported() external view returns (address[] memory);
```

{% endcode %}

Returns the `tnftsSupported` state array. This array contains addresses for every TNFT contract address that has NFTs stored in the basket.

#### **getTokenIdLibrary**

{% code overflow="wrap" %}

```javascript
function getTokenIdLibrary(address _tnft) external view returns (uint256[] memory);
```

{% endcode %}

Returns the `tokenIdLibrary` mapped array. This array contains tokenIds for each token stored in this contract, given the TNFT contract address.

#### **getSupportedFeatures**

{% code overflow="wrap" %}

```javascript
function getSupportedFeatures() external view returns (uint256[] memory);
```

{% endcode %}

Returns the `supportedFeatures` state array. This array contains all features the basket supports and therefore all NFTs must support in order to be compatible with the basket.

#### **getSharePrice**

{% code overflow="wrap" %}

```javascript
function getSharePrice() public view returns (uint256 sharePrice);
```

{% endcode %}

Returns the USD value per basket share in 18 decimals.&#x20;

#### **getTotalValueOfBasket**

{% code overflow="wrap" %}

```javascript
function getTotalValueOfBasket() public view returns (uint256 totalValue);
```

{% endcode %}

Returns the total USD value of the basket.

* This value is calculated as the total value of all deposited NFTs + accrued rent + unclaimed rent.
* The rent value used is only updated post-rebase.

#### **isCompatibleTnft**

{% code overflow="wrap" %}

```javascript
function isCompatibleTnft(address _tangibleNFT, uint256 _tokenId) public view returns (bool);
```

{% endcode %}

Returns true if a specified token is compatible with the basket and thus can be deposited into the basket.

A token is compatible if and only if:

* It is of the same category (or “type”)
* It supports all subcategories (aka “features”) as the basket.
* It is in the same location as the basket. (i.e. “US” or “UK”)

### Write Functions

#### **depositTNFT**

{% code overflow="wrap" %}

```javascript
function depositTNFT(address _tangibleNFT, uint256 _tokenId) external returns (uint256 basketShare);
```

{% endcode %}

This method allows any user with a compatible NFT to deposit their NFT into the basket in exchange for minted basket tokens.

* Any unclaimed rent claimable from the rent manager is claimed and transferred to the depositor.
* A deposit fee is taken upon every deposit which (by default) is .5% of basket tokens.
* The basket tokens (aka “shares”) minted is calculated using the USD value of the NFT deposited.
* The token being deposited MUST be approved on the TNFT contract before executing a deposit.

#### **batchDepositTNFT**

{% code overflow="wrap" %}

```javascript
function batchDepositTNFT(address[] memory _tangibleNFTs, uint256[] memory _tokenIds) external returns (uint256[] memory basketShares);
```

{% endcode %}

This method allows any user with a 1 or more compatible NFTs to deposit a batch of NFTs into the basket in exchange for minted basket tokens.

* Any unclaimed rent claimable from the rent manager is claimed and transferred to the depositor.
* A deposit fee is taken upon every deposit which (by default) is .5% of basket tokens.
* The basket tokens (aka “shares”) minted is calculated using the USD value of the NFTs deposited taking into account the native share price.
* The tokens being deposited MUST be approved on the TNFT contract(s) before executing a batch deposit.

#### **redeemTNFT**

{% code overflow="wrap" %}

```javascript
function redeemTNFT(uint256 _budget, bytes32 _desiredToken) external;
```

{% endcode %}

This method is used to redeem an NFT from the basket in exchange for basket tokens. This method will take a budget of basket tokens and your desired token data (NFT contract address + tokenId) and if the budget is sufficient will transfer the NFT stored in `nextToRedeem` to the msg.sender.

* The NFT stored in `nextToRedeem` is randomly chosen via VRF.
* After a successful execution of this method, a new \*random\* NFT will be chosen.
* The basket tokens (aka “shares”) burned are calculated using the USD value of the NFTs deposited taking into account the native share price.

#### **rebase**

{% code overflow="wrap" %}

```javascript
function rebase() public;
```

{% endcode %}

This function allows for the Basket token to "rebase" and will update the rebase multiplier (aka “rebaseIndex”) based on the amount of rent accrued by the basket tokens.

* As the amount of rent accrued increases, every balance of basket token holders will also increase.
* 10% of the incoming rent is distributed to veRWA holders.

## BasketManager

### Code

[BasketManager.sol](https://github.com/TangibleTNFT/baskets-foundry/blob/main/src/BasketManager.sol)

### Address

`0x5e581ce0472bF528E7F5FCB96138d7759AC2ac3f`

### Read Functions

#### **getBasketsArray**

{% code overflow="wrap" %}

```javascript
function getBasketsArray() external view returns (address[] memory);
```

{% endcode %}

Returns an array of basket addresses that have been deployed.

#### fetchBasketByHash

{% code overflow="wrap" %}

```javascript
function fetchBasketByHash(bytes32 _featuresHash) public view returns (address);
```

{% endcode %}

Returns the address associated with a features hash. If address(0), hash is not taken.

* A hash is consisted of 3 things:
  * tnftType of basket as uint256
  * location ISO code as uint16
  * array of features as uint256

#### **createHash**

{% code overflow="wrap" %}

```javascript
function createHash(uint256 _tnftType, uint16 _location, uint256[] memory _features) public pure returns (bytes32 hashedFeatures);
```

{% endcode %}

Takes the 3 arguments that create a unique basket and creates a 32 byte hash. The 3 arguments are mentioned above.

### Write Functions

#### **deployBasket**

{% code overflow="wrap" %}

```javascript
function deployBasket(
    string memory _name,
    string memory _symbol,
    uint256 _tnftType,
    uint16 _location,
    uint256[] memory _features,
    address[] memory _tangibleNFTDeposit,
    uint256[] memory _tokenIdDeposit
) external returns (IBasket, uint256[] memory basketShares);
```

{% endcode %}

This method deploys a new Basket contract.

* The combination of `_tnftType`, `_location`, and `_features` MUST be unique.
* The `_name` must be unique
* The `_symbol` must be unique
* 1 or more compatible NFTs must be specified as the initial deposit.
* `_features` must be sorted and cannot contain duplicates.

This method returns the address of the new basket as well as the array of basket tokens minted to the deployer.

## BasketVrfConsumer

### Code

[BasketsVrfConsumer.sol](https://github.com/TangibleTNFT/baskets-foundry/blob/main/src/BasketsVrfConsumer.sol) inherits `GelatoVRFConsumerBaseUpgradeable`

### Address

`0x68179D8f2dbd5969F421DfC5f92C40ecDD530c41`

### Read Functions

#### **requestTracker**

{% code overflow="wrap" %}

```javascript
function requestTracker(uint256) public view returns (address);
```

{% endcode %}

Returns the address of a basket that made the VRF request, given the requestId.

#### **outstandingRequest**

```javascript
function outstandingRequest(address) public view returns (uint256);
```

Returns the outstanding requestId for a specified basket’s pending request for entropy, if any.

### Write Functions

#### **makeRequestForRandomWords**

```javascript
function makeRequestForRandomWords() external onlyBasket returns (uint256 requestId);
```

This method makes a request to Gelato VRF. It will return with a valid requestId provided by Gelato.

* Only callable by a basket contract.

#### **fulfillRandomWords**

{% code overflow="wrap" %}

```javascript
function fulfillRandomness(uint256 randomness, bytes calldata dataWithRound) external;
```

{% endcode %}

This method is the VRF callback function. Vrf coordinator will respond with our random word by calling this method.

* Only callable by the VRF coordinator contract.
* Will make an external call to the appropriate basket awaiting entropy. Will be used to generate the next redeemable NFT in that basket.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tangible.store/baskets/technical/contracts-and-functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
