### Setting up a vault

To set up a vault we need to determine some parameters such as the fixed rate APR in the vault, the length of the contract in days, the base asset, the protocol fees and a function that generates the variable yield to be simulated. Here, we will bundle all of them into a single object `params`. With the params set, we can set up a vault like this:

```typescript
import { Dashi, setupUser } from 'dashi'

const params = {
    vault: {
        baseAsset: 'x',
        fixedRateAPR: 0.122,
        termInDays: 90,
        fees: {
            protocol: 0.125
        },
    }
};


const vault = new Dashi(
    params.vault.fixedRateAPR, 
    params.vault.termInDays, 
    params.vault.baseAsset,
    params.vault.fees
);

```

### Setting up users

To set up a user, Dashi has a helper function called `setupUser` which takes two parameters: the number of units of the asset and the name of the asset. To set up Alice with 700k `x`, Bob with 300k `x`, Charlie with 20k `x` and Denise with 10k `x`:

```typescript
const alice = setupUser(700E3, 'x');
const bob = setupUser(300E3, 'x');
const charlie = setupUser(20E3, 'x');
const denise = setupUser(10E3, 'x');
```

### Deploying positions in the vault

To deploy a position in the vault, each user must pick a side `fixed` or `variable`. Let's say that Alice and Bob will pick the fixed side and Charlie and Denise will pick the variable side. To deploy their capital to the vault we do:

```typescript
vault.addFixed(alice, 700E3, params.vault.baseAsset);
vault.addFixed(bob, 300E3, params.vault.baseAsset);
vault.addVariable(charlie, 20E3, params.vault.baseAsset);
vault.addVariable(denise, 10E3, params.vault.baseAsset);
```

### Locking the vault

Now we need to try to lock the vault:

```typescript
vault.lockVault()
```

This function will check if the sides of the contract have been filled with enough capital and lock the positions that remain locked. It will also trigger the payout for the fixed side and unlock these payments. Both Alice and Bob can withdraw their fixed payment but not their principal.

```typescript
vault.getFunds(alice)
console.log(alice.portfolio.report())
/*
[
  { asset: 'x', value: 21000 },
  {
    asset: 'dashi-fixed-e72b7eae-0c83-4775-ae64-7fc8c80f53e2',
    value: 1
  }
]
*/
vault.getFunds(bob)
console.log(bob.portfolio.report())
/*
[
  { asset: 'x', value: 9000 },
  {
    asset: 'dashi-fixed-0f125fc3-7718-49a2-ae2d-23818f481fa1',
    value: 1
  }
]
*/
```

notice that Alice and Bob have their funds and an NFT from a fixed position that will allow them to withdraw their principal later.

### Evolving the vault

Let's suppose that the underlying instrument generated 8k over the first 30 days. To simulate that, we can use the function `evolve()`. The first argument of this function is how many days of the contract it will evolve and the optional second argument is the annualized rate to be considered in that period.

To calculate the APR rate for the underlying instrument to return 8k we do `8 / 1000 / 30 * 365` and pass as the second argument of the `evolve()` function

```typescript
vault.evolve(30, 8 / 1000 / 30 * 365);
```

### Partial withdraws

Although this feature is not available in the current version of the SFIV, Dashi users on the variable side should be able to withdraw their funds at any time. If Charlie decides to withdraw we have:

```typescript
vault.getFunds(charlie)
console.log(charlie.portfolio.report())
/*
[
  { asset: 'x', value: 4666.666666666666 },
  {
    asset: 'dashi-variable-92c8cb9c-9fd4-427b-a830-7b3054d4e78e',
    value: 1
  }
]
*/
console.log(denise.portfolio.report())
/*
[
  { asset: 'x', value: 0 },
  {
    asset: 'dashi-variable-fe29c59d-a9c7-4fc8-8fc0-a4e9cee6b9cf',
    value: 1
  }
]
*/
```

Charlie managed to withdraw his capital before the end of the contract, while Denise preferred the end of it. Thus Charlie now has 4.6k and Denise only has the NFT.

Now, let's suppose that after another 20 days (50 days total), the underlying instrument added another 7k in yield to a total of 15k and now only Denise wants to withdraw.

