# Vesting

This module was highly inspired by the [Chain4Energy cfevesting module](https://github.com/chain4energy/c4e-chain/tree/master/x/cfevesting)

## Abstract

The `vesting` module provides functionality for creating and managing vesting accounts within the blockchain. Vesting accounts are special accounts that release tokens over a specified period, ensuring a controlled distribution of tokens. This module allows token holders to create new vesting accounts, split existing vesting accounts, and manage the vesting process through a set of defined messages and events. The `MsgCreateVestingAccount` message allows any token holder to create a new continuous vesting account and transfer tokens to it. The `MsgSplitVestingAccount` message enables existing vesting accounts to split their locked tokens into a new vesting account, preserving the total number of tokens, vesting times, and token release speed.

## Contents

1. [**Messages**](#messages)
2. [**Events**](#events)

## Messages

### Create Vesting Account

Creates a new continuous vesting account and sends token from the creator account.

`MsgCreateVestingAccount` can be submitted by any token holder via a `MsgCreateVestingAccount` transaction.

```{.go}
type MsgCreateVestingAccount struct {
	FromAddress string
	ToAddress   string
	Amount      sdk.Coins
	StartTime   int64
	EndTime     int64
}
```

**Params:**

| Param       | Description                            |
| ----------- | -------------------------------------- |
| FromAddress | Vesting pool owner address             |
| ToAddress   | New continuous vesting account address |
| Amount      | Amount to lock in vesting account      |
| StartTime   | Vesting start time - unix              |
| EndTime     | Vesting end time - unix                |

**State modifications:**

* Validates if `FromAddress` has enough tokens.
* Creates a new continuous vesting account with address equal to ToAddress and time params according to provided data
* Sends tokens from `FromAddress` account to `ToAddress`

### Split vesting accounts

Split tokens that are locked in vesting to a new vesting account. Total number of tokens in vesting, vesting times and token release speed are preserved. This mechanism can also be called as a "vesting cession".

The `MsgSplitVestingAccount` can be submitted by any vesting account via a `MsgSplitVestingAccount` transaction.

```{.go}
type MsgSplitVestingAccount struct {
	FromAddress string
	ToAddress   string
	Amount      sdk.Coins
	StartTime   int64
	EndTime     int64
}
```

**Params:**

| Param       | Description                            |
| ----------- | -------------------------------------- |
| FromAddress | Vesting pool owner address             |
| ToAddress   | New continuous vesting account address |
| Amount      | Amount of locked vesting to split      |
| StartTime   | Vesting start time - unix              |
| EndTime     | Vesting end time - unix                |

**State modifications:**

* Validates if `FromAddress` has enough locked tokens in the vesting
* Validates if the `start time` of the new vesting account is after the start time of the original vesting account
* Validates if the `end time` of the new vesting account is after the end time of the original vesting account
* Creates new `continuous vesting account` with address equal to `ToAddress` and time parameters set to:
  * `start time` is set to the provided start time
  * `end time` is set to the provided end time
* Sends locked vesting from FromAddress account to ToAddress

### Client

The `x/vesting` module provides CLI commands to interact with it:

* `create-vesting-account [to-address] [amount] [start-time] [end-time]`
* `split-vesting-account [to-address] [amount] [start-time] [end-time]`

Users must provide:

* Valid `to-address`.
* `amount` of coins (e.g. `1000uempe`).
* `start-time` and `end-time` as UNIX timestamps.

Example:

```shell
emped tx vesting create-vesting-account empe1xyz... 1000uempe 1672531200 1704067200 --from mykey
```

This creates a vesting account starting at UNIX time `1672531200` and ending at `1704067200`.

### Events

#### MsgCreateVestingAccount

| Type                   | Attribute Key | Attribute Value                                        |
| ---------------------- | ------------- | ------------------------------------------------------ |
| EventNewVestingAccount | address       | {new\_vesting\_account\_address}                       |
| message                | action        | /chain4energy.c4echain.vesting.MsgCreateVestingAccount |
| message                | sender        | {sender\_address}                                      |
| transfer               | recipient     | {module\_account}                                      |
| transfer               | sender        | {creator}                                              |
| transfer               | amount        | {amount}                                               |

#### MsgSplitVestingAccount

| Type                   | Attribute Key | Attribute Value                                       |
| ---------------------- | ------------- | ----------------------------------------------------- |
| EventVestingSplit      | source        | {from\_account\_address}                              |
| EventVestingSplit      | destination   | {to\_account\_address}                                |
| EventNewVestingAccount | address       | {new\_vesting\_account\_address}                      |
| message                | action        | /chain4energy.c4echain.vesting.MsgSplitVestingAccount |
| message                | sender        | {sender\_address}                                     |
| transfer               | recipient     | {module\_account}                                     |
| transfer               | sender        | {creator}                                             |
| transfer               | amount        | {amount}                                              |
