# Smart Contracts

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

### Protocol-wide contracts <a href="#protocol-wide-contracts" id="protocol-wide-contracts"></a>

> These contracts are deployed only once per chain.

* `ARBERA` — ERC20 token.
* `ProtocolFees` — Stores two fee values.
  * `yieldAdmin` — `ARBERA` and rewards fee % for Future LP Yield.
  * `yieldProtocol` — `brTOKEN` fee % for the protocol.
* `ProtocolFeeRouter` — Stores mutable address of `ProtocolFees`.
* `IndexManager` — Stores all Den addresses and boolean if they are verified or not.
* `RewardsWhitelister` — Stores list of whitelisted reward tokens.
* `UniswapDexAdapter` — Helper contract for adding liquidity and swapping on Uniswap/forks.
* `V3TwapUtilities` — Helper functions to compute Uniswap V3 X96 price, it's square root and derive V3 pool address deterministically.

### Den-related smart contracts <a href="#den-related-smart-contracts" id="den-related-smart-contracts"></a>

> These three contracts implementations are deployed once.

* `WeightedIndex` — Main Den contract (inherits from `DecentralizedIndex`).
* `StakingPoolToken` — Allows staking Den LP tokens.
* `TokenRewards` — Accumulates and distributes rewards for staked Den LP tokens.

New Dens are created by calling `WheightedIndexFactory` .

{% tabs %}
{% tab title="WeightedIndex.sol" %}

### Variables <a href="#variables" id="variables"></a>

* `address PAIRED_LP_TOKEN` — paired Den LP token, eg. `HONEY`;
* `Config config` — Configuration:
  * `address partner` — Address of Den creator.
* `Fees fees` — Struct with Den fees:
  * `uint16 burn` — Burn fee (see ).
  * `uint16 bond` — Fee on wrapping `TOKEN` into `brTOKEN`.
  * `uint16 debond` — Fee on unwrapping `brTOKEN` into `TOKEN`.
  * `uint16 buy` — Fee on buying `brTOKEN` with `TOKEN`.​
  * `uint16 sell` — Fee on selling `brTOKEN` for `TOKEN`.
  * `uint16 partner` — Den creator fee.
  * For all the fees: `1000 = 10%, 100 = 1%, etc.`
* `uint256 created` — Timestamp of Den creation.
* `address lpRewardsToken` — Address of LP rewards token.
* `address lpStakingPool` — Address of Staked Den LP token.

### Functions

{% code overflow="wrap" %}

```solidity
/**
 * Wraps TOKEN into brTOKEN at current ratio (always >= 1) minus fees.
 * @param _token TOKEN address to wrap into brTOKEN.
 * @param _amount Amount of TOKEN to wrap.
 * @param _amountMintMin Minimal brTOKEN amount to receive.
 */
function bond(address _token, uint256 _amount, uint256 _amountMintMin)

/**
 * Unwraps brTOKEN into TOKEN at current ratio (always >= 1) minus fees.
 * @dev Set unnamed params as empty arrays.
 * @param _token Amount of brTOKEN to unwrap into TOKEN.
 */
function debond(uint256 _amount, address[] memory, uint8[] memory)

/**
 * Adds liquidity to the Den LP while disabling fees.
 * @param idxTokens Amount of brTOKEN.
 * @param daiTokens Amount of PAIRED_LP_TOKEN.
 * @param slippage Amount of slippage (10 == 1%).
 * @param deadline Max timestamp to execute the tx.
 */
function addLiquidityV2(uint256 idxTokens, uint256 daiTokens, uint256 slippage, uint256 deadline) returns (uint256);

/**
 * Removes liquidity from the Den LP while disabling fees.
 * @param _lpTokens Amount of Den LP tokens.
 * @param _minTokens Minimal amount of brTOKEN to receive.
 * @param _minDAI Minimal amount of PAIRED_LP_TOKEN to receive.
 * @param _deadline Max timestamp to execute the tx.
 */
function removeLiquidityV2(uint256 _lpTokens, uint256 _minTokens, uint256 _minDAI, uint256 _deadline)

/**
 * Take flashloan of TOKEN backing the brTOKEN, paying 10 HONEY fee.
 * @dev HONEY needs to be approved for spending by Den contract.
 * @param _recipient Address of flashloan receipient.
 * @param _token Address of the TOKEN to flashloan.
 * @param _amount Amount of the TOKEN to flashloan.
 * @param _data Data to send to the receipient in the callback.
 */
function flash(address _recipient, address _token, uint256 _amount, bytes calldata _data)
```

{% endcode %}
{% endtab %}

{% tab title="StakingPoolToken.sol" %}

### Variables

* `address indexFund` — Address of the brTOKEN.
* `address poolRewards` — Address of TokenRewards contract.
* `address stakeUserRestriction` — Boolean if there are staking restrictions.
* `address stakingToken` — Address of the Den LP token.

### Functions

{% code overflow="wrap" %}

```solidity
/**
 * Stakes Den LP tokens for given _user.
 * @param _user Address that will receive Staked Den LP tokens.
 * @param _amount Amount of Den LP tokens to stake.
 */
function stake(address _user, uint256 _amount)

/**
 * Unstakes Den LP tokens.
 * @param _amount Amount of Staked Den LP tokens to unstake.
 */
function unstake(uint256 _amount)
```

{% endcode %}
{% endtab %}

{% tab title="TokenRewards.sol" %}

### Functions

{% code overflow="wrap" %}

```solidity
/**
 * Claims rewards accumualted with Staked Den LP tokens.
 * @param _wallet Address for which to distribute rewards.
 */
function claimReward(address _wallet)

/**
 * Returns unpaid rewards for the user.
 * @param _token Address of the rewards token to check.
 * @param _wallet Address of the user to check.
 * @return Amount of reward tokens to claim.
 */
function getUnpaid(address _token, address _wallet) view returns (uint256)
```

{% endcode %}
{% endtab %}
{% endtabs %}
