# Token Vault

This is where NFTs are housed and fractional ownership is tracked. The contract is an ERC20 token which tracks ownership.

### **Contract Storage:**

```
    /// -----------------------------------
    /// -------- TOKEN INFORMATION --------
    /// -----------------------------------

    /// @notice the ERC721 token address of the vault's token
    address public token;

    /// @notice the ERC721 token ID of the vault's token
    uint256 public id;
```

```
    /// -------------------------------------
    /// -------- AUCTION INFORMATION --------
    /// -------------------------------------

    /// @notice the unix timestamp end time of the token auction
    uint256 public auctionEnd;

    /// @notice the length of auctions
    uint256 public auctionLength;

    /// @notice reservePrice * votingTokens
    uint256 public reserveTotal;

    /// @notice the current price of the token during an auction
    uint256 public livePrice;

    /// @notice the current user winning the token auction
    address payable public winning;

    enum State { inactive, live, ended, redeemed }

    State public auctionState;
```

```
    /// -----------------------------------
    /// -------- VAULT INFORMATION --------
    /// -----------------------------------

    /// @notice the governance contract which gets paid in ETH
    address public settings;

    /// @notice the address who initially deposited the NFT
    address public curator;

    /// @notice the AUM fee paid to the curator yearly. 3 decimals. ie. 100 = 10%
    uint256 public fee;

    /// @notice the last timestamp where fees were claimed
    uint256 public lastClaimed;

    /// @notice a boolean to indicate if the vault has closed
    bool public vaultClosed;

    /// @notice the number of ownership tokens voting on the reserve price at any given time
    uint256 public votingTokens;
    
    /// @notice a mapping of users to their desired token price
    mapping(address => uint256) public userPrices;
```

### **Governance Functions:**

```
function kickCurator(address _curator)
```

This function allows for governance to remove a curator who is acting maliciously in some way.

### **Curator Functions:**

```
function updateCurator(address _curator)
```

Allows the curator to update their address.

```
function updateBasePrice(uint256 _price)
```

Allows the curator to update the base price of the NFT. This will influence the max and min reserve prices.

```
function updateAuctionLength(uint256 _length)
```

Allows the curator to update the length of an auction for the NFT.

```
function updateFee(uint256 _fee)
```

Allows the curator to update their fee.

```
function claimFees()
```

Can be called by anyone but claims fees for the curator and governance.

### Pricing Functions:

```
    /// @notice a function for an end user to update their desired sale price
    /// @param _new the desired price in ETH
    function updateUserPrice(uint256 _new)
```

Public function for a user to update their desired reserve price. Updated the full reserve price as well.

```
    /// @notice an internal function used to update sender and receivers price on token transfer
    /// @param _from the ERC20 token sender
    /// @param _to the ERC20 token receiver
    /// @param _amount the ERC20 token amount
    function _beforeTokenTransfer(address _from, address _to, uint256 _amount) internal virtual override
```

This function is called on all token transfers. Its core functionality is to update the reserve price on transfer based on the new holders desired reserve prices.

### Auction Functions:

```
    /// @notice kick off an auction. Must send reservePrice in ETH
    function start() external payable
```

Start an auction by sending ETH to the smart contract. This will set a `livePrice` variable and allow for `bid()` to be called.&#x20;

```
    /// @notice an external function to bid on purchasing the vaults NFT. The msg.value is the bid amount
    function bid() external payable
```

Bid on an already live auction. Must send more ETH than the previous bid by a percentage set by governance. If the auction is within 15 minutes of ending, extend the auction by 15 minutes.

```
    /// @notice an external function to end an auction after the timer has run out
    function end() external
```

This can be called by anyone once an auction has ended to close the vault and send NFT to the winner.

```
    /// @notice an external function to burn all ERC20 tokens to receive the ERC721 token
    function redeem() external
```

Burn the total supply of ownership tokens to receive the NFT.

```
    /// @notice an external function to burn ERC20 tokens to receive ETH from ERC721 token purchase
    function cash() external
```

Burn your tokens to receive ETH based on your percentage of the total supply. Only to be called once an auction has ended.&#x20;

```
    /// @dev internal helper function to send ETH and WETH on failure
    function _sendETHOrWETH(address who, uint256 amount) internal
```

Helper function to try to send someone ETH and if that fails we force them to take WETH.
