# xWin Fund

### FundV2

#### userAvgPrice

```solidity
struct userAvgPrice {
  uint256 shares;
  uint256 avgPrice;
}
```

#### validInvestors

```solidity
mapping(address => bool) validInvestors
```

Whitelisted addresses that can use the fund if openForPublic=false

#### performanceMap

```solidity
mapping(address => struct FundV2.userAvgPrice) performanceMap
```

User average price, and share amount for performace fee calculations

#### waivedPerformanceFees

```solidity
mapping(address => bool) waivedPerformanceFees
```

Priviliged addresses with fees waived for this fund (e.g. manager/platform)

#### TargetWeight

```solidity
mapping(address => uint256) TargetWeight
```

Stores the weight of the target asset

#### targetAddr

```solidity
address[] targetAddr
```

Array containing target asset addresses

#### priceMaster

```solidity
contract IxWinPriceMaster priceMaster
```

Address of price master

#### xWinSwap

```solidity
contract IxWinSwap xWinSwap
```

Address of swap engine

#### lockingAddress

```solidity
address lockingAddress
```

Address of locked staking contract, for performance fee discounts

#### managerAddr

```solidity
address managerAddr
```

Address of manager wallet to receive management fees

#### managerRebAddr

```solidity
address managerRebAddr
```

Address of manager account, which can execute manager only functions

#### platformWallet

```solidity
address platformWallet
```

Address of platform wallet to receive platform fees

#### lastFeeCollection

```solidity
uint256 lastFeeCollection
```

Last block where fees were collected

#### nextRebalance

```solidity
uint256 nextRebalance
```

Next available block

#### pendingMFee

```solidity
uint256 pendingMFee
```

Pending shares to award to manager

#### pendingPFee

```solidity
uint256 pendingPFee
```

Pending shares to award to platform

#### managerFee

```solidity
uint256 managerFee
```

manager fee in 4 decimals, e.g 100% = 10000

#### platformFee

```solidity
uint256 platformFee
```

platform fee in 4 decimals, e.g 100% = 10000

#### smallRatio

```solidity
uint256 smallRatio
```

#### performFee

```solidity
uint256 performFee
```

platform fee in 4 decimals, e.g 100% = 10000

#### UPMultiplier

```solidity
uint256 UPMultiplier
```

Unit price multiplier

#### openForPublic

```solidity
bool openForPublic
```

#### Received

```solidity
event Received(address, uint256)
```

#### ManagerFeeUpdate

```solidity
event ManagerFeeUpdate(uint256 fromFee, uint256 toFee, uint256 txnTime)
```

#### ManagerOwnerUpdate

```solidity
event ManagerOwnerUpdate(address fromAddress, address toAddress, uint256 txnTime)
```

#### initialize

```solidity
function initialize(string _name, string _symbol, address _baseToken, address _USDAddr, address _manageraddr, address _managerRebaddr, address _platformWallet, address _lockedStaking) external
```

#### init

```solidity
function init(uint256 _managerFee, uint256 _performFee, uint256 _platformFee, bool _openForPublic, uint256 _UPMultiplier, uint256 _rebalancePeriod, uint256 _blocksPerDay, uint256 _smallRatio) external
```

#### collectFundFee

```solidity
function collectFundFee() external
```

Mints management fee to manager wallet, sets pendingMFee to 0

#### collectPlatformFee

```solidity
function collectPlatformFee() external
```

Mints platform fee to platform wallet, sets pendingPFee to 0

#### \_calcFundFee

```solidity
function _calcFundFee() internal
```

Updates pending management/platform fee

#### createTargetNames

```solidity
function createTargetNames(address[] _toAddr, uint256[] _targets) public
```

Sets target token addresses and weights for the fund

#### Rebalance

```solidity
function Rebalance(address[] _toAddr, uint256[] _targets, uint32 _slippage) public
```

Performs rebalance with new weight and reset next rebalance period

#### Rebalance

```solidity
function Rebalance(address[] _toAddr, uint256[] _targets) external
```

#### deposit

```solidity
function deposit(uint256 amount, uint32 _slippage) public returns (uint256)
```

#### deposit

```solidity
function deposit(uint256 amount) external returns (uint256)
```

Deposits baseToken into the fund, and receives shares based on the fund's unitPrice

**Parameters**

| Name   | Type    | Description                    |
| ------ | ------- | ------------------------------ |
| amount | uint256 | Amount of baseToken to deposit |

**Return Values**

| Name | Type    | Description                                 |
| ---- | ------- | ------------------------------------------- |
| \[0] | uint256 | shares Amount of shares minted to depositor |

#### \_deposit

```solidity
function _deposit(uint256 amount, uint32 _slippage) internal returns (uint256)
```

#### withdraw

```solidity
function withdraw(uint256 amount, uint32 _slippage) public returns (uint256)
```

#### withdraw

```solidity
function withdraw(uint256 amount) external returns (uint256)
```

Withdraws from the fund by burning shares, liquidating assets into baseToken and transfering to user

