Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mana calculator #1158

Merged
merged 45 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e823ede
Add Delegator Component
Dr-Electron Aug 20, 2023
b38912e
Add Validator Component
Dr-Electron Aug 27, 2023
55edaa6
Add accumulation tab
Dr-Electron Aug 27, 2023
9888b67
Fix react-select styling
Dr-Electron Sep 3, 2023
eacf444
Hide validators behind advanced settings
Dr-Electron Sep 3, 2023
2c9123b
Add 'Add' buttons
Dr-Electron Sep 3, 2023
d17806c
Basic css touch ups
lucas-tortora Sep 4, 2023
1fa3160
restyle validator boxes
lucas-tortora Oct 13, 2023
8ecf3aa
Remove 'epoch' in TPS tab
Dr-Electron Oct 15, 2023
afae7a1
Move the advanced setting to a less obvious place
Dr-Electron Oct 15, 2023
3a4be25
Hide some of the validator’s settings
Dr-Electron Oct 15, 2023
b3d5d4d
Make needed inputs numbers
Dr-Electron Oct 15, 2023
302bad6
Swap 'passiveRewards' and 'manaGeneratedPerEpoch'
Dr-Electron Oct 16, 2023
eaa86c2
Don't use micro
Dr-Electron Oct 16, 2023
5817c2d
add mana calc text
oliviasaa Oct 20, 2023
05b8eef
Merge branch 'mana-calculator' of https://github.com/iotaledger/iota-…
oliviasaa Oct 20, 2023
6fa6a7a
Update src/components/ManaCalculator/utils.ts
Dr-Electron Oct 24, 2023
5c6832c
Update mana-calculator.md (#1283)
DafPhil Oct 26, 2023
ef790cf
Update mana-calculator.md (#1284)
DafPhil Oct 26, 2023
7b7513a
Merge branch 'main' into mana-calculator
Dr-Electron Oct 26, 2023
f8d39eb
feat: Flexible network configuration for Mana calculator (#1289)
marc2332 Oct 27, 2023
1652d1d
Format
Dr-Electron Oct 27, 2023
c6ff575
Lint
Dr-Electron Oct 28, 2023
c36d196
Merge branch 'main' into mana-calculator
Dr-Electron Nov 2, 2023
b47899d
Fix epochDiff
Dr-Electron Nov 2, 2023
a7e46e5
Merge remote-tracking branch 'origin/main' into mana-calculator
begonaalvarezd Nov 3, 2023
b13c9b0
feat: Improved user flow of Mana Calculator (#1314)
marc2332 Nov 5, 2023
493e754
chore: Refactor mana calculator (#1315)
marc2332 Nov 6, 2023
09e1db9
feat: Add user total holding input in Mana Calculator (#1316)
marc2332 Nov 6, 2023
67c2d3b
feat: Mana accumulation graph in Mana Calculator (#1317)
marc2332 Nov 6, 2023
b0f1dc7
feat: Block issuance rate graph in Mana Calculator (#1318)
marc2332 Nov 6, 2023
2003952
Merge branch 'main' into mana-calculator
Dr-Electron Nov 6, 2023
f2182f2
Add time to issue default block (#1323)
Dr-Electron Nov 7, 2023
36f07e6
Format
Dr-Electron Nov 7, 2023
daed1df
fix: remove redundant *1000 in humanized duration
begonaalvarezd Nov 7, 2023
e73ce44
feat: UI polish (#1321)
marc2332 Nov 8, 2023
b7d163f
feat: Mana calculator units (#1324)
marc2332 Nov 8, 2023
9e1f314
Use BPS instead of TPS (#1327)
Dr-Electron Nov 8, 2023
7798427
feat: Final values for networks in Mana Calculator (#1325)
marc2332 Nov 8, 2023
c7e7722
Format
Dr-Electron Nov 8, 2023
5cca6c0
Remove Mana calc from Mana page
Dr-Electron Nov 8, 2023
5adcb2a
Remove unused var
Dr-Electron Nov 8, 2023
4d921bf
Fix linting errors
jlvandenhout Nov 8, 2023
413a470
Apply suggestions from code review
Dr-Electron Nov 8, 2023
5a147f6
Fix typo
Dr-Electron Nov 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions docs/learn/protocols/iota2.0/core-concepts/mana-calculator.md
Dr-Electron marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import ManaCalculator from '@site/src/components/ManaCalculator';

# Mana Calculator

Mana is a scarce resource used to access the IOTA ledger and update its state through block creation. It is a spendable asset tracked in the ledger state, powering smart contracts, DeFi applications, block creation, and various other services. Our incentives scheme allows you to stake or delegate mana to receive Mana rewards, in addition to the Mana generation your IOTA holdings grant you without having to participate in any consensus-related activity.

In this article, we introduce the Mana Calculator: a tool to help you make decisions about the type of participation that will suit you the most, to help you predict the Mana generation you’ll be granted, and to decide the number of IOTA tokens you should hold to have a particular desired level of access guaranteed in the future.

## How to use the Calculator: Step-by-step instructions

- **Choose the network you want to estimate the Mana Generation:** this calculator works for both Shimmer and the future IOTA 2.0 network. Those two networks will have their own type of Mana (IOTA Mana and Shimmer Mana), with their own parameters and, consequently, their own behavior. Be sure you select the correct scenario you want to simulate!

- **Choose your role:** are you going to delegate to a validator, be a validator yourself or just hold tokens? To be a validator, you must run a node and lock your tokens while you are performing such validation services, but this will give you higher rewards. If you wish to delegate to a validator, your tokens will not be locked and you won’t need to run a node, but this will give you less rewards than validating. Finally, just holding tokens grants you a certain Mana generation, but it will be less than the validating or delegating.

- **Input the number of tokens you own:** no matter which network and role you choose, your Mana generation will depend on how many available tokens you have. Pay attention to the units! The input should be done in IOTA or Shimmer (not microIota or Glow).

Now you are mostly done! With the inputs above, you can already estimate how much Mana you’ll be granted per epoch. But what does it mean in tps? How many blocks per second this Mana grants you? The answer to this question depends on the size of your block and the network congestion levels. However, we can use a default block size, which will be enough for most applications, and assume certain levels of congestion. This takes us to the very last step to be taken in this calculator:

- **Choose a congestion level:** given a certain Mana generation per epoch, this can be translated into a number of blocks issued per seconds that depends on the congestion level. Choose one of the given congestion levels (low, stable, or extreme) to estimate how many blocks per second your tokens and participation grants you! This metric is also showed in a alternative way: time until block issuance, which tells you in which periodicity you’ll be able to issue a block.

<ManaCalculator/>


## Advanced settings

The steps shown above are enough to roughly estimate your Mana generation and granted tps; however, if you wish, you can play with the advanced settings to have more precise results.

- **Change the state of the system:** the default settings assume a certain level of participation in the consensus (i.e., locked stake, delegated stake and performance factor of validators). Those settings can be changed unter the “Advanced settings - State of the System” tab. You can also add or delete validators and change their fixed costs.

- If you choose to delegate:
- **Change the validator you delegate to:** by the default settings, you'll be delegating to Validator 1 (which is pool that, technically speaking, is under the "equilibrium state", see the WP for more details). However, you can change this setting and know your rewards if you participate in other pools, with different share of delegated to locked stake, and different performance factors.

- If you choose to validate:
- **Change the amount of stake is delegated to you:** by the default settings of the calculator, you'll be assigned a certain share of the delegated stake automatically when you start validating. However, you can change this setting and know your rewards if you manage to atract more (or less) delegated stake than the default setting.
- **Change your performance factor:** by the default settings of the calculator, your performance factor is 0.95. However, you can change this to simulate larger or smaller shares of online time.
- **Change your fixed costs:** by the default settings of the calculator, your fixed costs are zero. This setting can be changed so you spare part of the pool rowards just for yourself. However, notice that the fixed cost is a public parameter, that you define during registration. This means that the delegator know how you set this value and might consider it when choosing a validator to delegate. Furthermore, is you set this value too high, you'll be punished and won't get rewards at all.

- **Simulate your Mana accumulation**: the default setting of the calculator assumes a stationary regime and calculates the block creation rate you guarantee depending on your stake and level of participation. However, specially in the early stages of the network you might want to save your mana to sell later. This tab simulates how much Mana you will accumulate in a certain time period. For that (besides the other already defined inputs), you just need to choose a initial and final epochs, and the tool will plot a graph of your accumulation during that period. In the same graph, you can also have an idea of how many blocks can be issued with this accumulated amount of Mana, for the different congestion levels (already defined in the non-advanced settings).


6 changes: 6 additions & 0 deletions docs/learn/protocols/iota2.0/core-concepts/mana.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import ManaCalculator from '@site/src/components/ManaCalculator';

# Tokenomics: Mana, Accounts, Staking and Delegation

Mana is a scarce resource used to access the IOTA ledger and update its state through block creation. It is a spendable asset tracked in the ledger state, powering smart contracts, DeFi applications, block creation, and various other services, and is linked to [accounts](#accounts), which allow you to [stake or delegate](#staking-and-delegation-1) mana to receive [Mana rewards](#mana-rewards).
Expand Down Expand Up @@ -237,3 +239,7 @@ A reward scheme is always a powerful mechanism to incentivize actors to have cer
- No incentives for centralizing the funds of validators and delegators.
- By the construction of our reward formulas, there is no incentive for the centralization of validator funds. Technically speaking, this means that two different validators do not get more rewards by combining their stake.
- Analogously, the concentration of delegator funds is disincentivized by the construction of our reward formula. As more delegated stake is concentrated on the same validator, the rewards of the delegators become smaller. Then, the delegators are incentivized to redelegate to validators with less delegated stake. In the long run, under the assumption that actors are rational, the system should stabilize around a constant ratio of delegated and validator stake among pools.

## Mana Calculator

<ManaCalculator/>
159 changes: 159 additions & 0 deletions src/components/ManaCalculator/calculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import {
GENERATION_PER_SLOT,
first_slot_of_epoch,
potential_Mana,
IOTA_SUPPLY,
targetReward,
EPOCH_DURATION,
decay,
} from './utils';
import { ValidatorParameters, ValidatorProps } from './types';

export function calculateManaRewards(
stake: number,
yourPool: number,
validatorParameters: ValidatorParameters,
validators: ValidatorProps[],
initialEpoch: number,
finalEpoch: number,
yourRole: 'Validator' | 'Delegator',
): number {
let totalTargetReward = 0;
let epochDiff = 1;

Check failure on line 22 in src/components/ManaCalculator/calculator.ts

View workflow job for this annotation

GitHub Actions / consistency

'epochDiff' is never reassigned. Use 'const' instead
if (finalEpoch) {
for (let i = 0; i < epochDiff; i++) {
totalTargetReward += decay(targetReward(initialEpoch + i), epochDiff - i);
}
} else {
finalEpoch = initialEpoch + 1;
totalTargetReward = targetReward(initialEpoch);
}

const lockedStake: number[] = validators.map(
(validator) => validator.lockedStake,
);
const fixedCosts: number[] = validators.map(
(validator) => validator.fixedCost,
);
const performance: number[] = validators.map(
(validator) => validator.performanceFactor,
);
const delegatedStake: number[] = validators.map(
(validator) => validator.delegatedStake,
);

if (yourRole === 'Validator') {
lockedStake.push(stake * validatorParameters.shareOfYourStakeLocked);
fixedCosts.push(validatorParameters.fixedCost);
performance.push(validatorParameters.performanceFactor);
delegatedStake.push(
(1 - validatorParameters.shareOfYourStakeLocked) * stake +
validatorParameters.attractedNewDelegatedStake +
validatorParameters.attractedDelegatedStakeFromOtherPools *
delegatedStake.reduce((a, b) => a + b, 0),
);
for (let i = 0; i < validators.length; i++) {
delegatedStake[i] *=
1 - validatorParameters.attractedDelegatedStakeFromOtherPools;
}
}

if (yourRole === 'Delegator') {
delegatedStake[yourPool] += stake;
}

const totalValidatorsStake = lockedStake.reduce((a, b) => a + b, 0);
const totalDelegatedStake = delegatedStake.reduce((a, b) => a + b, 0);
const totalStake = totalDelegatedStake + totalValidatorsStake;
const restOfTokenHoldings = IOTA_SUPPLY - totalStake;
if (restOfTokenHoldings < 0) {
throw new Error('Pools must have (collectively) at most iotaSupply tokens');
}

// Calculates profit margin of the epoch (only when there are tokens stake, otherwise, it's set to None)
let profitMargin: number | null;
if (totalStake > 0) {
profitMargin = totalValidatorsStake / (totalValidatorsStake + totalStake);
} else {
profitMargin = null;
}

// Calculates the total rewards for each pool, already discounting the validator fixed cost
const poolRewards: number[] = new Array(lockedStake.length).fill(0);
if (totalStake > 0) {
if (totalValidatorsStake > 0) {
for (let i = 0; i < lockedStake.length; i++) {
poolRewards[i] =
((lockedStake[i] + delegatedStake[i]) / totalStake +
lockedStake[i] / totalValidatorsStake) *
totalTargetReward *
(performance[i] / 2.0) -
epochDiff * fixedCosts[i];
}
} else {
for (let i = 0; i < lockedStake.length; i++) {
poolRewards[i] =
((lockedStake[i] + delegatedStake[i]) / totalStake) *
totalTargetReward *
(performance[i] / 2.0) -
epochDiff * fixedCosts[i];
}
}
}

// Calculates the rewards for each validator
const validatorRewards: number[] = new Array(lockedStake.length).fill(0);
for (let i = 0; i < lockedStake.length; i++) {
if (poolRewards[i] < 0) {
validatorRewards[i] = 0;
poolRewards[i] = 0;
} else if (poolRewards[i] === 0) {
validatorRewards[i] = epochDiff * fixedCosts[i];
} else {
validatorRewards[i] =
epochDiff * fixedCosts[i] +
poolRewards[i] * profitMargin +
((1 - profitMargin) * poolRewards[i] * lockedStake[i]) /
(delegatedStake[i] + lockedStake[i]);
}
}

const delegatorRewards: number[] = new Array(lockedStake.length).fill(0);
for (let i = 0; i < lockedStake.length; i++) {
if (poolRewards[i] > 0) {
delegatorRewards[i] =
(poolRewards[i] * (1 - profitMargin) * delegatedStake[i]) /
(delegatedStake[i] + lockedStake[i]);
}
}

let rewards = 0;
if (yourRole === 'Delegator') {
if (delegatorRewards[yourPool] > 0) {
rewards = (delegatorRewards[yourPool] * stake) / delegatedStake[yourPool];
}
}

if (yourRole === 'Validator') {
rewards = validatorRewards[lockedStake.length - 1];
}

return rewards;
}

export function calculatePassiveRewards(
tokens: number,
initialEpoch: number,
finalEpoch: number,
): number {
return potential_Mana(
tokens,
first_slot_of_epoch(initialEpoch) - 1,
first_slot_of_epoch(finalEpoch) - 1,
GENERATION_PER_SLOT,
);
}

export function calculateTPS(mana: number, congestion: number): number {
return mana / congestion / EPOCH_DURATION;
}
Loading
Loading