# Cron

### Intro

Cron will be will determine the beginning or the end of a competition, and provide the current number of the competition. Its major purpose is to enable the generation of clock signals specified in natural language, rather than time intervals, to manage different bounty pools.This will enable to set Weekly, or Monthly competitions, always driven by the Gregorian calendar.&#x20;

The Smart Contracts can be found [here](https://github.com/helena-network/cron), and below it is explained the basic behaviour to be used in other applications.

### Interface

A common interface (`IPeriod.sol`) is shared by every Smart Contract, where the following functions are implemented:

| Function                                     | Description                                                                 |
| -------------------------------------------- | --------------------------------------------------------------------------- |
| `getLength() public view  returns (uint256)` | Returns the number of units per period                                      |
| `unit() public view returns (string)`        | Returns a string,  specifying the type of  unit  used (eg: seconds, blocks) |
| `height() public view returns (uint256)`     | Returns the current  epoch (number of periods at the current timestamp)     |
| `heightOf(uint _timestamp)`                  | Returns the height of a given timestamp                                     |

### Usage

Implementing an internal clock compliant with `IPeriod` can be done in an easy way,  by deploying an `IPeriod` contract and then linking it to your Smart Contract.&#x20;

The following steps are required:

#### 1. Make your contract periodic

In order to enable granularity and capability to be shared among different Smart Contracts, every period (referenced in blocks, seconds or date format) is defined on a different Smart Contract instance. To include an internal clock into your Smart Contract instance, you will need to include an `IPeriod` instance into  your solidity code:

```
contract PeriodicToken {

IPeriod public period;
...

    function setPeriod(address _period) public {
        period =  _period;
    } 
 }
```

#### 2. Deploy your personalised period

You will need now to deploy new periodic contract, compliant with the `IPeriod` interface. Depending on your use case, you will need a different period instance. Today, the following types of period implementations are provided  in the [Cron](https://github.com/Frontier-project/cron) repo:&#x20;

* [**Blocks**](https://github.com/Frontier-project/cron/tree/develop/contracts/blocks): A periodic Smart Contract, where a provided by constructor length  (T) specified. Thus, every T blocks,  height is incremented.
* [**Monthly**](https://github.com/Frontier-project/cron/blob/develop/contracts/calendar/Monthly.sol): Increments `height()` every month  (e.g January, February), since the deployment  of the periodic Smart Contract
* [**Daily**](https://github.com/Frontier-project/cron/blob/develop/contracts/calendar/Daily.sol): Increments `height()` every day (eg Monday, Tuesday), since the deployment  of the periodic Smart Contract
* [**Yearly**](https://github.com/Frontier-project/cron/blob/develop/contracts/calendar/Yearly.sol): Increments `height()` every year (e.g 2018, 2019), since the deployment  of the periodic Smart Contract

#### &#x20;3. Link your contract with the new period

Now  that you have your periodic contract deployed, you can lazily assign it to your Smart Contract. In case you're using truffle migrations, this could be done as follows:

```
module.exports = (deployer) => {
  deployer.then(async () => {
      const PeriodInstance = await PeriodContract.deployed()
      await PeriodicStatesContract.setPeriod(PeriodInstance.address)
  })
}
```

#### 4. Map your variables to the period height

Now, your can create periodic states from your initially deployed contract, by  just mapping every variable  to the height of  the  periodic contract, using `period.height().`

```
contract PeriodicToken{

mapping (uint256 => uint256) private _totalSupply;
IPeriod public period;
...
  
    function totalSupply() public view returns (uint256) {
        return _totalSupply[period.height()];
    }
    
    function setPeriod(address _period) public {
        period =  _period;
    } 
 }
```
