# uwu-factory-v1-1-0

The `uwu-factory-v1-1-0` contract serves as the central management system for Vaults and is the sole authorized caller for minting and burning tokens in the `uwu-token-v1-1-0` contract. Users can deposit STX as collateral into the contract and mint UWU tokens in return. Furthermore, users can deposit UWU into the contract and burn it by repaying debt, allowing them to reclaim their STX collateral.

## Data Storage

These structures allow the contract to maintain its state, track information, and ensure data consistency throughout the contract's lifecycle.

### last-vault-id

```
(define-data-var last-vault-id uint u0)
```

A data variable that stores the ID of the most recently opened Vault.

### opened-vault-count

```
(define-data-var opened-vault-count uint u0)
```

A data variable that keeps track of the current number of opened Vaults.

### liquidated-vault-count

```
(define-data-var liquidated-vault-count uint u0)
```

A data variable that stores the total number of Vaults that have been liquidated.

### vaults

```
(define-map vaults uint 
    {
        id: uint,
        owner: principal,
        collateral: uint,
        debt: uint,
        height: uint,
        liquidated: bool
    }
)
```

A map that stores information related to each Vault, including its ID, the owning principal, the amount of deposited collateral, the current debt, the block-height at which the Vault was opened (in Stacks blocks), and the liquidation status of the Vault.

### vault-entries

```
(define-map vault-entries principal (list 20 uint))
```

A map that maintains a record of the IDs of each of the opened Vaults owned by each principal, with a maximum limit of 20 Vaults per principal at any given time.

### last-removed-entry

```
(define-map last-removed-entry principal uint)
```

A map that stores the most recent ID removed from the `vault-entries` map for each principal.

## Public Functions

These functions are accessible by external contracts or users, enabling interaction with the contract and state modification.

### open-vault

<pre><code><strong>(define-public (open-vault (collateral uint) (debt uint)))
</strong></code></pre>

A public function that creates a new Vault for the `tx-sender` using the provided collateral and debt amounts. The collateral ratio must be at least 150%. A minimum of 25 UWU (`u25000000`) must be borrowed and a 100bps (1.00%) one-time borrow fee is taken from the debt borrowed.

| **Parameter** | **Type** | **Description**                     |
| ------------- | -------- | ----------------------------------- |
| collateral    | uint     | The amount of collateral to deposit |
| debt          | uint     | The amount of debt to borrow        |

### borrow-vault

```
(define-public (borrow-vault (id uint) (amount uint)))
```

A public function that enables the owner of a specified Vault to take on additional debt in that Vault. The `tx-sender` must be the owner of the Vault. The Vault cannot be liquidated, and the collateral ratio must be at least 150%, taking into account the newly borrowed amount. A minimum of 1 UWU (`u1000000`) must be borrowed and a 100bps (1.00%) one-time borrow fee is taken from the debt borrowed. If the Vault has zero debt, a minimum of 25 UWU (`u25000000`) must be borrowed.

| **Parameter** | **Type** | **Description**                    |
| ------------- | -------- | ---------------------------------- |
| id            | uint     | The ID of the Vault to borrow from |
| amount        | uint     | The amount of debt to borrow       |

### collateralize-vault

```
(define-public (collateralize-vault (id uint) (amount uint)))
```

A public function that allows the owner of a specified Vault to deposit additional collateral into that Vault. The `tx-sender` must be the owner of the Vault, and the Vault cannot be liquidated.

| **Parameter** | **Type** | **Description**                      |
| ------------- | -------- | ------------------------------------ |
| id            | uint     | The ID of the Vault to collateralize |
| amount        | uint     | The amount of collateral to deposit  |

### repay-vault

```
(define-public (repay-vault (id uint) (amount uint)))
```

A public function that allows the owner of a specified Vault to repay the debt of that Vault. The `tx-sender` must be the owner of the Vault, and the Vault cannot be liquidated. The amount repaid must either equal the total debt of the Vault or leave a remaining debt of at least 25 UWU (`u25000000`) in the Vault to prevent dust amounts from being left behind.

| **Parameter** | **Type** | **Description**                      |
| ------------- | -------- | ------------------------------------ |
| id            | uint     | The ID of the Vault to repay debt in |
| amount        | uint     | The amount of debt to repay          |

### withdraw-vault

```
(define-public (withdraw-vault (id uint) (amount uint)))
```

A public function that enables the owner of a specified Vault to withdraw excess collateral from that Vault. The `tx-sender` must be the owner of the Vault, the Vault cannot be liquidated, and the collateral ratio must remain at least 150% after accounting for the withdrawn amount.

| **Parameter** | **Type** | **Description**                      |
| ------------- | -------- | ------------------------------------ |
| id            | uint     | The ID of the Vault to withdraw from |
| amount        | uint     | The amount of collateral to withdraw |

### transfer-vault

```
(define-public (transfer-vault (id uint) (account principal)))
```

A public function that permits the owner of a specified Vault to transfer ownership of that Vault to a new principal. The `tx-sender` must be the owner of the Vault, the Vault cannot be liquidated, and the receiver cannot currently own more than 20 Vaults. Once transferred, the receiver gains full control of the Vault, and the original owner loses access unless the Vault is transferred back. The ID of the Vault is removed from the original owner's `vault-entries` map and added to the new owner's map.