**Parameters**

| Name   | Type    | Description                  |
| ------ | ------- | ---------------------------- |
| amount | uint256 | Amount of shares to withdraw |

**Return Values**

| Name | Type    | Description                                          |
| ---- | ------- | ---------------------------------------------------- |
| \[0] | uint256 | amount Amount of baseTokens transferred to depositor |

#### \_withdraw

```solidity
function _withdraw(uint256 amount, uint32 _slippage) internal returns (uint256)
```

#### MoveNonIndexNameToBase

```solidity
function MoveNonIndexNameToBase(address _token, uint32 _slippage) external returns (uint256 balanceToken, uint256 swapOutput)
```

fund owner move any name back to baseToken

#### emergencyRedeem

```solidity
function emergencyRedeem(uint256 redeemUnit) external
```

get the proportional token without swapping it in emergency case

#### \_getTransferAmt

```solidity
function _getTransferAmt(address underying, uint256 redeemratio) internal view returns (struct xWinLib.transferData transData)
```

Calc return balance during redemption

#### \_getMintQty

```solidity
function _getMintQty(uint256 _unitPrice) internal view returns (uint256 mintQty)
```

Calc qty to issue during subscription

#### \_getActiveOverWeight

```solidity
function _getActiveOverWeight(address destAddr, uint256 totalvalue) internal view returns (uint256 destRebQty, uint256 destActiveWeight, bool overweight)
```

Calculates the weight difference between the current fund and target

**Parameters**

| Name       | Type    | Description      |
| ---------- | ------- | ---------------- |
| destAddr   | address | token address    |
| totalvalue | uint256 | fund vault value |

**Return Values**

| Name             | Type    | Description                                   |
| ---------------- | ------- | --------------------------------------------- |
| destRebQty       | uint256 | Amount of tokens to sell if overweight        |
| destActiveWeight | uint256 | amount of weight the token is off from target |
| overweight       | bool    | bool to indicate if token is overweight       |

#### \_rebalance

```solidity
function _rebalance(uint32 _slippage) internal
```

#### \_sellOverWeightNames

```solidity
function _sellOverWeightNames(uint32 _slippage) internal returns (struct xWinLib.UnderWeightData[] underwgts, uint256 totalunderwgt)
```

Sells overweight tokens

**Parameters**

| Name       | Type   | Description                 |
| ---------- | ------ | --------------------------- |
| \_slippage | uint32 | Slippage used for the swaps |

**Return Values**

| Name          | Type                              | Description                                        |
| ------------- | --------------------------------- | -------------------------------------------------- |
| underwgts     | struct xWinLib.UnderWeightData\[] | Returns remaining underweighted tokens, and amount |
| totalunderwgt | uint256                           | Total underweighted sum                            |

#### \_buyUnderWeightNames

```solidity
function _buyUnderWeightNames(struct xWinLib.UnderWeightData[] underweights, uint256 totalunderwgt, uint32 _slippage) internal
```

Buys Underweighted tokens

#### \_moveNonIndex

```solidity
function _moveNonIndex(address _token, uint32 _slippage) internal returns (uint256 balanceToken, uint256 swapOutput)
```

#### \_getDeleteNames

```solidity
function _getDeleteNames(address[] _toAddr) internal view returns (struct xWinLib.DeletedNames[] delNames)
```

#### \_convertTo18

```solidity
function _convertTo18(uint256 value, address token) internal view returns (uint256)
```

#### getEstimateShares

```solidity
function getEstimateShares(uint256 _amt) external view returns (uint256 mintQty)
```

Display estimate shares if deposit

#### getUnitPrice

```solidity
function getUnitPrice() external view returns (uint256)
```

The unitprice of a share of this fund in baseToken

#### \_getUnitPrice

```solidity
function _getUnitPrice(uint256 fundvalue) internal view returns (uint256)
```

#### getUnitPriceInUSD

```solidity
function getUnitPriceInUSD() external view returns (uint256)
```

The unitprice of a share of this fund, in stablecoinUSDAddr

#### getLatestPrice

```solidity
function getLatestPrice(address _targetAdd) external view returns (uint256)
```

#### getVaultValues

```solidity
function getVaultValues() external view returns (uint256)
```

Gets the total value of the tokens within the fund, value shown in baseToken

#### getVaultValuesInUSD

```solidity
function getVaultValuesInUSD() external view returns (uint256)
```

Gets the total value of the tokens within the fund, value shown in stablecoinUSDAddr

#### getTokenValues

```solidity
function getTokenValues(address tokenaddress) external view returns (uint256)
```

return token value in the vault in base currency

#### getFundTotalSupply

```solidity
function getFundTotalSupply() public view returns (uint256)
```

Actual total supply, taking into account for fees

#### \_getLatestPrice

```solidity
function _getLatestPrice(address _targetAdd) internal view returns (uint256)
```

#### \_getLatestPriceInUSD

```solidity
function _getLatestPriceInUSD(address _targetAdd) internal view returns (uint256)
```

