# Fund

## Getting Fund Info

#### `Fund.tokenUnderlying() → address`

The address of the underlying asset.

```shell
>>> fund.tokenUnderlying()
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
```

#### `Fund.tokenShare(uint256 tranche) → address`

Getter for one of the addresses of `tranche`: QUEEN (0), BISHOP (1) or ROOK (2).

```bash
>>> fund.tokenShare(0)
'0x93ef1Ea305D11A9b2a3EbB9bB4FCc34695292E7d'
```

#### `Fund.primaryMarket() → address`

The address of the primary market contract.

```bash
>>> fund.primaryMarket()
'0xcD0B4D35cc6Ec86d1D52b8Eb07b5d029e39bA70E'
```

#### `Fund.primaryMarketUpdateProposal() → address, uint256`

Getter for the upcoming primary market upgrade, if any.

#### `Fund.twapOracle() → ITwapOracleV2`

The TWAP Oracle of the underlying asset.

```bash
>>> fund.twapOracle()
'0x2BaC57D29570Fe56B60216c26dA3C5B5c804B916'
```

#### `Fund.feeCollector() → address`

The address of the fee collector of the fund.

```bash
>>> fund.feeCollector()
'0xbc428f6573827Db9773F9e4bC1f5C899c884842c'
```

#### `Fund.endOfDay(uint256 timestamp) → uint256`

It calculates the trading day end timestamp of the given `timestamp`. A trading day starts at UTC time `SETTLEMENT_TIME` of a day (inclusive) and ends at the same time of the next day (exclusive).

```bash
>>> fund.endOfDay(1604214000)
'1604239200'
```

#### `Fund.trancheTotalSupply(uint256 tranche) → uint256`

Getter for the total supply of `tranche`.

```bash
>>> fund.trancheTotalSupply(0)
'144207156642170957094'
```

#### `Fund.getRebalanceSize() → uint256`

Getter for the number of historical rebalances.

```bash
>>> fund.getRebalanceSize()
'1'
```

#### `Fund.getRebalance(uint256 index) → Rebalance`

Getter for the Rebalance parameters of a given rebalance version.

```bash
>>> fund.getRebalance(0)
ratioB2Q: '442549502169234'
ratioR2Q: '0'
ratioBR: '474988241234265736'
timestamp: '1668702923'
```

#### `Fund.currentDay() → uint256`

The end timestamp of the current trading day.

```bash
>>> fund.currentDay()
'1670248800'
```

#### `Fund.splitRatio() → uint256`

The amount of BISHOP received by splitting one QUEEN. This ratio changes on every rebalance.

```bash
>>> fund.splitRatio()
'594418130555555555274'
```

#### `Fund.historicalSplitRatio(uint256 version) → uint256`

Getter for past split ratio of a given rebalance version.

```bash
>>> fund.historicalSplitRatio(0)
'805392577500508333333'
```

#### `Fund.fundActivityStartTime() → uint256`

Getter for the start timestamp of the current activity window of the fund.

```bash
>>> fund.fundActivityStartTime()
'1670162400'
```

#### `Fund.isFundActive(uint256 timestamp) → bool`

Check if the fund is currently active.

#### `Fund.getEquivalentTotalB() → uint256`

Getter for the equivalent amount of BISHOP supply if all QUEEN are split.

```bash
>>> fund.getEquivalentTotalB()
'85719348463971426438951'
```

#### `Fund.getEquivalentTotalQ() → uint256`

Getter for the equivalent amount of QUEEN supply if all BISHOP and ROOK are merged.

```bash
>>> fund.getEquivalentTotalQ()
'144207156642170957094'
```

#### `Fund.historicalEquivalentTotalB(uint256 day) → uint256`

Getter for the past equivalent total amount of BISHOP on a given `day`.

```bash
>>> fund.historicalEquivalentTotalB(1669903200)
'85717176424199353954085'
```

#### `Fund.historicalNavs(uint256 day) → uint256, uint256`

Getter for the past net asset values on a given `day`.

```bash
>>> fund.historicalNavs(1669903200)
navB: '1002161928302678888'
navR: '1159606682688588925'
```

