# The Formulas

<figure><img src="/files/BEv5VUNPHUMZ1bRyWnjI" alt=""><figcaption></figcaption></figure>

### Explanation:

The staking system will provide greater rewards for those that stake longer and continue to participate in THE Ecosystem. When pairing with one of the DAO NFTs you will incur additional bonuses in the staking platform.

<mark style="color:orange;">**No NFT staking:**</mark> 0.41% max of 5M voting power

<mark style="color:orange;">**Bronze NFT:**</mark> 0.82% max of 10M voting power

<mark style="color:orange;">**Silver NFT:**</mark> 1.23% max of 20M voting power

<mark style="color:orange;">**Gold NFT:**</mark> 1.64% max of 30M voting power

<mark style="color:orange;">**Diamond NFT:**</mark> 2.47% max of 50M voting power

### Weighted voting power calculation

```solidity
uint256 userWeightedAmount = 0;
uint256 multiplier = getMultiplier(user.startedAt, block.timestamp);
uint256 totalMultiplier = 10000 +
(multiplier * (pointsPerDay + user.boostPointsBP)) /
ONE_DAY;

return userWeightedAmount;
```

### Staking formula with and without NFT

```solidity
function snapshotORGVotingPower(address _user)
        public
        view
        returns (uint256)
    {
        UserInfo storage user = userInfo[0][_user];

        uint256 weightedVotingPower = getVotingPower(0, _user);
        uint256 theBalance = The.balanceOf(_user);

        uint256 total = weightedVotingPower + theBalance;

        if(_user != vb){
            if(user.boostPointsBP == 0 ){ //no nft
                return total > 5000000 * 1e18 ? 5000000 * 1e18 : total;
            } else if(user.boostPointsBP == 41){ //bronze
                return total > 10000000 * 1e18 ? 10000000 * 1e18 : total;
            } else if(user.boostPointsBP == 82){ //silver
                return total > 20000000 * 1e18 ? 20000000 * 1e18 : total;
            } else if(user.boostPointsBP == 123){ //gold
                return total > 30000000 * 1e18 ? 30000000 * 1e18 : total;
            } else if(user.boostPointsBP == 206){ //diamond
                return total > 50000000 * 1e18 ? 50000000 * 1e18 : total;
            }
        } else { //if user is vitalik 
            return total > 200000000 * 1e18 ? 200000000 * 1e18 : total;
        }

        return 0;
    }
```

### Penalty when un-staking

```solidity
uint256 userVotingPower = getVotingPower(_pid, sender);
                uint256 totalMultiplier = ((userVotingPower + _amount) * 10000) /
                    (user.amount + _amount);

                uint256 multiplier = (ONE_DAY * (totalMultiplier - 10000)) /
                    (pointsPerDay + user.boostPointsBP);

                user.startedAt = block.timestamp - multiplier;
```

### Penalty when un-staking (explained)

```solidity
uint256 multiplier = getMultiplier(user.startedAt, block.timestamp);

-- first we calculate the time difference between staking deposit and current time

uint256 totalMultiplier = 10000 +
        (multiplier * (pointsPerDay + user.boostPointsBP)) /
        ONE_DAY;

-- we use 10000 denominator
-- 10000 + means that staker should always start with 1x rewards
-- we add time difference * (0.41 (pointsperday) + nftboost) and divide that with number of seconds in a day


userWeightedAmount = (user.amount * totalMultiplier) / 10000;
-- final calculation of user weighted stake
```

### Formula when adding tokens to an existing stake

```solidity
if (user.amount > 0) {
    uint256 userVotingPower = getVotingPower(_pid, sender);
    uint256 totalMultiplier = ((userVotingPower + _amount) * 10000) /
    (user.amount + _amount);

    uint256 multiplier = (ONE_DAY * (totalMultiplier - 10000)) /
    (pointsPerDay + user.boostPointsBP);

    user.startedAt = block.timestamp - multiplier;
}
```

### Formula when adding tokens to an existing stake (explained)

```solidity
uint256 userVotingPower = getVotingPower(_pid, sender);
-- we get current voting power, formula is described in first example

uint256 totalMultiplier = ((userVotingPower + _amount) * 10000) /
(user.amount + _amount);
-- then we reverse calculate totalMultiplier
    userVotingPower from above + _amount which is new amount user is trying to deposit * DENOMINATOR
    divided by staked amount (non-weighted) + new amount.
    totalMultiplier in this case means what would multiplier be if user initially staked user.amount + _amount

uint256 multiplier = (ONE_DAY * (totalMultiplier - 10000)) /
                (pointsPerDay + user.boostPointsBP);
-- in the formula above we calculate what would that be in the seconds

user.startedAt = block.timestamp - multiplier;

-- and finally we subtract those seconds from current timestamp
```


---

# 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://the-protocol-erc.gitbook.io/the-whitepaper/the-staking/the-formulas.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.