#### \_getVaultValues

```solidity
function _getVaultValues() internal view returns (uint256)
```

#### \_getVaultValuesInUSD

```solidity
function _getVaultValuesInUSD() internal view returns (uint256)
```

#### \_getUP

```solidity
function _getUP() internal view returns (uint256)
```

#### \_getUnitPrice

```solidity
function _getUnitPrice() internal view returns (uint256)
```

#### \_getUPInUSD

```solidity
function _getUPInUSD() internal view returns (uint256)
```

#### \_getTokenValues

```solidity
function _getTokenValues(address token) internal view returns (uint256)
```

#### \_getTokenValuesInUSD

```solidity
function _getTokenValuesInUSD(address token) internal view returns (uint256)
```

#### getBalance

```solidity
function getBalance(address fromAdd) public view returns (uint256)
```

#### getTargetNamesAddress

```solidity
function getTargetNamesAddress() external view returns (address[] _targetNamesAddress)
```

#### getTargetWeightQty

```solidity
function getTargetWeightQty(address targetAdd, uint256 srcQty) internal view returns (uint256)
```

*return target amount based on weight of each token in the fund*

#### GetFundExtra

```solidity
function GetFundExtra() external view returns (uint256 managementFee, uint256 performanceFee, uint256 platFee, address mAddr, address mRebAddr, address pWallet)
```

Get All Extra the fund data needed for client

#### GetFundDataAll

```solidity
function GetFundDataAll() external view returns (contract IERC20Upgradeable baseCcy, address[] targetAddress, uint256 totalUnitB4, uint256 baseBalance, uint256 unitprice, uint256 fundvalue, uint256 unitpriceUSD, uint256 fundvalueUSD, string fundName, string symbolName)
```

Get All the fund data needed for client

#### setValidInvestor

```solidity
function setValidInvestor(address _wallet, bool _allow) external
```

#### setOpenForPublic

```solidity
function setOpenForPublic(bool _allow) external
```

#### updateOtherProperties

```solidity
function updateOtherProperties(uint256 newCycle, uint256 _ratio, uint256 _UPMultiplier) external
```

#### updateBlockPerday

```solidity
function updateBlockPerday(uint256 _blocksPerDay) external
```

*update average blocks per day value*

#### updatePlatformProperty

```solidity
function updatePlatformProperty(address _newAddr, uint256 _newFee) external
```

*update platform fee and wallet*

#### setPerformanceFee

```solidity
function setPerformanceFee(uint256 _performFee) external
```

#### updateManagerProperty

```solidity
function updateManagerProperty(address newRebManager, address newManager, uint256 newFeebps) external
```

*update manager fee and wallet*

#### updatexWinEngines

```solidity
function updatexWinEngines(address _priceMaster, address _xwinSwap) external
```

*update xwin master contract*

#### updateLockedStakingAddress

```solidity
function updateLockedStakingAddress(address _lockedStaking) external
```

#### setPerformDeposit

```solidity
function setPerformDeposit(uint256 mintShares, uint256 latestUP) internal
```

Handles performance fee logic, keeping record of deposits

**Parameters**

| Name       | Type    | Description        |
| ---------- | ------- | ------------------ |
| mintShares | uint256 | Shares minted      |
| latestUP   | uint256 | Unit price of fund |

#### setPerformWithdraw

```solidity
function setPerformWithdraw(uint256 swapOutput, uint256 _shares, address _investorAddress, address _managerAddress) internal returns (uint256)
```

Handles performance fee logic, calculating profit after swap

**Parameters**

| Name              | Type    | Description                        |
| ----------------- | ------- | ---------------------------------- |
| swapOutput        | uint256 | Amount of tokens received          |
| \_shares          | uint256 | Amount of shares burned            |
| \_investorAddress | address | User address that is withdrawing   |
| \_managerAddress  | address | Address to receive performance fee |

#### getUserAveragePrice

```solidity
function getUserAveragePrice(address _user) external view returns (uint256 shares, uint256 avgPrice)
```

Returns Users average price and shares

**Parameters**

| Name   | Type    | Description         |
| ------ | ------- | ------------------- |
| \_user | address | Address of the user |

**Return Values**

| Name     | Type    | Description                     |
| -------- | ------- | ------------------------------- |
| shares   | uint256 | Total shares minted by the user |
| avgPrice | uint256 | Average mint price              |

#### getDiscountedPerformFee

```solidity
function getDiscountedPerformFee(address _user) public view returns (uint256 newPerformanceFee)
```

Returns performance fee for user after applying discount

**Parameters**

| Name   | Type    | Description         |
| ------ | ------- | ------------------- |
| \_user | address | Address of the user |

#### addContractWaiveFee

```solidity
function addContractWaiveFee(address _contract) external
```

#### removeContractWaiveFee

```solidity
function removeContractWaiveFee(address _contract) external
```

#### receive

```solidity
receive() external payable
```

#### onlyRebManager

```solidity
modifier onlyRebManager()
```