#### `Fund.extrapolateNav(uint256 price) → uint256`

It estimates the current net asset values of all tranches, considering the current underlying `price`, the accrued protocol fee and interest since the previous settlement.

#### `Fund.historicalUnderlying(uint256 day) → uint256`

Getter for the past underlying amount on a given `day`.

```bash
>>> fund.historicalUnderlying(1669903200)
'144402940283113283926'
```

#### `Fund.getTotalUnderlying() → uint256`

Getter for the current total underlying amount.

```bash
>>> fund.getTotalUnderlying()
'144439536988113283926'
```

#### `Fund.getStrategyUnderlying() → uint256`

Getter for the current total underlying amount in strategy contract.

```bash
>>> fund.historicalUnderlying()
'128181515724000000000'
```

#### `Fund.getTotalDebt() → uint256`

Getter for the amount of underlying that the fund owes the primary market for redemption.

```shell
>>> fund.getTotalDebt()
'0'
```

## Handling Rebalances

#### `Fund.doRebalance(uint256 amountQ, uint256 amountB, uint256 amountR, uint256 index) → uint256, uint256, uint256`

Get the results of share amounts `amountQ`, `amountB`, `amountR` after performing the rebalance at `index`.

* Note that this function performs no bounds checking on the given index; the transformation of a non-existent rebalance will result in undefined behavior.

```bash
>>> fund.doRebalance(1000000000000000000, 1000000000000000000, 1000000000000000000, 0)
newAmountQ: '1000442549502169234'
newAmountB: '474988241234265736'
newAmountR: '474988241234265736'
```

#### `Fund.batchRebalance(uint256 amountQ, uint256 amountB, uint256 amountR, uint256 fromIndex, uint256 toIndex) → uint256, uint256, uint256`

Get the results of share amounts `amountQ`, `amountB`, `amountR` after performing the rebalances from `fromIndex` to `toIndex`.

* Note that this function performs no bounds checking on the given indices. The original amounts are returned if `fromIndex` is no less than `toIndex`. A zero vector is returned if `toIndex` is greater than the number of existing rebalances.

#### `Fund.refreshBalance(address account, uint256 targetVersion)`

Transform share balances of `account`to a given `targetVersion`.

* Note that setting `targetVersion` to zero transforms the share balances to the latest version.

#### `Fund.refreshAllowance(address owner, address spender, uint256 targetVersion)`

Transform share allowances of `spender` approved by `owner` to a given `targetVersion`.

* Note that setting `targetVersion` to zero transforms the share allowances to the latest version.

## Transferring Tranche Tokens

#### `Fund.trancheBalanceOf(uint256 tranch, address account) → uint256`

Get the balance of `tranche` for the `account`.

#### `Fund.trancheAllBalanceOf(address account) → uint256, uint256, uint256`

Get the balances of all tranches for the `account`.

#### `Fund.trancheBalanceVersion(address account) → uint256`

Get the last rebalance version for the `account`.

#### `Fund.trancheAllowance(uint256 tranch, address owner, address spender) → uint256`

Get the allowance approved to `spender` of `tranche` by the `owner`.

#### `Fund.trancheAllowanceVersion(address owner, address spender) → uint256`

Get the last rebalance version of `spender`'s allowance by the `owner`.

#### `Fund.trancheTransfer(uint256 tranche, address recipient, uint256 amount, uint256 version)`

Refresh the balances of `msg.sender` and `recipient`, then transfer `amount` of `tranche` from `msg.sender` to `recipient`. It enforces the `version` to be the current rebalance version.

#### `Fund.trancheTransferFrom(uint256 tranche, address sender, address recipient, uint256 amount, uint256 version)`

Refresh the balances of `sender` and `recipient` and the allowances of `msg.sender` approved by `sender`, then transfer `amount` of `tranche` from `sender` to `recipient`. It enforces the `version` to be the current rebalance version.

#### `Fund.trancheApprove(uint256 tranche, address spender, uint256 amount, uint256 version)`

Sets `amount` as the allowance of `spender` over `tranche`. It enforces the `version` to be the current rebalance version.