```typescript
vault.evolve(20, 5 / 1000 / 20 * 365);
vault.getFunds(denise)
console.log(denise.portfolio.report())
/*
[
  { asset: 'x', value: 6708.333333333333 },
  {
    asset: 'dashi-variable-29f023ec-ed8f-42b1-b336-db885b8bad46',
    value: 1
  }
]
*/
```

because it is Denise's first withdrawal, she receives her entire portion since the beginning of the contract.

Now, passing another 10 days (60 days total), the underlying instrument generated another 3k and Charlie decides to withdraw:

```typescript
vault.evolve(10, 3 / 1000 / 10 * 365);
vault.getFunds(charlie)
console.log(charlie.portfolio.report())
/*
[
  { asset: 'x', value: 10500 },
  {
    asset: 'dashi-variable-7454f02f-b2c1-4d84-9da1-78d9af2d54d0',
    value: 1
  }
]
*/
```

and now Charlie has 10.5k in his possession.

Finally, let's suppose that at the end of the contract, the underlying instrument generated a total of 35k `x`, which is 17k more during the last 30 days of the contract. We can evolve the vault as:

```typescript
vault.evolve(30, 17 / 1000 / 30 * 365);
```

And all the users can withdraw their funds:

```typescript
vault.getFunds(alice)
console.log(alice.portfolio.report())
/* [
  { asset: 'x', value: 721000 },
  {
    asset: 'dashi-fixed-e986f4a8-59d5-4fe1-83c1-81a1264bf83a',
    value: 1
  }
] */
vault.getFunds(bob)
console.log(bob.portfolaio.report())
/* [
  { asset: 'x', value: 309000 },
  {
    asset: 'dashi-fixed-13fe8e51-06ea-4564-bdd4-aaf4ec12e09b',
    value: 1
  }
] */
vault.getFunds(charlie)
console.log(charlie.portfolio.report())
/* [
  { asset: 'x', value: 20416.666666666664 },
  {
    asset: 'dashi-variable-76e45fe6-6e8f-4c25-bec6-13df9d159799',
    value: 1
  }
] */
vault.getFunds(denise)
console.log(denise.portfolio.report())
/* [
  { asset: 'x', value: 10208.333333333332 },
  {
    asset: 'dashi-variable-0b39ef26-2b4a-422e-a9d6-3baaea83af26',
    value: 1
  }
] */
```

### The simulation

Putting together, this is the `app.js` file that generates these results:

```typescript
import { Dashi, setupUser } from 'dashi'

const params = {
    vault: {
        baseAsset: 'x',
        fixedRateAPR: 0.12166666666666666,
        termInDays: 90,
        fees: {
            protocol: 0.125
        },
    }
};

const vault = new Dashi(
    params.vault.fixedRateAPR,
    params.vault.termInDays,
    params.vault.baseAsset,
    params.vault.fees
);

const alice = setupUser(700E3, 'x');
const bob = setupUser(300E3, 'x');
const charlie = setupUser(20E3, 'x');
const denise = setupUser(10E3, 'x');

vault.addFixed(alice, 700E3, params.vault.baseAsset);
vault.addFixed(bob, 300E3, params.vault.baseAsset);
vault.addVariable(charlie, 20E3, params.vault.baseAsset);
vault.addVariable(denise, 10E3, params.vault.baseAsset);

vault.lockVault()

vault.getFunds(alice)
console.log(alice.portfolio.report())
vault.getFunds(bob)
console.log(bob.portfolio.report())

vault.evolve(30, 0.09733333333333334);
console.log(vault.status().floating)

vault.getFunds(charlie)
console.log(charlie.portfolio.report())
console.log(denise.portfolio.report())

vault.evolve(20, 7 / 1000 / 20 * 365);
vault.getFunds(denise)
console.log(denise.portfolio.report())

vault.evolve(10, 3 / 1000 / 10 * 365);
vault.getFunds(charlie)
console.log(charlie.portfolio.report())

vault.evolve(30, 17 / 1000 / 30 * 365);

console.log('End of the contract')
vault.getFunds(alice)
console.log(alice.portfolio.report())
vault.getFunds(bob)
console.log(bob.portfolio.report())
vault.getFunds(charlie)
console.log(charlie.portfolio.report())
vault.getFunds(denise)
console.log(denise.portfolio.report())
```