# Integration 101

You can find deployed contracts addresses and interfaces in [deployed-addresses](https://docs.arbera.io/deployed-addresses "mention").

## View functions

### Get list of all the Dens

```solidity
// IndexManager.sol
struct IIndexAndStatus {
    address index;
    bool verified;
}

function allIndexes() external view returns (IIndexAndStatus[] memory);
```

{% hint style="warning" %}
If the Den is not verified it's better not to interact with it, as it may have been unverified for security reasons.
{% endhint %}

### Get Den Info (CBR, fees)

```solidity
// IndexLens.sol
struct Fees {
    uint16 burn;
    uint16 bond;
    uint16 debond;
    uint16 buy;
    uint16 sell;
}

struct DenInfoMutable {
    uint cbr;
    Fees fees;
    address[] tokens;
    address pairedToken;
    [...]
}
function getIndexImmutableInfo(address _indexAddress) external view returns (DenInfoImmutable memory info_);
```

Returns `DenInfoImmutable` struct with Den info which cannot change:

* `cbr` as a number with 18 decimals.
* `fees` struct with all the fees except partner fee (taken on top of other fees, transparent to the user)
* `tokens` array of underlying assets (currently Arbera supports only 1 asset Dens).
* `pairedToken`  address of the Paired LP Token (currently HONEY or WBERA).

And many more — check out IndexLens.sol verified contract code.

### Calculate CBR (Manual)

```solidity
IDecentralizedIndex index = IDecentralizedIndex(_indexAddress);
uint totalSupply = index.totalSupply();
// Get underlying asset in th Den contract.
// Assuming there is only one underlying asset.
IDecentralizedIndex.IndexAssetInfo[] memory tokens = index.getAllAssets();
uint underlying = IERC20(tokens[0].token).balanceOf(_indexAddress);
uint decimals = IERC20Metadata(tokens[0].token).decimals();
// Normalize decimals
if (decimals < 18) {
	info_.underlying *= 10 ** (18 - decimals);
}
uint cbr = underlying == 0 || totalSupply == 0 ? 1e18 : (underlying * 1e18) / totalSupply;
```

To get CBR just divide `underlying.balanceOf(index)` by `index.totalSupply()` .

If totalSupply is 0 or there is no underlying token deposited it should default to `1e18`.

### Get amount of brTOKEN received by wrapping TOKEN

```solidity
// IndexLens.sol
function getBondAmountsOut(address _index, address _token, uint _amount) external view returns (uint) {
```

* `_index` — address of the Den token.
* `_token` — underlying asset of the Den.
* `_amount` — amount of underlying `_token` to wrap.

Returns amounts of brTOKEN received (after fees and accounting for CBR).

### Get amount of TOKEN received by unwrapping brTOKEN

```solidity
// IndexLens.sol
function getDebondAmountsOut(
    address _index,
    uint _amount
) external view returns (address[] memory tokens_, uint[] memory amounts_)
```

* `_index` — address of the Den token.
* `_amount` — amount of underlying `_index` to unwrap.

Returns array of token addresses and array of amounts.

{% hint style="info" %}
Currently all Dens have single asset, so it's safe to assume you only receive 1 token, ie. length of the arrays equals 1.
{% endhint %}

## Interactions

### Wrap TOKEN into brTOKEN

```solidity
// WeightedIndex.sol
function bond(address token, uint amount, uint amountMintMin) external;
```

* `token` — underlying token address
* `amount` — amount to wrap.
* `amountMintMin` — minimum amount to receive (considdering fees and CBR).

{% hint style="info" %}
Calling this function needs approval of the `amount` of `token` to the Den token contract.
{% endhint %}

### Unwrap brTOKEN into TOKEN

```solidity
// WeightedIndex.sol
function debond(uint amount, address[] memory token, uint8[] memory percentage) external;
```

* `amount` — amount to wrap.
* `amountMintMin` — minimum amount to receive (considering fees and CBR).

{% hint style="info" %}
This function doesn't need approvals.
{% endhint %}

### Add liquidity without fees

```solidity
// WeightedIndex.sol
function addLiquidityV2(uint idxTokens, uint daiTokens, uint slippage, uint deadline) external returns (uint);
```

* `idxTokens` — amount of Den tokens (brTOKEN).
* `daiTokens`  — amount of paired LP Token (currently DAI or WBERA).
* `slippage` — slippage as number with 4 decimals, ie. `100 = 1%`
* `deadline` — deadline timestamp for providing liquidity.

{% hint style="info" %}
Calling this function needs approval of the `daiTokens` of `pairedLPToken (DAI or WEBERA)` to the Den token contract.
{% endhint %}

### Remove liquidity without fees

```solidity
// WeightedIndex.sol
function removeLiquidityV2(uint lpTokens, uint minTokens, uint minDAI, uint deadline) external;
```

* `idxTokens` — amount of Den tokens (brTOKEN).
* `daiTokens`  — amount of paired LP Token (currently DAI or WBERA).
* `slippage` — slippage as number with 4 decimals, ie. `100 = 1%`
* `deadline` — deadline timestamp for providing liquidity.

{% hint style="info" %}
Calling this function needs approval of the `lpTokens` of `LP receipt token` to the Den token contract.
{% endhint %}

### Flash loan underlying tokens

```solidity
/**
 * @notice Take flash loan of underlying tokens.
 * @dev Other index functions are locked during flash loan.
 * @param _recipient Recipient of the flash loan.
 * @param _token Address of the token to flash loan.
 * @param _amount Amount of the token to flash loan.
 * @param _data Data passed to recipient in the callback.
 */
function flash(address _recipient, address _token, uint _amount, bytes calldata _data) external
```

You need to implement `IFlashLoanRecipient` interface.