| **Parameter** | **Type**  | **Description**                                |
| ------------- | --------- | ---------------------------------------------- |
| id            | uint      | The ID of the Vault to transfer                |
| account       | principal | The principal receiving ownership of the Vault |

### close-vault

```
(define-public (close-vault (id uint)))
```

A public function that enables the owner of a specified Vault to close that Vault. The `tx-sender` must be the owner of the Vault, and both the collateral and debt amounts in the Vault must be zero. Once closed, the Vault ID is removed from the owner's `vault-entries` map, and the information associated with the Vault is deleted from the `vaults` map.

| **Parameter** | **Type** | **Description**              |
| ------------- | -------- | ---------------------------- |
| id            | uint     | The ID of the Vault to close |

### liquidate-vault

```
(define-public (liquidate-vault (id uint)))
```

A public function that allows anyone to liquidate a specified Vault if its collateral ratio falls below 150%. The `tx-sender` does not need to be the owner of the Vault. If liquidated, the Vault is then purchasable via the `purchase-vault` public function. Following liquidation, the owner can no longer deposit collateral, borrow UWU, or execute other actions on the vault, except for closing it once the collateral and debt amounts reach zero.<br>

| **Parameter** | **Type** | **Description**                  |
| ------------- | -------- | -------------------------------- |
| id            | uint     | The ID of the Vault to liquidate |

### purchase-vault

```
(define-public (purchase-vault (id uint) (amount uint)))
```

A public function that enables anyone to repay the debt in a specified liquidated Vault in exchange for the Vault's collateral. The `tx-sender` does not need to be the owner. Users can purchase any portion of the Vault, receiving a proportionate share of the collateral. For instance, if a user repays 10% of the debt in a liquidated Vault, they would receive 10% of the Vault's collateral. The amount purchased must either equal the total debt of the Vault or leave a remaining debt of at least 25 UWU (`u25000000`) in the Vault to prevent dust amounts from being left behind.

| **Parameter** | **Type** | **Description**                      |
| ------------- | -------- | ------------------------------------ |
| id            | uint     | The ID of the Vault to purchase from |
| amount        | uint     | The amount of debt to repay          |

## Private Functions

These functions are accessible only within the contract they are defined in, providing encapsulation and preventing external access to specific functionality.

### get-collateral-ratio

```
(define-private (get-collateral-ratio (collateral uint) (debt uint)))
```

A private function that calculates the collateral ratio based on the given collateral and debt amounts.

| **Parameter** | **Type** | **Description**          |
| ------------- | -------- | ------------------------ |
| collateral    | uint     | The amount of collateral |
| debt          | uint     | The amount of debt       |

### remove-vault-entry

```
(define-private (remove-vault-entry (id uint)))
```

A private function that removes a specified ID linked to an open Vault, owned by the `tx-sender`, from the `vault-entries` map. This function does not remove the Vault from the `vaults` map.

| **Parameter** | **Type** | **Description**  |
| ------------- | -------- | ---------------- |
| id            | uint     | The ID to remove |

## Read-only Functions

These functions do not modify the contract's state and are used for querying or retrieving data. They can be called by external contracts or users but will not change the underlying state.

### get-last-vault-id

```
(define-read-only (get-last-vault-id))
```

A read-only function that returns the ID of the last opened Vault.

### get-opened-vault-count

```
(define-read-only (get-opened-vault-count))
```

A read-only function that returns the number of Vaults that are currently opened.

### get-liquidated-vault-count

```
(define-read-only (get-liquidated-vault-count))
```

A read-only function that returns the number of Vaults that have been liquidated.

### get-vault

```
(define-read-only (get-vault (id uint)))
```

A read-only function that returns the information associated with a Vault, including its owner, deposited collateral, current debt, the block-height at which the Vault was opened (in Stacks blocks), and its liquidation status.

| **Parameter** | **Type** | **Description**              |
| ------------- | -------- | ---------------------------- |
| id            | uint     | The ID of the Vault to query |

### get-vault-entries

```
(define-read-only (get-vault-entries (account principal)))
```

A read-only function that retrieves the list of IDs associated with the Vaults currently opened and owned by a specified principal.

| **Parameter** | **Type**  | **Description**        |
| ------------- | --------- | ---------------------- |
| account       | principal | The principal to query |

### get-vaults

```
(define-read-only (get-vaults (account principal)))
```

A read-only function that fetches the detailed information for each opened Vault owned by a specified principal.

| **Parameter** | **Type**  | **Description**        |
| ------------- | --------- | ---------------------- |
| account       | principal | The principal to query |

### get-can-liquidate-vault

```
(define-read-only (get-can-liquidate-vault (id uint)))
```

A read-only function that returns whether a Vault can be liquidated, along with its current collateral ratio.

| **Parameter** | **Type** | **Description**              |
| ------------- | -------- | ---------------------------- |
| id            | uint     | The ID of the Vault to query |
