> For the complete documentation index, see [llms.txt](https://cenit-finance-1.gitbook.io/generic-simulation-tool-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cenit-finance-1.gitbook.io/generic-simulation-tool-docs/others/formulae.md).

# Formulae

Throughout the spreadsheet template, there are multiple columns that accept formulae as input. These are used extensively for defining the model of the token mechanics.

## Formula syntax

The formula syntax accepts formulas that would be valid in Excel and outputs a single scalar, with two main differences:

* Instead of using references to cells, **use references to parameters** you have defined in the spreadsheet, or to one of the [predefined variables](broken://pages/SzCb8Kr4tFWoEan2gbjn#predefined-variables). For example, instead of referencing a value by its cell location such as `C7`, use the parameter reference you have created for it, such as `SE_transaction_fee_percent`. Note that all references are **case insensitive**.
* Do not put a "equals" sign `=` at the front of the formula. This is because the formula must be interpreted by the simulation software, not the spreadsheet itself.

### Operators

Accepted operators are:

* **Arithmetic operators:** `+` (addition), `-` (subtraction), `*` (multiplication), `/` (division), and `^` (exponentiation).&#x20;
* **Comparison operators:** `>` (greater than), `<` (lower than), `>=` (greater than or equal to), `<=` (less than or equal to), `=` (equals), and `<>` (does not equal).&#x20;

For further boolean operations, check out the next section.

### **Functions**

Available functions are:

* `ABS(x)`: returns the absolute value of x
* `MAX(arg1, arg2, ...)`: returns the largest value out of all the arguments
* `MIN(arg1, arg2, ...)`: returns the smallest value out of all the arguments
* `POW(arg1, arg2)`: returns arg1 to the power of arg2. Equivalent to `arg1^arg2`
* `INT(x)`: returns the integer part of x
* `LN(x)`: returns the natural logarith of x
* `EXP(x)`: returns the exponential of x
* `MOD(arg1, arg2)`: returns the remainder of the division of arg1 by arg2
* `SIN(x)`: returns the sine of x
* `COS(x)`: returns the cosine of x
* `TAN(x)`: returns the tangent of x
* `SQRT(x)`: returns the square root of x. Equivalent to `x^0.5`
* `AND(arg1, arg2, ...)`: returns the boolean true if all arguments are true, false otherwise
* `OR(arg1, arg2, ...)`: returns true if at least one of the arguments is true, false otherwise
* `NOT(x)`: returns the boolean opposite of x
* `RAND(low, high)`: returns a random sample in the uniform distribution between `low` and `high`
* `NORMAL(loc, scale)`: returns a random sample from the normal distribution with mean at `loc` and standard deviation `scale`

## Special syntax and utilities

We have added some special utilities to the formula syntax in order to make it specially useful for defining tokenomics models.

### Time units

There are two [Predefined Variables](broken://pages/SzCb8Kr4tFWoEan2gbjn#predefined-variables) related to time in the simulation:

* `time`: The simulated time elapsed since the beginning of the simulation
* `time_step`: The amount of time elapsed since the previous instant of the simulation

Both variables are defined in units of seconds. However, it is often useful to employ different time units in formulate. Therefore, a special syntax is available for both of these variables (and no others) by which attaching a suffix returns the value in different units. The unit suffixes available are:

* `.seconds`
* `.minutes`
* `.hours`
* `.days`
* `.months`
* `.years`

{% hint style="info" %}
Note that "months" are always approximated to be 30 days long for unit conversion purposes.
{% endhint %}

For instance, if during a particular time step in the simulation the elapsed time is 3888000 seconds, using `time.days` in a formula will result in a value of 45, `time.months` will be 1.5, and `time.years` will be 0.1233. Meanwhile, using either `time` without a suffix or `time.seconds` will result in 3888000.

### Previous value of a variable

In a formula, it is often useful to employ the value of a variable in the previous time step instead of the current time step. For example, this is often done in variables which depend on its own previous value.

In order to access this value, we have included a suffix available for any variable, either predefined or user defined: `.previous`

For example, consider a protocol where we already model how many individual node operators enter and exit during each simulation time step. We now want a variable named `VA_operators_current` to track the current amount of node operators. Using the `.previous` syntax, we can do this using a formula like:&#x20;

`VA_operators_current.previous + VA_operators_enter - VA_operators_exit`&#x20;

### Attribute syntax

[Agent](broken://pages/SzCb8Kr4tFWoEan2gbjn#agents) and [Vesting](broken://pages/mwRYaOwk9KJQEA3pNne2#vesting) entities you have defined have special attributes that track their state throughout the simulation. You can access them in order to use employ them in a formula by typing the agent or vesting entity reference followed by a dot (`.`)  and a special suffix, described below.

#### Agent attributes

* `.total_tokens`: total amount of tokens owned by the agent. This includes staked tokens and tokens provided as liquidity to the market
* `.idle_tokens`: tokens owned by the agent that are not staked nor provided as liquidity to the market
* `.staked_tokens`: tokens owned by the agent and provided as liquidity to the market
* `.liquidity_provided_tokens`: tokens owned by the agent that are provided as liquidity to the market
* `.held_tokens`: tokens owned by the agent that are not in provided as liquidity to the market (therefore, the sum of the `idle_tokens` and `staked_tokens`)
* `.locked_staked_tokens`: out of all of the staked tokens owned by the agent, the amount that is currently locked and thus unable to unstake if so desired
* `.liquidity_flow`: flow of tokens from the agent to the market liquidity pools/order books  in the current time step needed to maintain the liquidity ratio specified through the *liquidity provision* column in the [agents table](broken://pages/SzCb8Kr4tFWoEan2gbjn#agents). If negative it means it is subtracting liquidity from the market
* `.held_tokens_flow`: flow of tokens from the market to the agent in the current time step needed to maintain the number of desired idle and staked tokens, if so specified through the token holding and token staking columns in the [agents table](broken://pages/SzCb8Kr4tFWoEan2gbjn#agents)

#### Vesting entity attributes

* `.vesting_flow`: amount of tokens unlocked from the vesting supply for the agent related to this entity during the current time step
* `.vesting_sale_flow`: flow of tokens from the agent that the vesting entity is related to to the market in the current time step in order to accomplish the token sale specified through the *vesting sales percentage* and *vesting sales mean time* columns in the [vesting table](broken://pages/mwRYaOwk9KJQEA3pNne2#vesting)

{% hint style="info" %}
Please take into account that many of the agent and vesting entity attributes are calculated from the token flows you have defined that affect those agents or entities. As such, using them on your own formulae introduces new dependencies towards those flows, and could result in circular dependencies.&#x20;

If you encounter this problem, try to break up the dependencies using the previous value of the variables with the [`.previous` syntax](#previous-value-of-a-variable). To understand more about these implicit dependencies you can go to \[].
{% endhint %}

### Selector parameters case method syntax

[Selector parameters](broken://pages/mwRYaOwk9KJQEA3pNne2#selector-parameters) are special parameters that take one out of a list of text options. In order to use them within a formula, we use a special syntax called the "case" method, where attach `.case(...)` to the selector parameter reference in the formula, and within the parentheses we specify which value to result in for which selected option separated by commas.

Let's consider a selector parameter named `SE_example`, with three possible values "Option 1", "Option 2", and "Option 3". When "Option 1" is selected, we want the our formula to result in the value of a variable we have previously defined, let's call it `VA_option_1_value`, and so on for the other options. Then our formula with the case method syntax would be:

`SE_example.case("Option 1": VA_option_1_value, "Option 2": VA_option_2_value, "Option 3": VA_option_3_value)`

It is important to make sure that there is a value defined for each possible selected option, or the formula will fail when we select an undefined option.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://cenit-finance-1.gitbook.io/generic-simulation-tool-docs/others/formulae.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
