# The Euler Model

## Introduction

*We explain the Euler model using the Ethervista LP pool as an example, but the model can be applied to any contract that implements staking or locking of assets and distributes ETH rewards based on the user's share of those assets*

The Ethervista pair smart contract maintains a sequence of ascending numbers known as Euler amounts. These values are updated each time native ETH is transferred to the pair contract. Each Euler amount is determined by adding the previous Euler amount to the ratio of the fee to the current total supply of liquidity provider tokens (LP). **The initial Euler amount is set to zero**.

Mathematically, this update can be represented as:

$$
\text{Euler}*n = \text{Euler}*\text{n-1} + \frac{\text{fee}}{\text{LP supply}}
$$

With the corresponding sequence of rising numbers:

$$
{\text{ Euler}\_1, \text{ Euler}\_2, \text{ Euler}\_3, \text{ Euler}\_4 \ldots \text{ Euler}\_n }
$$

This sequence is particularly of interest to liquidity providers. Each provider is represented by a struct which stores the LP holdings of each user and a variable called `euler0` which is suggestively named after the Euler amounts in our sequence.

```solidity
struct Provider {
    uint256 lp;
    uint256 euler0;
};
```

This `uint256` number represents the latest Euler amount in our sequence at the time the user adds liquidity, in which case we would have

$$
\text{ euler0} = \text{ Euler}\_n
$$

Suppose the user decides to claim rewards a thousand swaps later. In that moment, the latest Euler amount is

$$
\text{Euler}\_\text{n+1000}
$$

The exact amount of rewards that this provider accumulated during these thousand swaps is:

$$
\text{Reward} = \text{lp} \* (\text{Euler}\_\text{n+1000}-\text{euler0})
$$

This approach operates under the assumption that the LP balance remains constant throughout the period. Therefore, whenever a provider takes any action, such as adding/removing/transferring liquidity, the variable `euler0` will be refreshed to reflect the latest Euler amount in our sequence. This measure prevents a liquidity provider from manipulating their own share of rewards.

As such, it is advisable for a liquidity provider to always claim rewards before adjusting their LP balance.&#x20;

**The Ethervista DEX uses the Euler model for:**&#x20;

* Rewarding l**iquidity providers**
* **Hardstaking**: Users can stake their tokens and receive rewards paid in ETH from the protocol fees every transaction&#x20;
* **Hardlocking**: Creators/users can lock their LP tokens and still benefit from rewards, something which was not possible in other AMM standards

## Implementing the Euler model

Three key components are needed to implement the Euler model in a smart contract

* An `updateStaker` function which update the user baseline **Euler0** when there is a balance change (i.e a user stakes/un-stakes/transfers) or a reward claim
* A `updateEuler` function which updates the Euler-array when ETH is received by the smart contract
* A **payable function** which calls updateEuler when receiving ETH
* A `viewShare` function which returns the reward share of each user&#x20;

```solidity
struct Staker {
    uint256 amountStaked;
    uint256 euler0;
}

uint256[] public euler; 
mapping(address => Staker) public stakers;

function updateEuler(uint256 Fee) internal { 
    if (euler.length == 0){
        euler.push((Fee*bigNumber)/totalSupply);
    }else{
        euler.push(euler[euler.length - 1] + (Fee*bigNumber)/totalSupply); 
    }
}

//alternatively can be the receive() function if ETH is sent directly
//to this contract
function contributeETH() external payable nonReentrant {
    updateEuler(msg.value);
}

function updateStaker(address user) external  { 
    if (euler.length == 0){
        stakers[user] = Staker(balanceOf[user], 0); 
    }else{
        stakers[user] = Staker(balanceOf[user], euler[euler.length - 1]);
    }
}

//+ stake/unstake/claim functions

function viewShare() public view returns (uint256 share) {
    if (euler.length == 0){
        return 0;
    }else{
        return stakers[msg.sender].amountStaked * (euler[euler.length - 1] - stakers[msg.sender].euler0)/bigNumber;
    }
}
```


---

# Agent Instructions: 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:

```
GET https://docs.ethervista.app/the-euler-model.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
